2012-10-04 05:56:23 +02:00
|
|
|
====================
|
|
|
|
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`_ 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``.
|
|
|
|
|
|
|
|
.. _`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.
|
|
|
|
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:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
$ mkdir binutils
|
|
|
|
$ cd binutils
|
|
|
|
$ cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
|
|
|
|
{enter "anoncvs" as the password}
|
|
|
|
$ cvs -z 9 -d :pserver:anoncvs@sourceware.org:/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 have
|
|
|
|
``binutils/build/binutils/ar`` and ``nm-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 run
|
|
|
|
``make``.
|
|
|
|
|
|
|
|
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 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
|
2012-10-05 22:50:05 +02:00
|
|
|
gold to be the installed system linker in your path.
|
2012-10-04 05:56:23 +02:00
|
|
|
|
|
|
|
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
|
2012-10-05 22:50:05 +02:00
|
|
|
sure to install the ``ar`` and ``nm-new`` you built to ``/usr/bin``.
|
2012-10-04 05:56:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
export CFLAGS="-O4"
|
|
|
|
|
|
|
|
* 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
|
|
|
|
export CFLAGS="-O4"
|
|
|
|
* 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
|
2012-10-05 22:50:05 +02:00
|
|
|
``plugin-api.h`` from gold which means that the resulting ``LLVMgold.so``
|
2012-10-04 05:56:23 +02:00
|
|
|
binary is also GPLv3. This can still be used to link non-GPLv3 programs
|
|
|
|
just as much as gold could without the plugin.
|