简单地说:
当指定-flto 时,gcc 将称为GIMPLE 树的中间程序表示嵌入到每个目标文件的专门部分中。稍后,链接时间优化器(GCC 的lto1 可执行文件)读取此信息,并执行不同的优化过程,包括 IPA 内联程序,以生成最终优化的可执行文件。
两个内联的影响可以用一个简单的例子来说明:
// foo.h
void foo() {}
// goo.h
int goo();
// goo.cpp
#include "goo.h"
int goo() { return 0x123; }
// foo.cpp
#include "foo.h"
#include "goo.h"
int main()
{
foo();
return goo();
}
首先,通常-O3编译:
g++ -O3 foo.cpp goo.cpp
通过反汇编a.out (objdump a.out -d) 我们得到main的以下代码:
00000000000004f0 <main>:
4f0: e9 0b 01 00 00 jmpq 600 <_Z3goov>
4f5: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4fc: 00 00 00
4ff: 90 nop
对foo() 的调用消失了——这是早期内联的工作。而goo()函数在编译foo.cpp的过程中对编译器是不可见的,所以无法对其进行优化。
现在,用-flto 重复编译:
g++ -O3 -flto foo.cpp goo.cpp
我们会得到以下反汇编:
00000000000004f0 <main>:
4f0: b8 23 01 00 00 mov $0x123,%eax
4f5: c3 retq
4f6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4fd: 00 00 00
这一次,对 goo 的调用被内联并替换为它的结果 0x123 - 这是 IPA 内联的工作。