FatLTO¶
Introduction¶
FatLTO objects are a special type of fat object file that contain LTO compatible IR in addition to generated object code, instead of containing object code for multiple target architectures. This allows users to defer the choice of whether to use LTO or not to link-time, and has been a feature available in other compilers, like GCC, for some time.
Under FatLTO the compiler can emit standard object files which contain both the
machine code in the .text
section and LLVM bitcode in the .llvm.lto
section.
Overview¶
Within LLVM, FatLTO is supported by choosing the FatLTODefaultPipeline
.
This pipeline will:
Run the pre-link UnifiedLTO pipeline on the current module.
Embed the pre-link bitcode in a special
.llvm.lto
section.Finish optimizing the module using the post-link ThinLTO pipeline.
Emit the object file, including the new
.llvm.lto
section.
Internally, the .llvm.lto
section is created by running the
EmbedBitcodePass
after the ThinLTOPreLinkDefaultPipeline
. This pass is
responsible for emitting the .llvm.lto
section. Afterwards, the
ThinLTODefaultPipeline
runs and the compiler can emit the fat object file.
Limitations¶
Linkers¶
Currently, using LTO with LLVM fat lto objects is supported by LLD and by the GNU linkers via The LLVM gold plugin. This may change in the future, but extending support to other linkers isn’t planned for now.
Supported File Formats¶
The current implementation only supports ELF files. At time of writing, it is
unclear if it will be useful to support other object file formats like COFF
or Mach-O
.
Usage¶
Clang users can specify -ffat-lto-objects
with -flto
or -flto=thin
.
Without the -flto
option, -ffat-lto-objects
has no effect.
Compile an object file using FatLTO:
$ clang -flto -ffat-lto-objects example.c -c -o example.o
Link using the object code from the fat object without LTO. This turns
-ffat-lto-objects
into a no-op, when -fno-lto
is specified:
$ clang -fno-lto -ffat-lto-objects -fuse-ld=lld example.o
Alternatively, you can omit any references to LTO with fat objects and retain standard linker behavior:
$ clang -fuse-ld=lld example.o
Link using the LLVM bitcode from the fat object with Full LTO:
$ clang -flto -ffat-lto-objects -fuse-ld=lld example.o # clang will pass --lto=full --fat-lto-objects to ld.lld
Link using the LLVM bitcode from the fat object with Thin LTO:
$ clang -flto=thin -ffat-lto-objects -fuse-ld=lld example.o # clang will pass --lto=thin --fat-lto-objects to ld.lld