diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -711,6 +711,16 @@ endif() endif() + if(BOOTSTRAP_LLVM_BOLT) + add_dependencies(clang-bootstrap-deps llvm-bolt merge-fdata) + set(LLVM_BOLT ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-bolt) + set(MERGE_FDATA ${LLVM_RUNTIME_OUTPUT_INTDIR}/merge-fdata) + list(APPEND _BOOTSTRAP_DEFAULT_PASSTHROUGH + LLVM_BOLT + MERGE_FDATA + ) + endif() + if(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED) add_dependencies(clang-bootstrap-deps llvm-profdata) set(PGO_OPT -DLLVM_PROFDATA=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-profdata) @@ -854,35 +864,47 @@ set(CLANG_INSTRUMENTED ${CLANG_PATH}-bolt.inst) set(BOLT_FDATA ${CMAKE_CURRENT_BINARY_DIR}/utils/perf-training/prof.fdata) - # Instrument clang with BOLT - add_custom_target(clang-instrumented - DEPENDS ${CLANG_INSTRUMENTED} - ) - add_custom_command(OUTPUT ${CLANG_INSTRUMENTED} - DEPENDS clang llvm-bolt - COMMAND llvm-bolt ${CLANG_PATH} -o ${CLANG_INSTRUMENTED} - -instrument --instrumentation-file-append-pid - --instrumentation-file=${BOLT_FDATA} - COMMENT "Instrumenting clang binary with BOLT" - VERBATIM - ) + add_custom_target(bolt-clang-instrumented-deps) + if ("bolt" IN_LIST LLVM_ENABLE_PROJECTS) + add_dependencies(bolt-clang-instrumented-deps llvm-bolt) + set(LLVM_BOLT $) + elseif (NOT LLVM_BOLT) + find_program(LLVM_BOLT llvm-bolt) + endif() - # Optimize original (pre-bolt) Clang using the collected profile - set(CLANG_OPTIMIZED ${CMAKE_CURRENT_BINARY_DIR}/clang.bolt) - add_custom_target(clang-bolt - DEPENDS ${CLANG_OPTIMIZED} - ) - add_custom_command(OUTPUT ${CLANG_OPTIMIZED} - DEPENDS clang-bolt-profile - COMMAND llvm-bolt ${CLANG_PATH} - -o ${CLANG_OPTIMIZED} - -data ${BOLT_FDATA} - -reorder-blocks=ext-tsp -reorder-functions=hfsort+ -split-functions - -split-all-cold -split-eh -dyno-stats -icf=1 -use-gnu-stack - COMMAND ${CMAKE_COMMAND} -E rename ${CLANG_OPTIMIZED} $ - COMMENT "Optimizing Clang with BOLT" - VERBATIM - ) + if (NOT LLVM_BOLT AND NOT "bolt" IN_LIST LLVM_ENABLE_PROJECTS) + message(STATUS "To enable optimizing Clang with BOLT enable bolt project or set LLVM_BOLT") + else() + # Instrument clang with BOLT + add_custom_target(clang-instrumented + DEPENDS ${CLANG_INSTRUMENTED} + ) + add_custom_command(OUTPUT ${CLANG_INSTRUMENTED} + DEPENDS bolt-clang-instrumented-deps clang + COMMAND ${LLVM_BOLT} ${CLANG_PATH} -o ${CLANG_INSTRUMENTED} + -instrument --instrumentation-file-append-pid + --instrumentation-file=${BOLT_FDATA} + COMMENT "Instrumenting clang binary with BOLT" + VERBATIM + ) + + # Optimize original (pre-bolt) Clang using the collected profile + set(CLANG_OPTIMIZED ${CMAKE_CURRENT_BINARY_DIR}/clang.bolt) + add_custom_target(clang-bolt + DEPENDS ${CLANG_OPTIMIZED} + ) + add_custom_command(OUTPUT ${CLANG_OPTIMIZED} + DEPENDS clang-bolt-profile + COMMAND ${LLVM_BOLT} ${CLANG_PATH} + -o ${CLANG_OPTIMIZED} + -data ${BOLT_FDATA} + -reorder-blocks=ext-tsp -reorder-functions=hfsort+ -split-functions + -split-all-cold -split-eh -dyno-stats -icf=1 -use-gnu-stack + COMMAND ${CMAKE_COMMAND} -E rename ${CLANG_OPTIMIZED} $ + COMMENT "Optimizing Clang with BOLT" + VERBATIM + ) + endif() endif() if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) diff --git a/clang/cmake/caches/BOLT-PGO-stage2.cmake b/clang/cmake/caches/BOLT-PGO-stage2.cmake new file mode 100644 --- /dev/null +++ b/clang/cmake/caches/BOLT-PGO-stage2.cmake @@ -0,0 +1,13 @@ +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(CLANG_BOLT_INSTRUMENT ON CACHE BOOL "") +set(CMAKE_EXE_LINKER_FLAGS "-Wl,--emit-relocs,-znow" CACHE STRING "") + +set(LLVM_ENABLE_PROJECTS "clang" CACHE STRING "") +set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "") + +# setup toolchain +set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "") +set(LLVM_DISTRIBUTION_COMPONENTS + clang + clang-resource-headers + CACHE STRING "") diff --git a/clang/cmake/caches/BOLT-PGO.cmake b/clang/cmake/caches/BOLT-PGO.cmake --- a/clang/cmake/caches/BOLT-PGO.cmake +++ b/clang/cmake/caches/BOLT-PGO.cmake @@ -11,7 +11,9 @@ install-distribution CACHE STRING "") +set(BOOTSTRAP_LLVM_BOLT ON) + set(PGO_BUILD_CONFIGURATION - ${CMAKE_CURRENT_LIST_DIR}/BOLT.cmake + ${CMAKE_CURRENT_LIST_DIR}/BOLT-PGO-stage2.cmake CACHE STRING "") include(${CMAKE_CURRENT_LIST_DIR}/PGO.cmake) diff --git a/clang/utils/perf-training/CMakeLists.txt b/clang/utils/perf-training/CMakeLists.txt --- a/clang/utils/perf-training/CMakeLists.txt +++ b/clang/utils/perf-training/CMakeLists.txt @@ -78,9 +78,21 @@ COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py clean ${CMAKE_CURRENT_BINARY_DIR} fdata COMMENT "Clearing old BOLT fdata") - # Merge profiles into one using merge-fdata - add_custom_target(clang-bolt-profile - COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge-fdata $ ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Merging BOLT fdata" - DEPENDS merge-fdata generate-bolt-fdata) + add_custom_target(clang-bolt-profile-deps) + if ("bolt" IN_LIST LLVM_ENABLE_PROJECTS) + add_dependencies(clang-bolt-profile-deps merge-fdata) + set(MERGE_FDATA $) + elseif (NOT MERGE_FDATA) + find_program(MERGE_FDATA merge-fdata) + endif() + + if (NOT MERGE_FDATA AND NOT "bolt" IN_LIST LLVM_ENABLE_PROJECTS) + message(STATUS "To enable optimizing Clang with BOLT enable bolt project or set MERGE_FDATA") + else() + # Merge profiles into one using merge-fdata + add_custom_target(clang-bolt-profile + COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge-fdata ${MERGE_FDATA} ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Merging BOLT fdata" + DEPENDS clang-bolt-profile-deps generate-bolt-fdata) + endif() endif()