Link Time Optimization

From SEGGER Wiki
Jump to: navigation, search

Link Time Optimization (LTO) enables additional optimization across compilation units to reduce code size or improve performance.

Compile Time Optimization

In a standard build system, each input source file is compiled into one compilation unit, usually an Elf object file. The compiler translates the source code into machine instructions and applies transformations according to the optimization level to generate fewer instructions or faster procedures. The instructions and data are stored in sections in the object file with additional information about required references to other sections which need to come from another object file.

Optimization is done separately within each object file. The generated sections cannot be modified by the linker (with the exception of resolving and inserting references). The linker takes all object files, places the sections according to the linker script, resolves references to sections from other object files, and may remove not referenced sections.

Link Time Optimization

LTO can apply inter-modular optimization. Instead of compiling each input source file into an object file, the compiler generates an intermediate representation, a bitcode, of the source code, which contains all information about references. The linker takes all intermediate files to resolve and analyze all references. In contrast to compiler optimization, the linker can modify the bitcode to apply optimization. It can remove unused references and symbols, but it can also inline sections and perform additional transformation.

After combining all intermediate files and applying optimization, the bitcode needs to be translated into machine instructions. The linker might feed the bitcode back to the compiler to do this step, or can directly be able to generate the target code.

Limitations of LTO

Debugging

LTO'd applications can usually not be debugged on source level anymore. During the linker's transformations the debug information about references from instructions to source code lines is not retained.

Mixed Input

LTO can only be applied to intermediate bitcode files. The linker can still take a combination of bitcode files and pre-compiled Elf object files to generate the target application. In this case, the object files are left untouched, but may provide symbol references which are used and required by the bitcode.

Additionally, if the object files contain any symbol references which need to be resolved at link time, these references need to be passed to LTO to keep the symbols when they are part of the bitcode. Otherwise LTO might remove all symbols and code which are not referenced from within the bitcode, leading to final linker errors.

FAQ

How to solve "error: undefined symbol A referenced by B" with LTO?

This error occurs when a symbol (function or variable) is not available in the final link step.

Usually this happens when a source file is accidentally not part of the build process.

If the error occurs only when LTO is enabled, there is a different solution: When B is a symbol of a pre-compiled library/object code, and A is a symbol implemented in source code, the linker needs to be configured to keep symbol A to not remove it during LTO. In Embedded Studio, add symbol A in project options -> Code -> Linker -> Keep Symbols

Examples for symbols in pre-compiled libraries, which need to be implemented in source code are:

 __SEGGER_RTL_X_file_bufsize, __SEGGER_RTL_X_file_stat, __SEGGER_RTL_X_file_write, stdout

in case Library I/O is set to None in Embedded Studio.