是C/C++;编译器跨编译单元优化?

是C/C++;编译器跨编译单元优化?,c,optimization,C,Optimization,可以在同一编译单元(即同一文件)内的函数之间进行优化,例如常量传播 例如: int f(int x) { return 3 + x; } int main(void) { printf("%d\n", 1 + f(4)); return 0; } 在那个例子中,我认为一个足够聪明的编译器可以将'4'常量传播到函数'f',用 另一个常量为“3”,并传播回结果值,从而将所有内容折叠为最终值“8” (如果我错了,请纠正我) 但是,如果函数“f”位于另一个编译单元中,会发生什

可以在同一编译单元(即同一文件)内的函数之间进行优化,例如常量传播

例如:

int f(int x)
{
    return 3 + x;
}

int main(void)
{
    printf("%d\n", 1 + f(4));
    return 0;
}
在那个例子中,我认为一个足够聪明的编译器可以将'4'常量传播到函数'f',用 另一个常量为“3”,并传播回结果值,从而将所有内容折叠为最终值“8”

(如果我错了,请纠正我)

但是,如果函数“f”位于另一个编译单元中,会发生什么情况。因为这两个单元是分开编译的,所以编译器不能 这样优化


这是否意味着优化只能在同一个编译单元内进行,或者是否存在某种形式的链接时间延迟优化

GCC4.5引入了链路时间优化。另外,它仅适用于x86和x64目标。

Microsoft Visual Studio支持由ltcg开关(链接时间代码生成)启用的WPO(全程序优化)


它引起了一些我现在还不记得的问题,很多开发人员都喜欢它。

< P>是的,VisualStudio中的VisualC++编译器称为:

整个程序优化允许 用于执行优化的编译器 中所有模块的信息 节目。没有完整的程序 优化,优化是 在每个模块上执行(编译和) 基础

根据所有模块的信息 编译器可以:

  • 跨多个应用程序优化寄存器的使用 功能边界

  • 做好跟踪工作 修改全局数据,允许 减少负载和负载的数量 商店

  • 更好地跟踪数据 可能的项目集由 指针取消引用,减少 装载和存储的数量

  • 在模块中内联函数 在中定义函数时 另一个模块

MSVC(自8.0:VS2005起)和GCC(自4.5起)都支持该概念

  • MSVC使用编译器开关
    /GL
    和链接器开关
    /LTCG

  • GCC必须启用它,并使用
    -flto
    -FWHORE程序
    -fwhopr
    ,和/或
    -组合
    ,以达到相同的效果。(在浏览器中搜索选项)


“问题”是每个编译单元(源文件)(在MSVC的情况下,每个库)都需要使用它进行编译,因此不能使用没有它编译的旧二进制对象文件。这也使得调试更加困难,因为优化器更具攻击性和不可预测性。

Clang编译到LLVM IR,而LLVM链接器在生成本机二进制文件时执行整个程序优化。

附带问题:从所有源树生成一个大的.c文件的脚本能否增加优化可能性?是的,将所有代码放在一个文件中称为合并,并且仅当代码支持它时才用于此目的。预处理器定义、静态每翻译单元定义、编译器限制和其他阻碍因素。OTOH,它还可以显著加快构建速度。更大的静态库2。带有“字节码”的静态库在任何时候都可能变得不受支持。我有更多的库,有非常大的代码库。另外,我还要增加编译时间。@Sharptooth:字节码只是中间表示。许多编译器都是这样做的。对于链接时间优化,建议每次重新编译整个程序-发布版本应该如何进行。因此,字节码的可能不兼容版本并不是真正的问题。@Dummy00001:是的,但您可能会试图将代码作为静态库发送给其他人。如果使用LTCG编译的库执行此操作,则当用户更新编译器时,它可能会变得不可用。@Dummy00001它不是中间的:静态库(只是obj文件包)是在windows上传送编译代码的首选方式,而在windows上,DLL不支持动态链接(也称为共享全局问题)。。。并且.lib文件变得非常庞大。尽管如此,它在代码消除方面所做的工作还是令人惊讶。llvm使混合和匹配模块以及单独或组合优化模块变得非常容易。并提供了许多(可能太多)优化机会。