问题标签 [lto]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
337 浏览

c - GCC LTO 胖目标文件上的“nm”输出不正确

如果我有tmp.c

我看gcc -c tmp.c -o tmp.o && nm tmp.o节目

但是,如果我使用 编译-flto -ffat-lto-objectsnm则符号值的输出为零:

我可以在两个文件的十六进制转储中使用34和值。12.o

我的问题是

  1. nmLTO fat 文件上的行为是预期的吗?我只是给它不期望的输入并且它正在输出垃圾吗?

  2. 什么解释了原始输出(符号值匹配未初始化的数组长度)?这个问题似乎对数组的问题没有帮助,但也许我误解了。

0 投票
1 回答
166 浏览

clang - 编译前使用 llvm-link

我做了一个小实验,看看如果我在编译之前将一堆虚拟 C 源文件编译成一个 LLVM 位代码文件(首先-emit-llvm用于编译成.bc文件,然后使用llvm-link将它们压缩成一个.bc文件), Clang 是否会产生更好的代码。一个虚拟库,而不是通常编译到要链接的单个目标文件,它似乎能够执行一些 WPO(整个程序优化),例如跨不同翻译单元的内联函数,否则它不会这样做。我通过 了解 LTO(链接时间优化)-flto,所以这更像是我的一个小实验,以了解 Clang 在这种特殊情况下的行为会有多么不同。

但是,我的问题是,以这种方式构建二进制文件是否可取?最终结果与简单地使用有什么不同-flto吗?如果是这样,无论是在过程还是最终结果方面,会有什么不同?如果不是,这只是一种更人为的调用 LTO 的方式吗?

0 投票
0 回答
65 浏览

c++ - 使用 LLVM LTO 剥离静态全局对象

我正在开发一个链接到多个二进制文件的静态库。我的目标是在我的库被链接时减少它的内存占用。

我的库的用户需要我在库的 cpp 文件中创建的某些全局对象,然后导出具有这些变量的外部声明的头文件。

问题是,根据库的使用方式,其中一些全局变量可能根本无法使用。

以下代码在一定程度上显示了我的代码结构:

Foo.hpp:

Bar1.hpp:

Bar2.hpp:

全局.cpp:

导出.hpp:

这是我的问题:

  1. 如果包含我的库的项目只使用 foo1,那么 foo2 会从最终的二进制文件中删除吗?因此,Bar2 类的代码也会被删除吗?

  2. 如果没有,你知道我可以如何重组我的代码,以便在链接过程中去掉未使用的符号和未使用的代码吗?我能想到的唯一方法是将 Globals.cpp 和 Export.hpp 移动到包含我的库的项目中。还有其他方法吗?

  3. 我能想到的一种方法是将 Globals.hpp 和 Export.hpp 拆分为更小的文件,其中包含一组有意义的声明和定义。那会有帮助吗?

0 投票
2 回答
1679 浏览

visual-studio - 即使 check_ipo_supported() 在 CMake 中工作,也未设置 INTERPROCEDURAL_OPTIMIZATION

我在 CMake 3.14.0 中有以下项目,它为 Visual Studio 2017 64 位生成器构建了一个项目(最低版本为 3.10.0,因为其他开发人员可以拥有以前版本的 CMake,但大于 3.9.0):

我添加了一些命令,用于在 Visual Studio 中添加对 LTO 的支持。我已经看到我必须检查对 IPO 的支持,如果可以,我必须设置INTERPROCEDURAL_OPTIMIZATION属性,这就是我所做的

当我运行项目时,我收到以下消息(我也在使用 vcpkg,这就是第一行的原因):

据我所见,该项目未启用链接时间优化。我还在 Visual Studio 中打开了项目,并检查了项目的命令行,这就是构建的结果:

并用于链接

我没有看到 LTO 的任何标志。

我已经为策略运行了命令,结果如下:

看来我以正确的方式使用它。

我不明白的是,如果命令check_ipo_supported告诉我另一个故事,为什么不应用该属性。

我做错了什么?

0 投票
0 回答
508 浏览

c++ - 使用 LTO 会导致对 std::basic_string 析构函数的未定义引用

决定在我的构建中尝试 LTO(CentOS 7、CMake 3.14.3、gcc 8.2.1、-std=c++17):

所有项目都构建良好,除了一个:

由于 vcpkg 提供的某些神秘原因libazurestorage.a(它是在没有LTO 的情况下构建的)无法解析std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()(只有那个符号!)。

为了让它更有趣——其他使用libazurestorage.abuild 的项目就好了。我检查了链接器的命令行——它们看起来几乎相同(几乎相同的库集,几乎相同的顺序)。

有什么想法可能是错的吗?或者如何弄清楚为什么其他项目构建良好?

0 投票
1 回答
63 浏览

c++ - 使用 extern inline 时 G++ 发出“指定存储类”错误

我使用链接时优化(-fltoing++ld命令行),并且我的一些方法声明(在标题中)被标记为extern inline(并且仅inline.cpp文件中)。编译产量:

以及其他方法和功能的一堆类似错误。EFAST意味着extern inline

为什么在启用 LTO 的情况下会发生这种情况?如果不允许这样做,我如何将声明和定义与内联和 LTO 分开?

0 投票
1 回答
46 浏览

c++ - G++ 和 LTO:如何分离声明和定义?

由于 LTO 可以从其他目标文件中解析inline符号,因此我尝试将inline函数的声明和定义分开。这是 3 个文件,dep.hppdep.cppmain.cpp其中main.cppdep.cpp链接在一起,并且在两者中dep.hpp都是#included:

这是 G++ 打印的错误:

命令行:

为什么链接器抱怨 undefined sayHello()when -fltois enabled 并且sayHello()它本身是inline?LTO不应该处理这种情况吗?

我正在使用 mingw-w64 8.1.0 x86_64-posix-seh

0 投票
0 回答
96 浏览

c++ - gcc 9.2:虚假-Wuninitialized

我正在尝试使用 gcc 9.2.0 构建我们的代码库,但是在使用 -flto 时,我收到了十几个缺少信息的警告。gcc6.3 没有出现这些问题。

不幸的是,提到的行实际上是空的,并且警告消息缺少未初始化的标识符。

我很想用一个较小的测试用例来重现,但我不知道它涉及哪个变量。提到的两个文件没有提及任何具体内容。它实际上抱怨编译器生成的函数(__ct_base)。

有什么方法可以从 gcc 获取有关警告的更多信息?

0 投票
1 回答
573 浏览

gcc - 在 LTO 模式下从 GCC/Clang 获取汇编输出

通常,可以使用 GCC 和 Clang中的标志从源文件中获取 GCC 的优化汇编程序输出-S,如下例所示。

但是假设我编译所有源文件-O3 -flto以启用链接时全程序优化,并希望查看最终编译器为函数生成的优化程序集,和/或查看代码在何处/如何内联。

正如预期的那样,编译的结果是一堆.o文件,它们实际上是伪装成目标文件的 IR 文件。在链接可执行文件或共享库时,它们会被混合在一起,作为一个整体进行优化,然后编译到目标二进制文件中。

但是如果我想要这个过程的汇编输出呢?也就是说,链接时优化之后、在将 IR 编译为汇编期间以及在实际汇编和链接到最终可执行文件之前产生的汇编源。

我尝试简单地-S在链接步骤中添加一个标志,但这并没有真正起作用。

我知道反汇编可执行文件是可能的,甚至与源代码交错,但有时查看实际编译器生成的程序集会更好,尤其是使用-fverbose-asm.

0 投票
1 回答
5901 浏览

lto - 使用 LTO 版本 6.0 而不是预期的 8.1 生成

我已按照 windows [1] 的 movesense 设置说明运行以下 cmake 命令,这似乎可以正常工作。但是,当我运行 ninja 命令时,它在第 9/9 步失败,抱怨 LTO 版本与配置不匹配。有什么建议吗?

错误:

使用 LTO 版本 6.0 生成,而不是预期的 8.1 编译终止。lto-wrapper.exe:致命错误:C:\PROGRA~2\GNUTOO~1\92019-~1\bin\AR19DD~1.EXE 返回 1 退出状态编译终止。c:/progra~2/gnutoo~1/92019-~1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none -eabi/bin/ld.exe:错误:lto-wrapper 失败 collect2.exe:错误:ld 返回 1 退出状态 ninja:构建停止:子命令失败。使用 LTO 版本 6.0 生成,而不是预期的 8.1 编译终止。lto-wrapper.exe:致命错误:C:\PROGRA~2\GNUTOO~1\92019-~1\bin\AR19DD~1.EXE 返回 1 退出状态编译终止。c:/progra~2/gnutoo~1/92019-~1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none -eabi/bin/ld.exe:错误:lto-wrapper 失败 collect2.exe:错误:ld 返回 1 退出状态 ninja:构建停止:子命令失败。

唯一不确定的安装部分是“Visual Studio Redistributable 2015”的安装,它说我有一个更新的版本,我不确定如何验证这一步是否正确。


我现在也使用“Vagrant 解决方案”尝试了同样的事情,当我输入 ninja dfupkg 时,我在最后一步遇到的错误是:

预期标记 round_div_expr 而不是 reference_type 请提交完整的错误报告,并在适当时提供预处理源。看 https://gcc.gnu.org/bugs/获取说明。lto-wrapper:致命错误:/usr/bin/arm-none-eabi-gcc 返回 1 退出状态编译终止。/usr/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld:错误:lto-wrapper 失败collect2:错误:ld 返回 1 退出状态 ninja:构建停止:子命令失败。

[1] https://bitbucket.org/suunto/movesense-device-lib/src/master/