diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt index 74907ad118d12f..9f5875dd212847 100644 --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -1,6 +1,17 @@ +cmake_minimum_required(VERSION 3.20.0) + set(LLVM_SUBPROJECT_TITLE "BOLT") -include(ExternalProject) +if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS) + set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) +endif() +include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake + NO_POLICY_SCOPE) + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project(bolt) + set(BOLT_BUILT_STANDALONE TRUE) +endif() set(BOLT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(BOLT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -9,6 +20,42 @@ set(CMAKE_CXX_STANDARD 17) # Add path for custom modules. list(INSERT CMAKE_MODULE_PATH 0 "${BOLT_SOURCE_DIR}/cmake/modules") +include(GNUInstallDirs) + +# standalone build, copied from clang +if(BOLT_BUILT_STANDALONE) + set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") + set(CMAKE_CXX_STANDARD_REQUIRED YES) + set(CMAKE_CXX_EXTENSIONS NO) + + if(NOT MSVC_IDE) + set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} + CACHE BOOL "Enable assertions") + # Assertions should follow llvm-config's. + mark_as_advanced(LLVM_ENABLE_ASSERTIONS) + endif() + + find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") + list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") + + set(LLVM_MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../llvm" CACHE PATH "Path to LLVM source tree") + find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} + NO_DEFAULT_PATH) + + # They are used as destination of target generators. + set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) + set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) + + include(AddLLVM) + include(TableGen) + include_directories(${LLVM_INCLUDE_DIRS}) + link_directories("${LLVM_LIBRARY_DIR}") + + set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_INSTALL_BINDIR}" ) + set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}/${LLVM_LIBDIR_SUFFIX}" ) + set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}/${LLVM_LIBDIR_SUFFIX}") +endif() # standalone + # Determine default set of targets to build -- the intersection of # those BOLT supports and those LLVM is targeting. set(BOLT_TARGETS_TO_BUILD_all "AArch64;X86;RISCV") @@ -94,6 +141,8 @@ if (BOLT_ENABLE_RUNTIME) if(CMAKE_SYSROOT) list(APPEND extra_args -DCMAKE_SYSROOT=${CMAKE_SYSROOT}) endif() + + include(ExternalProject) ExternalProject_Add(bolt_rt SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime" STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-stamps @@ -104,6 +153,7 @@ if (BOLT_ENABLE_RUNTIME) -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} -DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX} -DLLVM_LIBRARY_DIR=${LLVM_LIBRARY_DIR} + -DBOLT_BUILT_STANDALONE=${BOLT_BUILT_STANDALONE} ${extra_args} INSTALL_COMMAND "" BUILD_ALWAYS True @@ -113,6 +163,8 @@ if (BOLT_ENABLE_RUNTIME) add_llvm_install_targets(install-bolt_rt DEPENDS bolt_rt bolt COMPONENT bolt) + set(LIBBOLT_RT_INSTR "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/lib/libbolt_rt_instr.a") + set(LIBBOLT_RT_HUGIFY "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/lib/libbolt_rt_hugify.a") endif() find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld") diff --git a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h index e392029156bcea..fc1db7369eb4a3 100644 --- a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h +++ b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h @@ -58,7 +58,16 @@ class RuntimeLibrary { uint64_t RuntimeFiniAddress{0}; uint64_t RuntimeStartAddress{0}; - /// Get the full path to a runtime library specified by \p LibFileName. + /// Get the full path to a runtime library specified by \p LibFileName and \p + /// ToolPath. + static std::string getLibPathByToolPath(StringRef ToolPath, + StringRef LibFileName); + + /// Get the full path to a runtime library by the install directory. + static std::string getLibPathByInstalled(StringRef LibFileName); + + /// Gets the full path to a runtime library based on whether it exists + /// in the install libdir or runtime libdir. static std::string getLibPath(StringRef ToolPath, StringRef LibFileName); /// Load a static runtime library specified by \p LibPath. diff --git a/bolt/lib/CMakeLists.txt b/bolt/lib/CMakeLists.txt index 22a6be44f6458c..d0f921a1a1e2c4 100644 --- a/bolt/lib/CMakeLists.txt +++ b/bolt/lib/CMakeLists.txt @@ -1,3 +1,5 @@ +add_compile_definitions(CMAKE_INSTALL_FULL_LIBDIR="${CMAKE_INSTALL_FULL_LIBDIR}") + add_subdirectory(Core) add_subdirectory(Passes) add_subdirectory(Profile) diff --git a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp index d114d70f2d3766..026f8d35c55c63 100644 --- a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp @@ -32,10 +32,10 @@ cl::opt "(which is what --hot-text relies on)."), cl::cat(BoltOptCategory)); -static cl::opt RuntimeHugifyLib( - "runtime-hugify-lib", - cl::desc("specify file name of the runtime hugify library"), - cl::init("libbolt_rt_hugify.a"), cl::cat(BoltOptCategory)); +static cl::opt + RuntimeHugifyLib("runtime-hugify-lib", + cl::desc("specify path of the runtime hugify library"), + cl::init("libbolt_rt_hugify.a"), cl::cat(BoltOptCategory)); } // namespace opts diff --git a/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp index cd1b975be7b90e..53a0c811b41d58 100644 --- a/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp @@ -26,7 +26,7 @@ namespace opts { cl::opt RuntimeInstrumentationLib( "runtime-instrumentation-lib", - cl::desc("specify file name of the runtime instrumentation library"), + cl::desc("specify path of the runtime instrumentation library"), cl::init("libbolt_rt_instr.a"), cl::cat(BoltOptCategory)); extern cl::opt InstrumentationFileAppendPID; diff --git a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp index 276b034d71f96a..336c6768a7f712 100644 --- a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp @@ -26,8 +26,8 @@ using namespace bolt; void RuntimeLibrary::anchor() {} -std::string RuntimeLibrary::getLibPath(StringRef ToolPath, - StringRef LibFileName) { +std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath, + StringRef LibFileName) { StringRef Dir = llvm::sys::path::parent_path(ToolPath); SmallString<128> LibPath = llvm::sys::path::parent_path(Dir); llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); @@ -38,13 +38,36 @@ std::string RuntimeLibrary::getLibPath(StringRef ToolPath, llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); } llvm::sys::path::append(LibPath, LibFileName); - if (!llvm::sys::fs::exists(LibPath)) { - errs() << "BOLT-ERROR: library not found: " << LibPath << "\n"; - exit(1); - } return std::string(LibPath); } +std::string RuntimeLibrary::getLibPathByInstalled(StringRef LibFileName) { + SmallString<128> LibPath(CMAKE_INSTALL_FULL_LIBDIR); + llvm::sys::path::append(LibPath, LibFileName); + return std::string(LibPath); +} + +std::string RuntimeLibrary::getLibPath(StringRef ToolPath, + StringRef LibFileName) { + if (llvm::sys::fs::exists(LibFileName)) { + return std::string(LibFileName); + } + + std::string ByTool = getLibPathByToolPath(ToolPath, LibFileName); + if (llvm::sys::fs::exists(ByTool)) { + return ByTool; + } + + std::string ByInstalled = getLibPathByInstalled(LibFileName); + if (llvm::sys::fs::exists(ByInstalled)) { + return ByInstalled; + } + + errs() << "BOLT-ERROR: library not found: " << ByTool << ", " << ByInstalled + << ", or " << LibFileName << "\n"; + exit(1); +} + void RuntimeLibrary::loadLibrary(StringRef LibPath, BOLTLinker &Linker, BOLTLinker::SectionsMapper MapSections) { ErrorOr> MaybeBuf = diff --git a/bolt/lib/Target/AArch64/CMakeLists.txt b/bolt/lib/Target/AArch64/CMakeLists.txt index be03e247aa96b1..7e2d33e09b5a04 100644 --- a/bolt/lib/Target/AArch64/CMakeLists.txt +++ b/bolt/lib/Target/AArch64/CMakeLists.txt @@ -4,6 +4,18 @@ set(LLVM_LINK_COMPONENTS AArch64Desc ) +if(BOLT_BUILT_STANDALONE) + set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/AArch64/AArch64.td) + list(APPEND LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_SRC_DIR}/lib/Target/AArch64) + tablegen(LLVM AArch64GenInstrInfo.inc -gen-instr-info) + tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info) + tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables) + tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget) + + add_public_tablegen_target(AArch64CommonTableGen) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() + add_llvm_library(LLVMBOLTTargetAArch64 AArch64MCPlusBuilder.cpp diff --git a/bolt/lib/Target/RISCV/CMakeLists.txt b/bolt/lib/Target/RISCV/CMakeLists.txt index 7f955760632008..5d19d38717de4e 100644 --- a/bolt/lib/Target/RISCV/CMakeLists.txt +++ b/bolt/lib/Target/RISCV/CMakeLists.txt @@ -4,6 +4,19 @@ set(LLVM_LINK_COMPONENTS RISCVDesc ) +if(BOLT_BUILT_STANDALONE) + # tablegen, copied from llvm/lib/Target/RISCV/CMakeLists.txt + set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV/RISCV.td) + list(APPEND LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_SRC_DIR}/lib/Target/RISCV) + tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) + tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM RISCVGenSearchableTables.inc -gen-searchable-tables) + tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget) + + add_public_tablegen_target(RISCVCommonTableGen) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() + add_llvm_library(LLVMBOLTTargetRISCV RISCVMCPlusBuilder.cpp diff --git a/bolt/lib/Target/X86/CMakeLists.txt b/bolt/lib/Target/X86/CMakeLists.txt index 2b769bc7e7f5ce..b274716e89a4c7 100644 --- a/bolt/lib/Target/X86/CMakeLists.txt +++ b/bolt/lib/Target/X86/CMakeLists.txt @@ -5,6 +5,18 @@ set(LLVM_LINK_COMPONENTS X86Desc ) +if(BOLT_BUILT_STANDALONE) + set(LLVM_TARGET_DEFINITIONS ${LLVM_MAIN_SRC_DIR}/lib/Target/X86/X86.td) + list(APPEND LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_SRC_DIR}/lib/Target/X86) + tablegen(LLVM X86GenInstrInfo.inc -gen-instr-info -instr-info-expand-mi-operand-info=0) + tablegen(LLVM X86GenMnemonicTables.inc -gen-x86-mnemonic-tables -asmwriternum=1) + tablegen(LLVM X86GenRegisterInfo.inc -gen-register-info) + tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) + + add_public_tablegen_target(X86CommonTableGen) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() + add_llvm_library(LLVMBOLTTargetX86 X86MCPlusBuilder.cpp X86MCSymbolizer.cpp diff --git a/bolt/lib/Utils/CMakeLists.txt b/bolt/lib/Utils/CMakeLists.txt index d1403314274bd6..c452c1fac3772d 100644 --- a/bolt/lib/Utils/CMakeLists.txt +++ b/bolt/lib/Utils/CMakeLists.txt @@ -1,15 +1,39 @@ +find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc) +find_first_existing_vc_file("${BOLT_SOURCE_DIR}" bolt_vc) + +# The VC revision include that we want to generate. +set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc") + +set(generate_vcs_version_script "${LLVM_CMAKE_DIR}/GenerateVersionFromVCS.cmake") + +# Create custom target to generate the VC revision include. +add_custom_command(OUTPUT "${version_inc}" + DEPENDS "${llvm_vc}" "${bolt_vc}" "${generate_vcs_version_script}" + COMMAND ${CMAKE_COMMAND} "-DNAMES=BOLT" + "-DHEADER_FILE=${version_inc}" + "-DBOLT_SOURCE_DIR=${BOLT_SOURCE_DIR}" + "-DLLVM_VC_REPOSITORY=${llvm_vc_repository}" + "-DLLVM_VC_REVISION=${llvm_vc_revision}" + "-DLLVM_FORCE_VC_REVISION=${LLVM_FORCE_VC_REVISION}" + "-DLLVM_FORCE_VC_REPOSITORY=${LLVM_FORCE_VC_REPOSITORY}" + -P "${generate_vcs_version_script}") + +# Mark the generated header as being generated. +set_source_files_properties("${version_inc}" + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + add_llvm_library(LLVMBOLTUtils CommandLineOpts.cpp Utils.cpp - + ${version_inc} DISABLE_LLVM_LINK_LLVM_DYLIB LINK_LIBS ${LLVM_PTHREAD_LIB} - DEPENDS - llvm_vcsrevision_h - LINK_COMPONENTS Support ) diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp index 47375abb2ad3b4..435a8fa9cafcae 100644 --- a/bolt/lib/Utils/CommandLineOpts.cpp +++ b/bolt/lib/Utils/CommandLineOpts.cpp @@ -11,15 +11,15 @@ //===----------------------------------------------------------------------===// #include "bolt/Utils/CommandLineOpts.h" -#include "llvm/Support/VCSRevision.h" +#include "VCSVersion.inc" using namespace llvm; namespace llvm { namespace bolt { const char *BoltRevision = -#ifdef LLVM_REVISION - LLVM_REVISION; +#ifdef BOLT_REVISION + BOLT_REVISION; #else ""; #endif diff --git a/bolt/runtime/CMakeLists.txt b/bolt/runtime/CMakeLists.txt index 6a65f80fb9079f..948825ddc27eb2 100644 --- a/bolt/runtime/CMakeLists.txt +++ b/bolt/runtime/CMakeLists.txt @@ -16,12 +16,19 @@ add_library(bolt_rt_instr STATIC instr.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.h ) -set_target_properties(bolt_rt_instr PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") +set_target_properties(bolt_rt_instr PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") add_library(bolt_rt_hugify STATIC hugify.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.h ) -set_target_properties(bolt_rt_hugify PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_DIR}") +set_target_properties(bolt_rt_hugify PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") + +if(NOT BOLT_BUILT_STANDALONE) + add_custom_command(TARGET bolt_rt_instr POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_instr.a" "${LLVM_LIBRARY_DIR}") + add_custom_command(TARGET bolt_rt_hugify POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_hugify.a" "${LLVM_LIBRARY_DIR}") +endif() set(BOLT_RT_FLAGS -ffreestanding @@ -46,8 +53,8 @@ target_include_directories(bolt_rt_instr PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_compile_options(bolt_rt_hugify PRIVATE ${BOLT_RT_FLAGS}) target_include_directories(bolt_rt_hugify PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -install(TARGETS bolt_rt_instr DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") -install(TARGETS bolt_rt_hugify DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") +install(TARGETS bolt_rt_instr DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") +install(TARGETS bolt_rt_hugify DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_library(bolt_rt_instr_osx STATIC @@ -59,5 +66,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_SYSTEM_NAME STREQUAL "Da target_compile_options(bolt_rt_instr_osx PRIVATE -target x86_64-apple-darwin19.6.0 ${BOLT_RT_FLAGS}) - install(TARGETS bolt_rt_instr_osx DESTINATION "lib${LLVM_LIBDIR_SUFFIX}") + install(TARGETS bolt_rt_instr_osx DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") + + if(NOT BOLT_BUILT_STANDALONE) + add_custom_command(TARGET bolt_rt_instr_osx POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/lib/libbolt_rt_instr_osx.a" "${LLVM_LIBRARY_DIR}") + endif() endif() diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py index 3a6da210e01f08..da3ae34ba3bddb 100644 --- a/bolt/test/lit.cfg.py +++ b/bolt/test/lit.cfg.py @@ -92,10 +92,22 @@ tool_dirs = [config.llvm_tools_dir, config.test_source_root] +llvm_bolt_args = [] + +if config.libbolt_rt_instr: + llvm_bolt_args.append(f"--runtime-instrumentation-lib={config.libbolt_rt_instr}") + +if config.libbolt_rt_hugify: + llvm_bolt_args.append(f"--runtime-hugify-lib={config.libbolt_rt_hugify}") + tools = [ ToolSubst("llc", unresolved="fatal"), ToolSubst("llvm-dwarfdump", unresolved="fatal"), - ToolSubst("llvm-bolt", unresolved="fatal"), + ToolSubst( + "llvm-bolt", + unresolved="fatal", + extra_args=llvm_bolt_args, + ), ToolSubst("llvm-boltdiff", unresolved="fatal"), ToolSubst("llvm-bolt-heatmap", unresolved="fatal"), ToolSubst("llvm-bat-dump", unresolved="fatal"), diff --git a/bolt/test/lit.site.cfg.py.in b/bolt/test/lit.site.cfg.py.in index 46cb326dfbae18..457908fc7c4462 100644 --- a/bolt/test/lit.site.cfg.py.in +++ b/bolt/test/lit.site.cfg.py.in @@ -19,6 +19,8 @@ config.bolt_clang = "@BOLT_CLANG_EXE@" config.bolt_lld = "@BOLT_LLD_EXE@" config.targets_to_build = "@BOLT_TARGETS_TO_BUILD@" config.gnu_ld = "@GNU_LD_EXECUTABLE@" +config.libbolt_rt_instr = "@LIBBOLT_RT_INSTR@" +config.libbolt_rt_hugify = "@LIBBOLT_RT_HUGIFY@" import lit.llvm lit.llvm.initialize(lit_config, config)