Link Time Optimization
提供: C言語入門
スポンサーリンク
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 9月 11 23:43 f-normal.o 4 -rw-rw-r-- 1 kaworu 2752 9月 11 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
関連項目
ツイート
スポンサーリンク