2016-03-10 16 views
11

Tôi đang cố gắng áp dụng Tối ưu hóa thời gian liên kết với LLVM trên một dự án CMake, tạo thư viện được chia sẻ. Câu hỏi của tôi khá giống với câu hỏi này:LTO với LLVM và CMake

Switching between GCC and Clang/LLVM using CMake.

Tuy nhiên, các câu trả lời dường như không còn được áp dụng nữa, vì llvm-ld không có trong các phiên bản mới. Trên dòng lệnh, tôi chạy các lệnh sau để có được LTO (Giả sử chỉ có 2 .cpp files):

Compile để mã byte:

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

liên kết mã byte:

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

Tối ưu hóa mã byte:

opt -O3 unoptimized.bc -o optimized.bc 

Chuyển đổi mã byte thành đối tượng được chia sẻ:

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

Ai đó có thể cho tôi biết làm thế nào để CMake chạy các bước bổ sung?

+2

Nó có thể là một công việc cho [ 'add_custom_command'] (https://cmake.org/cmake/help/v3 .0/command/add_custom_command.html) của cmake ... Một cái gì đó giống như 'add_custom_command (OUTPUT libTest.so COMMAND clang ++ -shared được tối ưu hóa.bc -o libTest.so MAIN_DEPENDENCY optimize.bc)' Xem http://stackoverflow.com/ câu hỏi/13470499/cmake-add-custom-command-with-dependencies-from-a-thư mục khác – francis

Trả lời

6

Cách chính xác để sử dụng Clang và bật LTO đang sử dụng cờ -flto vào dòng lệnh clang cả lúc biên dịch thời gian liên kết. Ngoài ra, bạn sẽ cần phải làm việc trên nền tảng với trình liên kết hỗ trợ trực tiếp LTO (nền tảng của Apple nói chung) hoặc có trình liên kết LLVM (Linux sử dụng trình liên kết Vàng, nhưng tôi nghĩ một số đã nhận được Liên kết BFD để hỗ trợ plugin trình liên kết). Nếu bạn đang sử dụng plugin trình liên kết, bạn sẽ cần phải đảm bảo cài đặt LLVM của bạn được xây dựng và cài đặt plugin. Nếu có, Clang sẽ tự động thêm các tùy chọn dòng lệnh liên kết cần thiết để sử dụng plugin khi liên kết với -flto, ngay cả đối với các đối tượng dùng chung.

Ngoài ra, dự án LLVM đang làm việc trên một liên kết mới (LLD) sẽ hỗ trợ LTO ra khỏi hộp trên tất cả các nền tảng nó hỗ trợ, nhưng nó vẫn còn khá sớm ngày. Hiện tại tôi biết những người thử nghiệm hỗ trợ LTO của mình trên Windows và Linux và dường như nó hoạt động tốt nhưng vẫn bỏ lỡ nhiều tính năng.

1

Kích hoạt (mỏng) LTO trên cmake 3.9 và mới hơn nên đơn giản:

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

Thay vì set_target_properties mỗi dự án, một khung cảnh toàn cầu duy nhất của set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) thể được thực hiện.

Để tăng tốc độ recompiles, một bộ nhớ cache cho LTO có thể được thiết lập:

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) 

Điều này buộc gold như mối liên kết, để sử dụng các tùy chọn dòng lệnh đúng. Nó có thể yêu cầu một liên kết tượng trưng của /usr/lib/LLVMgold.so đến /usr/lib/llvm-4.0/lib/LLVMgold.so.

2

check_ipo_supported() khiến tôi gặp lỗi "Policy CMP0069 chưa được đặt" trên CMake 3.9.1.

Mỗi trợ giúp của nó, Chỉ có tối đa 3,8 bản LTO của trình biên dịch Intel được hỗ trợ. Nó cũng không hoạt động trên tiếng kêu của XCode 9 cho tôi.

gì làm việc, cuối cùng:

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

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

Hình như add_executable() nhu cầu là sau khi cmake_policy(SET CMP0069 NEW).

LTO bộ nhớ cache

target_link_libraries(Foobar "-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache") đã không có hại.

Chọn tùy chọn dòng lệnh của bạn depending on your linker.

tùy chọn More tàn bạo

Theo @ ChandlerCarruth của câu trả lời:

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