LLVM gold 插件¶
简介¶
使用链接时优化需要系统链接器的配合。Linux 系统上的 LTO 支持可通过 gold 链接器 获得,该链接器通过插件支持 LTO。这与 GCC LTO 项目使用的机制相同。
LLVM gold 插件在 libLTO 之上实现了 gold 插件接口。相同的插件也可以被其他工具(如 ar
和 nm
)使用。请注意,来自 binutils 2.21.51.0.2 及更高版本的 ld.bfd 也通过插件支持 LTO。但是,LLVM gold 插件与 ld.bfd 的使用尚未经过测试,因此不提供官方支持或建议。
从 LLVM 15 开始,gold 插件将忽略 ELF 对象文件 .llvmbc
部分中的比特码。但是,仍然支持使用比特码文件的 LTO。
如何构建¶
您需要拥有支持插件的 gold 并构建 LLVMgold 插件。gold 链接器安装为 ld.gold。要查看 gold 是否为系统上的默认链接器,请运行 /usr/bin/ld -v
。它将报告“GNU gold”或如果不是则报告“GNU ld”。如果 gold 已安装在 /usr/bin/ld.gold
,则一个选项是简单地将其设置为默认链接器,方法是备份现有的 /usr/bin/ld
并使用 ln -s /usr/bin/ld.gold /usr/bin/ld
创建符号链接。或者,您可以使用 clang 的 -fuse-ld=gold
构建,或将 -fuse-ld=gold
添加到 LDFLAGS 中,这将导致 clang 驱动程序直接调用 /usr/bin/ld.gold
。
如果已安装 gold,请通过运行 /usr/bin/ld.gold -plugin
检查插件支持。如果它提示“缺少参数”,则表示您有插件支持。如果不是,并且您收到类似“未知选项”的错误,则您需要构建 gold 或安装具有插件支持的版本。
下载、配置并构建支持插件的 gold
$ 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
这应该会为您提供
build/gold/ld-new
,它支持-plugin
选项。运行make
还会额外构建build/binutils/ar
和nm-new
二进制文件,它们也支持插件。准备好切换到使用 gold 后,请备份现有的
/usr/bin/ld
,然后将其替换为ld-new
。或者,安装到/usr/bin/ld.gold
并如前所述使用-fuse-ld=gold
。可选地,将
--enable-gold=default
添加到上述配置调用中,以便在使用make install
时自动将新构建的 gold 安装为默认链接器。构建 LLVMgold 插件。使用
-DLLVM_BINUTILS_INCDIR=/path/to/binutils/include
运行 CMake。正确的包含路径将包含文件plugin-api.h
。
用法¶
您应该使用选项 -flto
从 clang
生成比特码文件。此标志还会导致 clang
在其前缀下的 lib
目录中查找 gold 插件,并将 -plugin
选项传递给 ld
。如果没有 -fuse-ld=gold
,它不会查找备用链接器,这就是为什么您需要将 gold 设置为路径中已安装的系统链接器的原因。
ar
和 nm
也接受 -plugin
选项,并且可以将 LLVMgold.so
安装到 /usr/lib/bfd-plugins
以实现无缝设置。如果您自己构建了 gold,请确保将您构建的 ar
和 nm-new
安装到 /usr/bin
。
链接时优化的示例¶
以下示例显示了 gold 插件混合 LLVM 比特码和原生代码的工作示例。
--- 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");
}
--- 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 通知插件 foo3 从未在 IR 外部引用过,导致 LLVM 删除该函数。但是,与 libLTO 示例 不同,gold 目前不会消除 foo4。
使用 LTO 的 autotools 项目快速入门¶
一旦您的系统 ld
、ar
和 nm
都支持 LLVM 比特码,那么就可以轻松地使用 LTO 构建 autotools 项目了
按照说明 了解如何构建 LLVMgold.so。
将新构建的 binutils 安装到
$PREFIX
将
Release/lib/LLVMgold.so
复制到$PREFIX/lib/bfd-plugins/
设置环境变量(
$PREFIX
是您安装 clang 和 binutils 的位置)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 PATH="$PREFIX/bin:$PATH" export CC="clang -flto" export CXX="clang++ -flto" export RANLIB=/bin/true
像往常一样配置和构建项目
% ./configure && make && make check
环境变量设置也可能适用于非 autotools 项目,但您可能还需要设置 LD
环境变量。
许可证¶
gold 采用 GPLv3 许可证。LLVMgold 使用来自 gold 的接口文件 plugin-api.h
,这意味着生成的 LLVMgold.so
二进制文件也采用 GPLv3 许可证。这仍然可以用于链接非 GPLv3 程序,就像没有插件的 gold 一样。