LLVM gold plugin

1. Introduction
2. How to build it
3. Usage
   - Example of link time optimization
   - Quickstart for using LTO with autotooled projects
4. Licensing

Written by Nick Lewycky
Introduction

Building with link time optimization requires cooperation from the system linker. LTO support on Linux systems requires that you use the gold linker which supports LTO via plugins. This is the same system used by the upcoming 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`.

How to build it

You need to build gold with plugin support and build the LLVMgold plugin.

- Build gold with plugin support:

      mkdir binutils
      cd binutils
      cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
      {enter "anoncvs" as the password}
      cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co src
      mkdir build
      cd build
      ../src/configure --enable-gold --enable-plugins
      make all-gold

  That should leave you with binutils/build/gold/ld-new which supports the `-plugin` option.
- Build the LLVMgold plugin: Configure LLVM with `--with-binutils-include=/path/to/binutils/src/include` and run `make`.

Usage

The linker takes a `-plugin` option that points to the path of the plugin `.so` file. To find out what link command `gcc` would run in a given situation, run `gcc -v [...]` and look for the line where it runs `collect2`. Replace that with `ld-new -plugin /path/to/LLVMgold.so` to test it out. Once you're ready to switch to using gold, backup your existing `/usr/bin/ld` then replace it with `ld-new`.

You can produce bitcode files from `llvm-gcc` using `-emit-llvm` or `-flto`, or the `-O4` flag which is synonymous with `-O3 -flto`.

`llvm-gcc` has a `-use-gold-plugin` option which looks for the gold plugin in the same directories as it looks for `cc1` and passes the `-plugin` option to ld. It will not look for an alternate linker, which is why you need gold to be the installed system linker in your path.

Example of link time optimization

The following example shows a worked example of the gold plugin mixing LLVM bitcode and native code.

    --- a.c ---
    #include <stdio.h>

    extern void foo1(void);
    extern void foo4(void);

    void foo2(void) {
      printf("Foo2\n");
    }

    void foo3(void) {
      foo4();
    }

    int main(void) {
      foo1();
    }

    --- b.c ---
    #include <stdio.h>

    extern void foo2(void);

    void foo1(void) {
      foo2();
    }

    void foo4(void) {
      printf("Foo4");
    }

    --- command lines ---
    $ llvm-gcc -flto a.c -c -o a.o              # <-- a.o is LLVM bitcode file
    $ ar q a.a a.o                              # <-- a.a is an archive with LLVM bitcode
    $ llvm-gcc b.c -c -o b.o                    # <-- b.o is native object file
    $ llvm-gcc -use-gold-plugin a.a b.o -o main # <-- link with LLVMgold plugin

Gold informs the plugin that foo3 is never referenced outside the IR, leading LLVM to delete that function. However, unlike in the libLTO example gold does not currently eliminate foo4.

Quickstart for using LTO with autotooled projects

`gold`, `ar` and `nm` all support plugins now, so everything should be in place for an easy to use LTO build of autotooled projects:

- Follow the instructions on how to build libLLVMgold.so.
- Install the newly built binutils to `$PREFIX`
- Copy `Release/lib/libLLVMgold.so` to `$PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/4.2.1/` and `$PREFIX/lib/bfd-plugins/`
- Set environment variables (`$PREFIX` is where you installed llvm-gcc and binutils):

      export CC="$PREFIX/bin/llvm-gcc -use-gold-plugin"
      export CXX="$PREFIX/bin/llvm-g++ -use-gold-plugin"
      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
      export CFLAGS="-O4"

- Or you can just set your path:

      export PATH="$PREFIX/bin:$PATH"
      export CC="llvm-gcc -use-gold-plugin"
      export CXX="llvm-g++ -use-gold-plugin"
      export RANLIB=/bin/true
      export CFLAGS="-O4"

- Configure & 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.