web-dev-qa-db-ja.com

LTOとLLVMおよびCMake

共有ライブラリを作成するCMakeプロジェクトでLLVMを使用してリンク時間最適化を適用しようとしています。私の質問はこれとほとんど同じです:

CMakeを使用したGCCとClang/LLVMの切り替え

ただし、llvm-ldは新しいバージョンには存在しないため、回答はもう適用されないようです。コマンドラインで次のコマンドを実行してLTOを取得します(.cppファイルが2つしかない場合)。

バイトコードにコンパイルします。

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

リンクバイトコード:

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

バイトコードを最適化する:

opt -O3 unoptimized.bc -o optimized.bc

バイトコードを共有オブジェクトに変換します。

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

CMakeに追加のステップを実行させる方法を誰かに教えてもらえますか?

18
SPMP

Clangを使用してLTOを有効にする正しい方法は、コンパイル時にclangコマンドラインに-fltoフラグを使用して、リンク時におよびリンクすることです。

さらに、LTOを直接サポートするリンカー(Appleのプラットフォーム一般)を備えたプラットフォーム、またはLLVMリンカープラグイン(Goldリンカーを使用するLinux)を備えたプラットフォームで作業する必要がありますが、BFDリンカーをサポートするようになっているものもあると思いますリンカープラグインも)。リンカープラグインを使用している場合は、LLVMのインストールがプラグインをビルドしてインストールしたことを確認する必要があります。その場合、Clangは、共有オブジェクトの場合でも、-fltoとリンクするときにプラグインを使用するために必要なリンカーコマンドラインオプションを自動的に追加します。

また、LLVMプロジェクトは、サポートするすべてのプラットフォームでそのままLTOをサポートする新しいリンカー(LLD)に取り組んでいますが、まだかなり初期の段階です。現在、私はWindowsとLinuxでLTOサポートをテストしている人々を知っています。それはうまく機能しているように見えますが、それでも多くの機能がありません。

13

check_ipo_supported()の結果、CMake 3.9.1で「 Policy CMP0069 is not set」エラーが発生しました。

その助けによれば、CMake 3.8まではIntelコンパイラのLTOのみをサポートしていました。 XCode 9のclangでも動作しませんでした。

結局のところ、うまくいったこと:

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

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

add_executable()cmake_policy(SET CMP0069 NEW)の後に置く必要があるようです。

LTOキャッシュ

target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache")は害を及ぼしませんでした。

コマンドラインオプションを選択します リンカーによって異なります

もっと残忍なオプション

@ChandlerCarruthの答えによると:

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

Cmake 3.9以降で(シン)ltoを有効にするのは簡単です。

_include(CheckIPOSupported)
check_ipo_supported()
set_target_properties(myProject PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
_

プロジェクトごとに_set_target_properties_の代わりに、set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)の単一のグローバル設定を行うことができます。

再コンパイルを高速化するために、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)
_

これにより、正しいコマンドラインオプションを使用するために、goldがリンカとして強制されます。 _/usr/lib/LLVMgold.so_から_/usr/lib/llvm-4.0/lib/LLVMgold.so_へのシンボリックリンクが必要な場合があります。

2
Mr. White