FatLTO¶
简介¶
FatLTO 对象是一种特殊的胖目标文件,除了生成的目标代码外,还包含与 LTO 兼容的 IR,而不是包含多个目标架构的目标代码。 这允许用户将是否使用 LTO 的选择推迟到链接时,并且在其他编译器(如 GCC)中已经存在一段时间了。
在 FatLTO 下,编译器可以生成标准目标文件,其中包含 .text
节中的机器代码和 .llvm.lto
节中的 LLVM bitcode。
概述¶
在 LLVM 中,通过选择 FatLTODefaultPipeline
来支持 FatLTO。 此 pipeline 将会
在当前模块上运行预链接 (Thin)LTO pipeline。
将预链接 bitcode 嵌入到特殊的
.llvm.lto
节中。使用 ModuleOptimization pipeline 完成模块的优化。
生成目标文件,包括新的
.llvm.lto
节。
在内部,.llvm.lto
节是通过在 ThinLTOPreLinkDefaultPipeline
之后运行 EmbedBitcodePass
创建的。 此 pass 负责生成 .llvm.lto
节。 之后,ThinLTODefaultPipeline
运行,编译器可以生成胖目标文件。
局限性¶
链接器¶
目前,LLD 和 GNU 链接器通过 LLVM gold 插件 支持将 LTO 与 LLVM fat lto 对象一起使用。 未来这可能会改变,但目前尚无计划将支持扩展到其他链接器。
支持的文件格式¶
当前的实现仅支持 ELF 文件。 在撰写本文时,尚不清楚支持其他目标文件格式(如 COFF
或 Mach-O
)是否有用。
用法¶
Clang 用户可以使用 -flto
或 -flto=thin
指定 -ffat-lto-objects
。 如果没有 -flto
选项,-ffat-lto-objects
将不起作用。
使用 FatLTO 编译目标文件
$ clang -flto -ffat-lto-objects example.c -c -o example.o
链接时使用来自胖对象的对象代码,而不使用 LTO。 当指定 -fno-lto
时,这会将 -ffat-lto-objects
变成空操作
$ clang -fno-lto -ffat-lto-objects -fuse-ld=lld example.o
或者,您可以忽略任何对带有胖对象的 LTO 的引用,并保留标准链接器行为
$ clang -fuse-ld=lld example.o
链接时使用来自胖对象的 LLVM bitcode 和 Full LTO
$ clang -flto -ffat-lto-objects -fuse-ld=lld example.o # clang will pass --lto=full --fat-lto-objects to ld.lld
链接时使用来自胖对象的 LLVM bitcode 和 Thin LTO
$ clang -flto=thin -ffat-lto-objects -fuse-ld=lld example.o # clang will pass --lto=thin --fat-lto-objects to ld.lld