The LLVM gold plugin

Introduction

Building with link time optimization requires cooperation from the system linker. LTO support on Linux systems is available via the gold linker which supports LTO via plugins. This is the same mechanism used by the GCC LTO project.

The LLVM gold plugin implements the gold plugin interface on top of libLTO. The same plugin can also be used by other tools such as ar and nm. Note that ld.bfd from binutils version 2.21.51.0.2 and above also supports LTO via plugins. However, usage of the LLVM gold plugin with ld.bfd is not tested and therefore not officially supported or recommended.

As of LLVM 15, the gold plugin will ignore bitcode from the .llvmbc section inside of ELF object files. However, LTO with bitcode files is still supported.

How to build it

You need to have gold with plugin support and build the LLVMgold plugin. The gold linker is installed as ld.gold. To see whether gold is the default on your system, run /usr/bin/ld -v. It will report “GNU gold” or else “GNU ld” if not. If gold is already installed at /usr/bin/ld.gold, one option is to simply make that the default by backing up your existing /usr/bin/ld and creating a symbolic link with ln -s /usr/bin/ld.gold /usr/bin/ld. Alternatively, you can build with clang’s -fuse-ld=gold or add -fuse-ld=gold to LDFLAGS, which will cause the clang driver to invoke /usr/bin/ld.gold directly.

If you have gold installed, check for plugin support by running /usr/bin/ld.gold -plugin. If it complains “missing argument” then you have plugin support. If not, and you get an error such as “unknown option”, then you will either need to build gold or install a version with plugin support.

  • Download, configure and build gold with plugin support:

    $ git clone --depth 1 git://sourceware.org/git/binutils-gdb.git binutils
    $ mkdir build
    $ cd build
    $ ../binutils/configure --enable-gold --enable-plugins --disable-werror
    $ make all-gold
    

    That should leave you with build/gold/ld-new which supports the -plugin option. Running make will additionally build build/binutils/ar and nm-new binaries supporting plugins.

    Once you’re ready to switch to using gold, backup your existing /usr/bin/ld then replace it with ld-new. Alternatively, install in /usr/bin/ld.gold and use -fuse-ld=gold as described earlier.

    Optionally, add --enable-gold=default to the above configure invocation to automatically install the newly built gold as the default linker with make install.

  • Build the LLVMgold plugin. Run CMake with -DLLVM_BINUTILS_INCDIR=/path/to/binutils/include. The correct include path will contain the file plugin-api.h.

Usage

You should produce bitcode files from clang with the option -flto. This flag will also cause clang to look for the gold plugin in the lib directory under its prefix and pass the -plugin option to ld. It will not look for an alternate linker without -fuse-ld=gold, which is why you otherwise need gold to be the installed system linker in your path.

ar and nm also accept the -plugin option and it’s possible to to install LLVMgold.so to /usr/lib/bfd-plugins for a seamless setup. If you built your own gold, be sure to install the ar and nm-new you built to /usr/bin.

Quickstart for using LTO with autotooled projects

Once your system ld, ar, and nm all support LLVM bitcode, everything is in place for an easy to use LTO build of autotooled projects:

  • Follow the instructions on how to build LLVMgold.so.

  • Install the newly built binutils to $PREFIX

  • Copy Release/lib/LLVMgold.so to $PREFIX/lib/bfd-plugins/

  • Set environment variables ($PREFIX is where you installed clang and binutils):

    export CC="$PREFIX/bin/clang -flto"
    export CXX="$PREFIX/bin/clang++ -flto"
    export AR="$PREFIX/bin/ar"
    export NM="$PREFIX/bin/nm"
    export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
    
  • Or you can just set your path:

    export PATH="$PREFIX/bin:$PATH"
    export CC="clang -flto"
    export CXX="clang++ -flto"
    export RANLIB=/bin/true
    
  • Configure and build the project as usual:

    % ./configure && make && make check
    

The environment variable settings may work for non-autotooled projects too, but you may need to set the LD environment variable as well.

Licensing

Gold is licensed under the GPLv3. LLVMgold uses the interface file plugin-api.h from gold which means that the resulting LLVMgold.so binary is also GPLv3. This can still be used to link non-GPLv3 programs just as much as gold could without the plugin.