| # 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 |
| {ref}`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. |
| |
| (lto-how-to-build)= |
| |
| ## 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: |
| |
| ```console |
| $ 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 |
| 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`. |
| |
| ### Example of link time optimization |
| |
| The following example shows a worked example of the gold plugin mixing LLVM |
| bitcode and native code. |
| |
| ```c |
| --- 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"); |
| } |
| ``` |
| |
| ```console |
| --- command lines --- |
| $ clang -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 |
| $ clang b.c -c -o b.o # <-- b.o is native object file |
| $ clang -flto 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 |
| {ref}`libLTO example <libLTO-example>` gold does not currently eliminate foo4. |
| |
| ## 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 |
| {ref}`on how to build LLVMgold.so <lto-how-to-build>`. |
| |
| - 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): |
| |
| ```bash |
| 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: |
| |
| ```bash |
| export PATH="$PREFIX/bin:$PATH" |
| export CC="clang -flto" |
| export CXX="clang++ -flto" |
| export RANLIB=/bin/true |
| ``` |
| |
| - Configure and build the project as usual: |
| |
| ```console |
| % ./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. |
| |
| [gcc lto]: http://gcc.gnu.org/wiki/LinkTimeOptimization |
| [gold linker]: http://sourceware.org/binutils |
| [gold plugin interface]: http://gcc.gnu.org/wiki/whopr/driver |
| |