2012-10-04 11:56:23 +08: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.
|
|
|
|
|
2013-12-02 15:15:33 +08:00
|
|
|
* Download, configure and build gold with plugin support:
|
2012-10-04 11:56:23 +08:00
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
2013-12-02 15:15:33 +08:00
|
|
|
$ git clone --depth 1 git://sourceware.org/git/binutils-gdb.git binutils
|
2012-10-04 11:56:23 +08:00
|
|
|
$ mkdir build
|
|
|
|
$ cd build
|
2013-12-02 15:15:33 +08:00
|
|
|
$ ../binutils/configure --enable-gold --enable-plugins --disable-werror
|
2012-10-04 11:56:23 +08:00
|
|
|
$ make all-gold
|
|
|
|
|
2013-12-02 15:15:33 +08:00
|
|
|
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.
|
2012-10-04 11:56:23 +08:00
|
|
|
|
2016-01-30 09:10:15 +08:00
|
|
|
* Build the LLVMgold plugin. Run CMake with
|
2014-11-04 10:16:03 +08:00
|
|
|
``-DLLVM_BINUTILS_INCDIR=/path/to/binutils/include``. The correct include
|
|
|
|
path will contain the file ``plugin-api.h``.
|
2012-10-04 11:56:23 +08:00
|
|
|
|
|
|
|
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``.
|
|
|
|
|
2013-09-24 03:50:59 +08:00
|
|
|
You should produce bitcode files from ``clang`` with the option
|
2013-10-27 12:25:02 +08:00
|
|
|
``-flto``. This flag will also cause ``clang`` to look for the gold plugin in
|
2012-10-04 11:56:23 +08:00
|
|
|
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-06 04:50:05 +08:00
|
|
|
gold to be the installed system linker in your path.
|
2012-10-04 11:56:23 +08:00
|
|
|
|
2013-12-02 15:15:33 +08:00
|
|
|
``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``.
|
2012-10-04 11:56:23 +08: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
|
|
|
|
|
|
|
|
* 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
|
2012-10-06 04:50:05 +08:00
|
|
|
``plugin-api.h`` from gold which means that the resulting ``LLVMgold.so``
|
2012-10-04 11:56:23 +08:00
|
|
|
binary is also GPLv3. This can still be used to link non-GPLv3 programs
|
|
|
|
just as much as gold could without the plugin.
|