==================== 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 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 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 ` 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 `. * 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.