diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -443,7 +443,7 @@ "HAVE_CLANG_PLUGIN_SUPPORT" OFF) # If libstdc++ is statically linked, clang-repl needs to statically link libstdc++ -# itself, which is not possible in many platforms because of current limitations in +# itself, which is not possible in many platforms because of current limitations in # JIT stack. (more platforms need to be supported by JITLink) if(NOT LLVM_STATIC_LINK_CXX_STDLIB) set(HAVE_CLANG_REPL_SUPPORT ON) @@ -878,6 +878,97 @@ endforeach() endif() +if (CLANG_BOLT_INSTRUMENT) + set(C_COMPILER "clang-bolt.inst") + set(CXX_COMPILER "clang++-bolt.inst") + set(C_COMPILER_PATH ${CMAKE_BINARY_DIR}/bin/${C_COMPILER}) + set(CXX_COMPILER_PATH ${CMAKE_BINARY_DIR}/bin/${CXX_COMPILER}) + + # Instrument clang with BOLT + add_custom_target(clang-instrumented + DEPENDS ${C_COMPILER_PATH} + ) + add_custom_command(OUTPUT ${C_COMPILER_PATH} + DEPENDS clang llvm-bolt + COMMAND llvm-bolt $ -o ${C_COMPILER_PATH} + -instrument --instrumentation-file-append-pid + --instrumentation-file=${CMAKE_CURRENT_BINARY_DIR}/prof.fdata + COMMENT "Instrumenting clang binary with BOLT" + VERBATIM + ) + + # Make a symlink from ${C_COMPILER} to ${CXX_COMPILER} + add_custom_target(clang++-instrumented + DEPENDS ${CXX_COMPILER_PATH} + ) + add_custom_command(OUTPUT ${CXX_COMPILER_PATH} + DEPENDS clang-instrumented + COMMAND ${CMAKE_COMMAND} -E create_symlink + ${C_COMPILER_PATH} + ${CXX_COMPILER_PATH} + COMMENT "Creating symlink from BOLT instrumented clang to clang++" + VERBATIM + ) + + # Configure and build Clang with instrumented Clang to collect the profile + set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt-instrumented-clang-stamps/) + set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt-instrumented-clang-bins/) + set(build_configuration "$") + include(ExternalProject) + ExternalProject_Add(bolt-instrumentation-profile + DEPENDS clang++-instrumented + PREFIX bolt-instrumentation-profile + SOURCE_DIR ${CMAKE_SOURCE_DIR} + STAMP_DIR ${STAMP_DIR} + BINARY_DIR ${BINARY_DIR} + EXCLUDE_FROM_ALL 1 + CMAKE_ARGS + # We shouldn't need to set this here, but INSTALL_DIR doesn't + # seem to work, so instead I'm passing this through + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + -DCMAKE_C_COMPILER=${C_COMPILER_PATH} + -DCMAKE_CXX_COMPILER=${CXX_COMPILER_PATH} + -DCMAKE_ASM_COMPILER=${C_COMPILER_PATH} + -DCMAKE_ASM_COMPILER_ID=Clang + -DCMAKE_BUILD_TYPE=Release + -DLLVM_ENABLE_PROJECTS=${CLANG_BOLT_INSTRUMENT_PROJECTS} + -DLLVM_TARGETS_TO_BUILD=${LLVM_TARGETS_TO_BUILD} + BUILD_COMMAND ${CMAKE_COMMAND} --build ${BINARY_DIR} + --config ${build_configuration} + --target ${CLANG_BOLT_INSTRUMENT_TARGETS} + INSTALL_COMMAND "" + STEP_TARGETS configure build + USES_TERMINAL_CONFIGURE 1 + USES_TERMINAL_BUILD 1 + USES_TERMINAL_INSTALL 1 + ) + + # Merge profiles into one using merge-fdata + add_custom_target(clang-bolt-profile + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata + ) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata + DEPENDS merge-fdata bolt-instrumentation-profile-build + COMMAND merge-fdata ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata.* + -o ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata + COMMENT "Preparing BOLT profile" + VERBATIM + ) + + # Optimize original (pre-bolt) Clang using the collected profile + add_custom_target(clang-bolt + DEPENDS ${CMAKE_BINARY_DIR}/bin/clang-bolt + ) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/clang-bolt + DEPENDS clang-bolt-profile + COMMAND llvm-bolt $ + -o ${CMAKE_BINARY_DIR}/bin/clang-bolt + -data ${CMAKE_CURRENT_BINARY_DIR}/prof.fdata + COMMENT "Optimizing Clang with BOLT" + VERBATIM + ) +endif() + if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) add_subdirectory(utils/ClangVisualizers) endif() diff --git a/clang/cmake/caches/BOLT.cmake b/clang/cmake/caches/BOLT.cmake new file mode 100644 --- /dev/null +++ b/clang/cmake/caches/BOLT.cmake @@ -0,0 +1,14 @@ +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(CLANG_BOLT_INSTRUMENT ON CACHE BOOL "") +set(CLANG_BOLT_INSTRUMENT_PROJECTS "lld" CACHE STRING "") +set(CLANG_BOLT_INSTRUMENT_TARGETS "lld" CACHE STRING "") +set(CMAKE_EXE_LINKER_FLAGS "-Wl,--emit-relocs,-znow" CACHE STRING "") + +set(LLVM_ENABLE_PROJECTS "bolt;clang" CACHE STRING "") +set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "") + +# Disable function splitting enabled by default in GCC8+ +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-reorder-blocks-and-partition") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-reorder-blocks-and-partition") +endif()