可以在同一编译单元(即同一文件)中的函数之间进行常量传播等优化。
例如:
int f(int x)
{
return 3 + x;
}
int main(void)
{
printf("%d\n", 1 + f(4));
return 0;
}
在那个例子中,我认为一个足够聪明的编译器可以将'4'常量传播到函数'f',解决整数运算 另一个常量'3',并传回结果值,从而将所有内容折叠到最终值'8'。
(好吧,如果我错了,请纠正我。)
但是,如果函数'f'在另一个编译单元中,会发生什么。由于它们都是单独编译的,因此编译器不能 优化这种方式。
这是否意味着只能在同一个编译单元中进行优化,或者是否存在某些形式的链接时优化?
答案 0 :(得分:7)
MSVC(自8.0:VS2005)和GCC(自4.5以来)都支持这一概念。
MSVC使用编译器开关/GL
和链接器开关/LTCG
。 Documentation
GCC必须启用它并使用-flto
,-fwhole-program
,-fwhopr
和/或-combine
来达到同样的效果。 Documentation(在浏览器中搜索选项)
“问题”是每个编译单元(源文件)(以及MSVC每个库的情况下)都需要使用它编译,因此您不能使用没有它编译的旧二进制目标文件。它还使调试更难,因为优化器更具攻击性和不可预测性。
答案 1 :(得分:3)
Clang编译为LLVM IR,LLVM链接器在生成本机二进制文件时执行整个程序优化。
答案 2 :(得分:1)
Microsoft Visual Studio支持由ltcg开关启用的WPO(整个程序优化)(链接时代码生成)。
它引起了一些我现在不记得的其他问题,并且被许多开发人员所取代。
答案 3 :(得分:1)
是的,对于Visual Studio中的Visual C ++编译器,这称为Whole Program Optimization:
整个程序优化允许 编译器用于执行优化 有关所有模块的信息 程序。没有整个程序 优化,优化是 在每个模块上执行(compiland) 基础
有关所有模块的信息, 编译器可以:
优化寄存器的使用 功能界限。
更好地跟踪 允许修改全局数据 减少负荷和数量 存储
更好地跟踪 由a修改的可能的项目集 指针解除引用,减少了 装载和存储的数量。
甚至可以在模块中内联函数 当函数定义时 另一个模块。
答案 4 :(得分:0)
GCC 4.5引入了链接时优化。 AFAIK,它只适用于x86和x64目标。