如何将 GCC LTO 与不同优化的目标文件一起使用?

Posted

技术标签:

【中文标题】如何将 GCC LTO 与不同优化的目标文件一起使用?【英文标题】:How to use GCC LTO with differently optimized object files? 【发布时间】:2017-08-11 09:53:33 【问题描述】:

我正在为基于 Cortex-M4 的微控制器编译带有 arm-none-eabi-gcc 的可执行文件。非性能关键代码使用-Os(针对可执行代码大小进行了优化)编译,性能关键部分使用另一个优化标志,例如。 -Og / -O2

在这样的构建中使用-flto 是否安全?如果是这样,应该将哪个优化标志传递给链接器?

【问题讨论】:

【参考方案1】:

根据GCC documentation关于优化选项:

建议您使用相同的选项编译所有参与同一链接的文件

这样的说法相当含糊。不过,在深入了解release notes of GCC 5 时,还有一些额外的细节:

命令行优化和目标选项现在按功能流式传输,并由链接时优化器支持。此更改使链接时优化更透明地替代了每个文件的优化。现在可以构建需要针对不同翻译单元(例如 -ffast-math、-mavx 或 -finline)进行不同优化设置的项目。

以及有关哪些标志受此类限制影响以及哪些不受此类限制影响的信息:

请注意,这仅适用于那些可以传递给优化和目标属性的命令行选项。影响全局代码生成的命令行选项(例如 -fpic)、警告(例如 -Wodr)、影响静态变量优化方式的优化(例如 -fcommon)、调试输出(例如 -g)和 -- param 参数只能应用于整个链接时优化单元。在这些情况下,建议在编译时和链接时始终使用相同的选项。

在您的场景中,优化标志-Og-O2-Os 可以作为优化属性传递,并且不属于编译时间和链接时间标志应该相同的情况。所以是的,在这样的构建中使用-flto 应该是安全的。

关于在链接时传递的优化标志,如发行说明中所述:

与早期的 GCC 版本相反,优化和目标选项 在链接命令行上传递的将被忽略。

GCC 自动确定使用哪个优化级别,即编译目标文件时使用的***别。因此,您无需将任何 -O 优化选项传递给链接器。

【讨论】:

哇,太好了,感谢您找到它并在此处发布。这是否也适用于 GCC 6 和 7? @Venemo 我在 GCC 6 和 7 更改日志或其他相关文档中没有看到任何提及此行为发生变化的内容。所以它可能也适用于较新版本的 GCC。 我认为它不适用于 -Os / -O3 选项。我有一个文件从 -O3 中受益匪浅,为了将优化级别保持在 -O3 我基本上只需要为这个文件禁用 LTO(使用 -fno-lto)

以上是关于如何将 GCC LTO 与不同优化的目标文件一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

是否有理由不使用链接时间优化 (LTO)?

防止 GCC LTO 删除函数

gcc有薄lto吗?

GCC LTO 是不是执行跨文件死代码消除?

可以将不同的GCC方言联系在一起吗?

24 GCC LTO - Link Time Optimization