简体   繁体   English

使用 LLVM 和 CMake 的 LTO

[英]LTO with LLVM and CMake

I am trying to apply Link Time Optimization with LLVM on a CMake Project, that creates a shared library.我正在尝试在创建共享库的 CMake 项目上使用 LLVM 应用链接时间优化。 My question is pretty much the same as this one:我的问题与这个问题几乎相同:

Switching between GCC and Clang/LLVM using CMake . 使用 CMake 在 GCC 和 Clang/LLVM 之间切换

However, the answers do not seem to be applicable anymore, since llvm-ld is not present in the new versions.但是,答案似乎不再适用,因为新版本中不存在llvm-ld On the command line, I run the following commands to get LTO (Assuming there are only 2 .cpp files):在命令行上,我运行以下命令来获取 LTO(假设只有 2 个.cpp文件):

Compile to byte code:编译为字节码:

clang++ -c FirstClass.cpp -O3 -flto -o FirstClass.bc
clang++ -c SecondClass.cpp -O3 -flto -o SecondClass.bc

Link byte code:链接字节码:

llvm-link FirstClass.bc SecondClass.bc -o unoptimized.bc

Optimize byte code:优化字节码:

opt -O3 unoptimized.bc -o optimized.bc

Convert byte code to shared object:将字节码转换为共享对象:

clang++ -shared optimized.bc -o libTest.so

Could somebody please tell me how to have CMake run the additional steps?有人可以告诉我如何让 CMake 运行附加步骤吗?

The correct way to use Clang and enable LTO is using the -flto flag to the clang command line both at compile and link time.使用 Clang 和启用 LTO 的正确方法是在编译链接时对clang命令行使用-flto标志。

In addition, you will need to be working on a platform with a linker that either directly supports LTO (Apple's platforms generally) or that have an LLVM linker plugin (Linux using the Gold linker, but I think some have gotten the BFD linker to support the linker plugin as well).此外,您需要在一个带有链接器的平台上工作,该链接器直接支持 LTO(通常是 Apple 的平台)或具有 LLVM 链接器插件(Linux 使用 Gold 链接器,但我认为有些已经获得了 BFD 链接器支持)链接器插件也是如此)。 If you're using the linker plugin, you'll need to make sure your install of LLVM built and installed the plugin.如果您使用的是链接器插件,则需要确保您安装的 LLVM 已构建并安装了该插件。 If it did, Clang will automatically add the necessary linker command line options to use the plugin when linking with -flto , even for shared objects.如果是这样,Clang 将自动添加必要的链接器命令行选项以在与-flto链接时使用插件,即使对于共享对象也是如此。

Also, The LLVM project is working on a new linker (LLD) which will support LTO out of the box on all the platforms it supports, but it is still pretty early days.此外,LLVM 项目正在开发一个新的链接器 (LLD),它将在它支持的所有平台上开箱即用地支持 LTO,但它仍然处于早期阶段。 Currently I know of folks testing out its LTO support on Windows and Linux, and it seems to be working well but still misses many features.目前我知道有人在 Windows 和 Linux 上测试了它的 LTO 支持,它似乎运行良好,但仍然缺少许多功能。

check_ipo_supported() resulted for me in " Policy CMP0069 is not set" error on CMake 3.9.1. check_ipo_supported()导致我在 CMake 3.9.1 上出现“未设置策略 CMP0069 ”错误。

Per its help, CMake up to 3.8 only supported Intel compiler's LTO.根据其帮助,最高 3.8 的 CMake 仅支持英特尔编译器的 LTO。 It didn't work on XCode 9's clang for me either.它对我来说也不适用于 XCode 9 的叮当声。

What worked, in the end:什么工作,最后:

cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported)
check_ipo_supported()

add_executable(Foobar SOURCES)
set_target_properties(Foobar PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

Looks like add_executable() needs to be after cmake_policy(SET CMP0069 NEW) .看起来add_executable()需要在cmake_policy(SET CMP0069 NEW)

LTO cache LTO缓存

target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache") did no harm. target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache")没有坏处。

Pick your command-line option depending on your linker .根据您的链接器选择您的命令行选项。

More brutal option更残酷的选择

According to @ChandlerCarruth's answer:根据@ChandlerCarruth 的回答:

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
    target_link_libraries(Foobar -flto)
endif ()

Enabling (thin) lto on Cmake 3.9 and newer should be straightforward:在 Cmake 3.9 和更新版本上启用(瘦)lto 应该很简单:

include(CheckIPOSupported)
check_ipo_supported()
set_target_properties(myProject PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

Instead of set_target_properties per project, a single global setting of set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) can be done.取而代之的set_target_properties每个项目,单一全局设置set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)可以做到的。

In order to speed up recompiles, a cache for LTO can be set:为了加速重新编译,可以设置 LTO 的缓存:

function(append value)
    foreach(variable ${ARGN})
        set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
    endforeach(variable)
endfunction()

append("-fuse-ld=gold -Wl,--no-threads,--plugin-opt,cache-dir=${PROJECT_BINARY_DIR}/lto.cache" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)

This forces gold as linker, in order to use the right command line options.这会强制gold作为链接器,以便使用正确的命令行选项。 It might require a symlink of /usr/lib/LLVMgold.so to /usr/lib/llvm-4.0/lib/LLVMgold.so .它可能需要/usr/lib/LLVMgold.so/usr/lib/llvm-4.0/lib/LLVMgold.so的符号链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM