LTO

From Gentoo Wiki
(Redirected from User:Immolo/LTO)
Jump to:navigation Jump to:search

Link Time Optimization (LTO) is the term for a class of optimizations done during linking. The linker is aware of all the translation units (TUs) and can optimize more compared to what conventional optimization passes by a compiler individually can do. The most important optimizations that linker does are inlining and code locality improvements. This can increase system performance at the cost of longer compile time.

This article will show the user how to enable LTO without the need for third party overlays and using recommended tested CFLAGS for the best performance and system stability (with either GCC or LLVM-based toolchains).

Benefits of LTO

  • LTO can give double digit performance boosts for many programs.
  • Can lower RAM usage per program making it very useful for limited memory systems.

Downsides of LTO

  • Can increase compile time by 2 to 3 times.
  • Uses more RAM during compiling.
  • Not all programs become faster or smaller.
  • There is an increased chance of finding build-time or runtime bugs while using it.
  • Always be prepared to try without it if something is acting odd.

Enabling LTO System-wide

GCC Systems

Enable LTO

To enable LTO package building on GCC systems, edit /etc/portage/make.conf then add LTO to the USE line and -flto to the COMMON_FLAGS.

FILE /etc/portage/make.confmake.conf example
# These warnings indicate likely runtime problems with LTO, so promote them
# to errors. If a package fails to build with these, LTO should not be used there.
WARNING_FLAGS="-Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing"

COMMON_FLAGS="-O2 -pipe -march=native -flto ${WARNING_FLAGS}"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
USE="lto"

With this, LTO is now enabled on the system for all future emerges.

With GCC you can also pass the number of processes to use for linking to the -flto parameter using -flto=NUMBER-OF-PROCESSES which will speed it up. -flto=7 is a good value to use.

LLVM Systems

Enable LTO

All that is needed is to -flto to COMMON_FLAGS and lto to USE:

FILE /etc/portage/make.confmake.conf example
# These warnings indicate likely runtime problems with LTO, so promote them
# to errors. If a package fails to build with these, LTO should not be used there.
#
# Clang will soon gain -Wstrict-aliasing as a real warning (noop for now):
# https://github.com/llvm/llvm-project/pull/74155
#
# Clang does not yet have -Wlto-type-mismatch:
# https://github.com/llvm/llvm-project/issues/56487
WARNING_FLAGS="-Werror=odr -Werror=strict-aliasing"

COMMON_FLAGS="-O2 -pipe -march=native -flto ${WARNING_FLAGS}"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
USE="lto"

USE Flags

On both GCC and LLVM systems, some packages required special fixes to work with LTO and this is enabled by setting globally the lto USE flag.

FILE /etc/portage/make.confUSE flag example
USE="lto"

Troubleshooting, Fixing and Reporting LTO Issues

While LTO works without issue for most users thanks to the hard work of everyone in the community in Gentoo and beyond, there are still some packages that a user may run across that have been missed.

This section will show how to fix the issue for the their system and also report the issue (if needed) so it can be fixed for everyone to help make Gentoo better for everyone in the future.

Stable Systems

As of 2023-05-15, LTO fixes have mostly trickled down from testing to stable (e.g. ~amd64 to amd64). However, there may be exceptions, so before reporting, try the latest version of the package in the testing branch to see if it's already fixed and save themselves and the developers time and effort.

Note
In this example, app-editors/emacs is used to show steps. However, please be aware this may already be fixed at the time of reading, so should only be viewed as an example of the troubleshooting steps LTO users to be followed.
root #emerge --ask app-editors/emacs

In this example, on a stable amd64 system, Portage would compile version 28.2-r6. On the first sign of a build issues, check packages.gentoo.org if there is a version in testing. In this case, one would find that there is a version 28.3_rc1-r2 available.

In this case, the next step would be to temporarily accept the keyword for that version only so Portage only uses the testing version until the stable package version catches up to the fix.

To only accept the keyword for one version, then an = is required before the package type and then the version number after:

FILE /etc/portage/package.accept_keywords/emacsKeywording Example
=app-editors/emacs-28.3_rc1-r2

Then try to emerge the updated version:

root #emerge --ask app-editors/emacs

If the package now compiles fine, then no reporting is needed by the user. If, however, it still fails, then continue to the next step.

Latest Version Issues

Existing Reports Procedure

First check if a bug already exsts for the problem at bugs.gentoo.org. Using the search tool, looking up "emacs lto" would show a reported bug already as bug #854360.

Next, compare the reported version to the version tested on the system. If the version are the same, then no action is needed however, if the tested version was newer,then adding a comment that the problem still exists in the version testing should be added to help save time for the person working on the bug.

New Bugs Procedure

In the case of no bug being open after searching, then opening a new report is one of the most helpful things a Gentoo user can do to help highlight issues.

Do remember there is no shame if a mistake is made so there is no need for a user to feel nervous as you will be guided on what extra information is needed if required.

A bad bug report is always preferred over a perfect report that never gets reported.

Information Required

A good title helps, for example "app-editors/emacs-28.3_rc1-r2: fails to compile with LTO"

A short description of the issue and what has been tried so far.

Steps to reproduce, preferably from a fresh stage3 install:

  1. Install stage3 <tarball name used>
  2. Enable lto in make.conf via flags, per above instructions
  3. Add app-editors/emacs-28.3_rc1-r2 to package.accept_keywords
  4. emerge -va app-editors/emacs

Attach the build.log to the bug report from the location portage gives.

Add the output of emerge --info to a section comment.

This may sound confusing the first time, however it's very easy after the first time, and can be fun to watch a reported bug get fixed in real time.

Disable LTO per Package

After reporting, it's still possible to workaround the issue until a fix is committed by disabling LTO using package.env.

Create nolto.conf

package.env configuration is a Portage feature that allows a user to set CFLAGS and other options on a per-package basis.

Create /etc/portage/env/nolto.conf with the following:

FILE /etc/portage/env/nolto.confnolto.conf example
# Env setup to disable LTO and related warnings for problematic builds
DISABLE_LTO="-Wno-error=odr -Wno-error=lto-type-mismatch -Wno-error=strict-aliasing -fno-lto"
CFLAGS="${CFLAGS} ${DISABLE_LTO}"
CXXFLAGS="${CXXFLAGS} ${DISABLE_LTO}"
FCFLAGS="${FCFLAGS} ${DISABLE_LTO}"
FFLAGS="${FFLAGS} ${DISABLE_LTO}"

These is the configuration that Portage will use for packages defined in the next step.

Create package.env/noltobuild

Suppose further emacs is an problematic package, then /etc/portage/package.env/noltobuild would look like:

FILE /etc/portage/package.env/noltobuildnoltobuild config example
app-editors/emacs nolto.conf

Now compiling app-editors/emacs on the user's system would no longer build with LTO and the compiling issue found at the start would be fixed as a workaround until a permanent fix is found in Gentoo.

See Also