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 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
.
You need to have gold with plugin support and build the LLVMgold plugin.
Check whether you have gold running /usr/bin/ld -v
. It will report "GNU
gold" or else "GNU ld" if not. If you have gold, check for plugin support
by running /usr/bin/ld -plugin
. If it complains "missing argument" then
you have plugin support. If not, such as an "unknown option" error then you
will either need to build gold or install a version with plugin support.
To build gold with plugin support:
$ mkdir binutils $ cd binutils $ cvs -z 9 -d :pserver:[email protected]:/cvs/src login {enter "anoncvs" as the password} $ cvs -z 9 -d :pserver:[email protected]:/cvs/src co binutils $ 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. It also built would havebinutils/build/binutils/ar
andnm-new
which support plugins but don't have a visible -plugin option, instead relying on the gold plugin being present in../lib/bfd-plugins
relative to where the binaries are placed.Build the LLVMgold plugin: Configure LLVM with
--with-binutils-include=/path/to/binutils/src/include
and runmake
.
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 clang
using -emit-llvm
or
-flto
, or the -O4
flag which is synonymous with -O3 -flto
.
Any of these flags 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, which is why you need
gold to be the installed system linker in your path.
If you want ar
and nm
to work seamlessly as well, install
LLVMgold.so
to /usr/lib/bfd-plugins
. If you built your own gold, be
sure to install the ar
and nm-new
you built to /usr/bin
.
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 ---
$ 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.
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):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 export CFLAGS="-O4"
Or you can just set your path:
export PATH="$PREFIX/bin:$PATH" export CC="clang -flto" export CXX="clang++ -flto" export RANLIB=/bin/true export CFLAGS="-O4"
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.
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.