1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
====================
The LLVM gold plugin
====================
Introduction
============
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``.
.. _`gold linker`: http://sourceware.org/binutils
.. _`GCC LTO`: http://gcc.gnu.org/wiki/LinkTimeOptimization
.. _`gold plugin interface`: http://gcc.gnu.org/wiki/whopr/driver
.. _lto-how-to-build:
How to build it
===============
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:
.. code-block:: bash
$ 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. Running ``make`` will additionally build
``build/binutils/ar`` and ``nm-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 file ``plugin-api.h``.
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 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``.
Example of link time optimization
---------------------------------
The following example shows a worked example of the gold plugin mixing LLVM
bitcode and native code.
.. code-block:: 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");
}
.. code-block:: bash
--- 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):
.. code-block:: 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:
.. code-block:: 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:
.. code-block:: bash
% ./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.
|