LLVM gold 插件

简介

使用链接时优化需要系统链接器的配合。Linux 系统上的 LTO 支持可通过 gold 链接器 获得,该链接器通过插件支持 LTO。这与 GCC LTO 项目使用的机制相同。

LLVM gold 插件在 libLTO 之上实现了 gold 插件接口。相同的插件也可以被其他工具(如 arnm)使用。请注意,来自 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/arnm-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

用法

您应该使用选项 -fltoclang 生成比特码文件。此标志还会导致 clang 在其前缀下的 lib 目录中查找 gold 插件,并将 -plugin 选项传递给 ld。如果没有 -fuse-ld=gold,它不会查找备用链接器,这就是为什么您需要将 gold 设置为路径中已安装的系统链接器的原因。

arnm 也接受 -plugin 选项,并且可以将 LLVMgold.so 安装到 /usr/lib/bfd-plugins 以实现无缝设置。如果您自己构建了 gold,请确保将您构建的 arnm-new 安装到 /usr/bin

使用 LTO 的 autotools 项目快速入门

一旦您的系统 ldarnm 都支持 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 一样。