How to Build LLVM with Link Time Optimization (LTO)
Enable LTO when building LLVM by setting the LLVM_ENABLE_LTO CMake option to Thin or Full, and ensure you use an LTO-capable linker such as LLD or Gold.
Building the LLVM project with Link Time Optimization (LTO) produces faster, more optimized compiler binaries by enabling whole-program analysis across translation units. The llvm/llvm-project repository uses CMake to control this through the LLVM_ENABLE_LTO option, which configures the build to leverage the libLTO plugin and compatible linkers. This guide walks through the exact configuration steps, source files, and verification methods used in the official LLVM codebase.
Understanding LLVM's LTO Implementation
LLVM supports two distinct LTO modes that integrate with the build system at different stages of the pipeline.
CMake Option Configuration
The LLVM_ENABLE_LTO option is defined in llvm/cmake/modules/HandleLLVMOptions.cmake, where it defaults to OFF but accepts Thin or Full as valid values. When enabled, this variable propagates to the compiler flag generation logic, injecting -flto and linker-specific options during the configuration phase. The module validates that the selected linker supports LTO before generating the build targets.
The LTO Plugin Architecture
Link-time optimization relies on libLTO, implemented in llvm/lib/Linker, which provides the C API used by linkers to process LLVM bitcode at link time. The AddLLVM.cmake module (located at llvm/cmake/modules/AddLLVM.cmake) coordinates between the build system and libLTO by adding the necessary -Wl,-plugin-opt flags and ensuring the chosen linker (LLD or Gold) loads the appropriate plugin.
Prerequisites for Building LLVM with LTO
Before configuring the build, ensure your system meets the following requirements:
- LTO-capable linker: On Linux, install
lld(recommended) orld.gold. On Windows, LLD-link is mandatory. - Clang compiler: While GCC can work, LLVM officially recommends building with Clang (
clangandclang++) to ensure optimal LTO compatibility. - Sufficient memory: Full-LTO requires significantly more RAM during linking than Thin-LTO or standard builds.
- CMake and Ninja: Version 3.20+ of CMake and a recent Ninja build system for efficient parallel compilation.
Configuring and Building LLVM with LTO
Follow these steps to configure and compile LLVM with LTO enabled, using the exact CMake variables referenced in the source tree.
Step 1: Select an LTO-Capable Linker
On Linux systems, install LLD via your package manager, or ensure ld.gold is available. On Windows, the LLVM build system will emit an error if LLD-link is not detected when LLVM_ENABLE_LTO is active.
Step 2: Configure CMake with LLVM_ENABLE_LTO
Create a build directory and run CMake with the appropriate LTO setting. The LLVM_ENABLE_LTO flag propagates to HandleLLVMOptions.cmake, which switches the build mode to Thin-LTO or Full-LTO.
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
mkdir build && cd build
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;lld;mlir" \
-DLLVM_ENABLE_LTO=Thin \
-DLLVM_USE_LINKER=lld \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
../llvm
For Full-LTO (classic LTO with whole-program optimization), change -DLLVM_ENABLE_LTO=Full and ensure you have sufficient memory available.
Step 3: Build the Project
Invoke your build tool to compile with LTO flags active. During this process, CMake adds -flto to compilation commands, and the final link step invokes the LTO plugin through AddLLVM.cmake.
ninja
Step 4: Verify LTO Sections in Binaries
After building, verify that LTO was applied by inspecting the binary for SHT_LLVM_LTO sections using llvm-readelf.
llvm-readelf -S bin/clang | grep LTO
The presence of .llvm.lto or SHT_LLVM_LTO sections confirms the binary was built with Link Time Optimization.
CMake Configuration Examples
Choose the configuration that matches your optimization needs and hardware constraints.
Thin-LTO Configuration (Recommended)
Thin-LTO performs fast, scalable summary analysis and requires less memory than Full-LTO.
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_ENABLE_LTO=Thin \
-DLLVM_USE_LINKER=lld \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
../llvm
Full-LTO Configuration
Full-LTO performs whole-program optimization but requires substantial memory during the final link step.
cmake -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;lld;polly" \
-DLLVM_ENABLE_LTO=Full \
-DLLVM_USE_LINKER=gold \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
../llvm
Summary
- Set
LLVM_ENABLE_LTO=ThinorLLVM_ENABLE_LTO=Fullin your CMake configuration to build LLVM with Link Time Optimization. - Use an LTO-capable linker such as LLD or Gold via the
LLVM_USE_LINKERvariable. - The
HandleLLVMOptions.cmakemodule processes LTO settings, whileAddLLVM.cmakeinjects the necessary compiler and linker flags. - Verify LTO application by checking for
SHT_LLVM_LTOsections in built binaries usingllvm-readelf. - Thin-LTO offers a balance of performance and resource usage, while Full-LTO provides maximum optimization at the cost of higher memory requirements.
Frequently Asked Questions
What is the difference between Thin-LTO and Full-LTO when building LLVM?
Thin-LTO performs a fast, scalable analysis using summary information, allowing parallel backend compilation and reduced memory usage. Full-LTO performs whole-program optimization by merging all bitcode into a single module at link time, resulting in potentially better optimization but requiring significantly more memory and time during linking. The choice is controlled by setting LLVM_ENABLE_LTO to the corresponding value in your CMake configuration.
Which linker should I use for building LLVM with LTO on Linux?
LLVM recommends using LLD (lld) when building with LTO, specified via -DLLVM_USE_LINKER=lld. Alternatively, the Gold linker (ld.gold) with the LLVM plugin is supported. The build system in AddLLVM.cmake validates linker compatibility and emits errors if the selected linker cannot support LTO.
How can I verify that LLVM was built with LTO enabled?
After building, run llvm-readelf -S on any generated binary (such as bin/clang) and search for LTO-related sections. The presence of sections named .llvm.lto or entries with SHT_LLVM_LTO type confirms that Link Time Optimization was active during the build process.
Does building LLVM with LTO require more memory than a standard build?
Yes, particularly when using Full-LTO. Full-LTO consolidates all translation units during the link step, which can consume substantial RAM on large projects like LLVM. Thin-LTO mitigates this by processing modules in parallel, making it the recommended approach for systems with limited memory.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →