- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在编译翻译单元时,编译器会进行大量优化 - 内联、常量折叠/传播、别名分析、循环展开、死代码消除以及许多我从未听说过的其他优化。在多个翻译单元之间使用 LTO/LTCG/WPO 时是否全部完成,或者只是完成了其中的一个子集(或变体)(我听说过内联)?如果没有完成所有优化,我会考虑统一构建优于 LTO(或者当有超过 1 个统一源文件时可能同时使用它们)。
我的猜测是它不一样(统一构建具有完整的优化集),而且它在编译器之间变化很大。
每个编译器的 lto 文档并没有准确回答这个问题(或者我无法理解它)。
由于 lto 涉及将中间表示保存在目标文件中,理论上 LTO 可以进行所有优化......对吗?
请注意,我不是在询问构建速度 - 这是一个单独的问题。
编辑:我最感兴趣的是 gcc/llvm。
最佳答案
如果您查看您找到的 gcc 文档:
-flto[=n]
This option runs the standard link-time optimizer. When invoked with source code, it generates GIMPLE (one of GCC's internal representations) and writes it to special ELF sections in the object file. When the object files are linked together, all the function bodies are read from these ELF sections and instantiated as if they had been part of the same translation unit.
To use the link-time optimizer, -flto and optimization options should be specified at compile time and during the final link. For example:
gcc -c -O2 -flto foo.c
gcc -c -O2 -flto bar.c
gcc -o myprog -flto -O2 foo.o bar.o
The first two invocations to GCC save a bytecode representation of GIMPLE into special ELF sections inside foo.o and bar.o. The final invocation reads the GIMPLE bytecode from foo.o and bar.o, merges the two files into a single internal image, and compiles the result as usual. Since both foo.o and bar.o are merged into a single image, this causes all the interprocedural analyses and optimizations in GCC to work across the two files as if they were a single one. This means, for example, that the inliner is able to inline functions in bar.o into functions in foo.o and vice-versa.
正如文档所述,是的,全部!优化就像程序在单个文件中编译一样。这也可以通过 -fwhole-program
来获得“相同”的优化结果。
如果你编译这个非常简单的例子:
f1.cpp:
int f1() { return 10; }
f2.cpp:
int f2(int i) { return 2*i; }
main.cpp:
int main()
{
int res=f1();
res=f2(res);
res++;
return res;
}
我得到了汇编输出:
00000000004005e0 <main>:
4005e0: b8 15 00 00 00 mov $0x15,%eax
4005e5: c3 retq
4005e6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4005ed: 00 00 00
所有代码都按预期内联。
我的经验是,实际的 gcc 使用 lto 进行优化,就像在单个文件中编译一样。在非常罕见的情况下,我在使用 lto 时得到了 ICE。但是在实际的 5.2.0 版本中,我再也没有看到任何 ICE。
[ICE]-> 内部编译器错误
关于c++ - LTO 中的优化是否与正常编译中的相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31720814/
我正在使用 CMake 为我的 C 编译启用 IPO(过程间优化): set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRU
我正在使用 CMake 为我的 C 编译启用 IPO(过程间优化): set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRU
我一直在尝试使用以下代码片段(gcc 编译时没有任何警告)更改 Windows(7 和 Server 2012 R2)中 LTO8 磁带的事件分区: DWORD partition= 2; if(Se
考虑以下程序: #include #include int main() { std::string s; std::getline(std::cin, s);
我正在使用链接时间优化 (lto) 和 O2 优化级别编译一个带有修改版 clang 的项目。 O0 和 O1 都很好,但遗憾的是 O2 删除了一些函数调用。有没有办法告诉优化忽略特定功能?我已经尝试
我有带闪存的 MCU(像往常一样)。链接器将 .struct_init、.struct_init_const、.struct_not_init 部分放置到属于闪存部分 20 的地址。它在链接器脚本中被
在编译翻译单元时,编译器会进行大量优化 - 内联、常量折叠/传播、别名分析、循环展开、死代码消除以及许多我从未听说过的其他优化。在多个翻译单元之间使用 LTO/LTCG/WPO 时是否全部完成,或者只
比较 C++ 中的虚函数和 C 中的虚表,编译器在一般情况下(以及对于足够大的项目)在去虚拟化方面是否同样出色? 天真地,C++ 中的虚函数似乎具有更多的语义,因此可能更容易去虚拟化。 更新: Moo
GCC、MSVC、LLVM 和可能的其他工具链支持链接时间(整个程序)优化,以允许优化编译单元之间的调用。 编译生产软件时是否有理由不启用此选项? 最佳答案 我假设 “生产软件” 是指您交付给客户/投
有没有办法检测代码是否是用 -flto 编译的? 示例是Linux下的经典库或可执行文件,使用GCC(4.9.1)编译,无需调试。 最佳答案 考虑到 LTO 信息存储在目标文件内的几个 ELF 部分中
假设我有一个函数 void do_something() { //.... #ifdef FEATURE_X feature_x(); #endif /
对于 gcc,这个 answer告诉我们如何验证链接时间优化是否已执行。对于 clang,我看不到任何类似于 .gnu.lto 的条目. 更具体地说,我有一个二进制文件,我很确定 LTO 应该有很大的
我试图用下一个标志编译我的源代码: 1. -flto2. -flto -ffat-lto-objects3. -flto -fno-fat-lto-objects 第三个提供优化slim文档中编写的
我有一个项目,在 ARM Cortex-M4 处理器上运行,我试图在其中包含 gcc 链接时优化 (LTO) 功能。 目前我的编译和链接标志是: CFLAGS = -ggdb -ffunction-s
在编写代码或构建脚本以使用 LTO 进行编译时需要牢记哪些注意事项和陷阱? 这个问题背后的动机是为了更好地理解为什么某些项目在启用 LTO 时编译不干净。特别是,我无法构建 ICU在启用 LTO 的情
我想使用符号版本控制和链接时优化 (LTO) 编译共享库。但是,一旦我打开 LTO,一些导出的符号就会消失。这是一个最小的例子: 首先定义函数 fun 的两个实现: $ cat fun.c #incl
当我尝试使用 -flto 构建静态库时,出现 undefined reference 错误: library.cpp: #include void foo() { std::cout << "T
Clang 允许使用瘦 lto 来加快编译时间,同时仍然保留使用 lto 和选项 -flto=thin 的大部分优点。 . gcc 有相当于 clang 的薄 lto 吗? 最佳答案 GCC 有一个相
我正在使用 arm-none-eabi-gcc 为基于 Cortex-M4 的微 Controller 编译一个可执行文件。非性能关键代码使用 -Os(针对可执行代码大小进行了优化)编译,性能关键部分
有这样的代码: #include "kernel.h" int main() { ... for (int t = 0; t 1099: 00 109a: f
我是一名优秀的程序员,十分优秀!