Building with link time optimization requires cooperation from the system linker. LTO support on Linux systems requires that you use the gold linker or ld.bfd from binutils >= 2.21.51.0.2, as they support 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
.
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 recent version
of ld.bfd with plugin support and then build gold plugin.
Download, configure and build ld.bfd with plugin support:
$ git clone --depth 1 git://sourceware.org/git/binutils-gdb.git binutils $ mkdir build $ cd build $ ../binutils/configure --disable-werror # ld.bfd includes plugin support by default $ make all-ld
That should leave you with
build/ld/ld-new
which supports the-plugin
option. Runningmake
will additionally buildbuild/binutils/ar
andnm-new
binaries supporting plugins.Build the LLVMgold plugin. Run CMake with
-DLLVM_BINUTILS_INCDIR=/path/to/binutils/include
. The correct include path will contain the fileplugin-api.h
.
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 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, which is why you 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
.
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
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.
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.