Link Time Optimization

提供: C言語入門
2017年9月11日 (月) 23:57時点におけるDaemon (トーク | 投稿記録)による版 (実行例)

(差分) ←前の版 | 最新版 (差分) | 次の版→ (差分)
移動: 案内検索
スポンサーリンク

CコンパイラLink Time Optimization (LTO) とは、リンク時の最適化を行うものです。

読み方

Link Time Optimization
りんく たいむ おぷてぃまいぜーしょん

概要

Link Time Optimization がなかったころは、コンパイル単位でしか最適化ができませんでした。 Link Time Optimization (LTO) では、GIMPLE のバイトコード表現を .o ファイルの特別なセクションに保存します。リンク時にコンパイルしなおし、リンク時に最適化がなされます。 リンク時に使われないコードが排除されます。 LTO は、 gcc 4.5 からサポートされました。 

LTO は、

  • ELF ベースのシステム
  • darwin
  • cygwin
  • mingw

をサポートしています。

GIMPLE バイトコードは、最終オブジェクトファイルに保存されるため、標準のオブジェクトファイルよりも LTO サポートのオブジェクトファイルのほうが大きくなります。

コンパイル

LTO を使うには、 -flto オプションを使用します。

$ gcc -flto -c foo.c
$ gcc -flto -c bar.c
$ gcc -flto foo.o bar.o -o a.out

clang でも同様のオプションを使用します。 

$ clang -flto -c foo.c
$ clang -flto -c bar.c
$ clang -flto foo.o bar.o -o a.out

実行例

LTO を使用した場合としない場合で、作成されるオブジェクトを比較するため、以下のコードを試してみました。

int
f () {
        return 0;
}

LTO オプションありと、なしの場合で、作成されるオブジェクトのファイルが明らかに違うことがわかります。

$ gcc-7 -c -flto f.c
$ gcc-7 -c  f.c -o f-normal.o
$ ls -ls *.o
4 -rw-rw-r-- 1 kaworu 1224  911 23:43 f-normal.o
4 -rw-rw-r-- 1 kaworu 2752  911 23:43 f.o
$ nm f-normal.o
0000000000000000 T f
$ nm f.o
nm: f.o: plugin needed to handle lto object
0000000000000001 C __gnu_lto_slim
0000000000000001 C __gnu_lto_v1

LTO なしのオブジェクトのセクションは、以下の通りです。

$ objdump -x f-normal.o
 
f-normal.o:     ファイル形式 elf64-x86-64
f-normal.o
アーキテクチャ: i386:x86-64, フラグ 0x00000011:
HAS_RELOC, HAS_SYMS
開始アドレス 0x0000000000000000
 
セクション:
索引名          サイズ      VMA               LMA               File off  Algn
  0 .text         0000000b  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  0000004b  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  0000004b  2**0
                  ALLOC
  3 .comment      00000031  0000000000000000  0000000000000000  0000004b  2**0
                  CONTENTS, READONLY
  4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  0000007c  2**0
                  CONTENTS, READONLY
  5 .eh_frame     00000038  0000000000000000  0000000000000000  00000080  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 f.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000 g     F .text  000000000000000b f
 
 
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE
0000000000000020 R_X86_64_PC32     .text

LTO ありだと、セクションが増えてます。

$ objdump -x f.o
 
f.o:     ファイル形式 elf64-x86-64
f.o
アーキテクチャ: i386:x86-64, フラグ 0x00000010:
HAS_SYMS
開始アドレス 0x0000000000000000
 
セクション:
索引名          サイズ      VMA               LMA               File off  Algn
  0 .text         00000000  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00000040  2**0
                  ALLOC
  3 .gnu.lto_.inline.884dff53571d960e 00000020  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, READONLY, EXCLUDE
  4 .gnu.lto_f.884dff53571d960e 000000eb  0000000000000000  0000000000000000  00000060  2**0
                  CONTENTS, READONLY, EXCLUDE
  5 .gnu.lto_.symbol_nodes.884dff53571d960e 0000001e  0000000000000000  0000000000000000  0000014b  2**0
                  CONTENTS, READONLY, EXCLUDE
  6 .gnu.lto_.refs.884dff53571d960e 0000000f  0000000000000000  0000000000000000  00000169  2**0
                  CONTENTS, READONLY, EXCLUDE
  7 .gnu.lto_.decls.884dff53571d960e 00000189  0000000000000000  0000000000000000  00000178  2**0
                  CONTENTS, READONLY, EXCLUDE
  8 .gnu.lto_.symtab.884dff53571d960e 00000011  0000000000000000  0000000000000000  00000301  2**0
                  CONTENTS, READONLY, EXCLUDE
  9 .gnu.lto_.opts 000000b7  0000000000000000  0000000000000000  00000312  2**0
                  CONTENTS, READONLY, EXCLUDE
 10 .comment      00000031  0000000000000000  0000000000000000  000003c9  2**0
                  CONTENTS, READONLY
 11 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000003fa  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 f.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .gnu.lto_.inline.884dff53571d960e      0000000000000000 .gnu.lto_.inline.884dff53571d960e
0000000000000000 l    d  .gnu.lto_f.884dff53571d960e    0000000000000000 .gnu.lto_f.884dff53571d960e
0000000000000000 l    d  .gnu.lto_.symbol_nodes.884dff53571d960e        0000000000000000 .gnu.lto_.symbol_nodes.884dff53571d960e
0000000000000000 l    d  .gnu.lto_.refs.884dff53571d960e        0000000000000000 .gnu.lto_.refs.884dff53571d960e
0000000000000000 l    d  .gnu.lto_.decls.884dff53571d960e       0000000000000000 .gnu.lto_.decls.884dff53571d960e
0000000000000000 l    d  .gnu.lto_.symtab.884dff53571d960e      0000000000000000 .gnu.lto_.symtab.884dff53571d960e
0000000000000000 l    d  .gnu.lto_.opts 0000000000000000 .gnu.lto_.opts
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000001       O *COM*  0000000000000001 __gnu_lto_v1
0000000000000001       O *COM*  0000000000000001 __gnu_lto_slim

関連項目




スポンサーリンク