| ==================== | |
| 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. | |
| .. _`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 | |
| =============== | |
| 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: | |
| .. code-block:: bash | |
| $ 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 | |
| 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. |