diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt index 9f5875dd21284..6d918fc624ba5 100644 --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -84,8 +84,7 @@ set(BOLT_ENABLE_RUNTIME_default OFF) if ((CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") AND (CMAKE_SYSTEM_NAME STREQUAL "Linux" - OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") - AND (NOT CMAKE_CROSSCOMPILING)) + OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")) set(BOLT_ENABLE_RUNTIME_default ON) endif() option(BOLT_ENABLE_RUNTIME "Enable BOLT runtime" ${BOLT_ENABLE_RUNTIME_default}) @@ -135,36 +134,110 @@ if (LLVM_INCLUDE_TESTS) endif() endif() -if (BOLT_ENABLE_RUNTIME) - message(STATUS "Building BOLT runtime libraries for X86") - set(extra_args "") - if(CMAKE_SYSROOT) - list(APPEND extra_args -DCMAKE_SYSROOT=${CMAKE_SYSROOT}) +function(bolt_rt_target_supported target supported) + + if(${target} STREQUAL ${HOST_NAME}) + set(${supported} TRUE PARENT_SCOPE) + return() + elseif(${target} STREQUAL "X86") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --target=x86_64-linux-gnu") + elseif(${target} STREQUAL "AArch64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --target=aarch64-linux-gnu") + elseif(${target} STREQUAL "RISCV") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --target=riscv64-linux-gnu") + endif() + + try_compile(CROSS_COMP + ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/test/test.cpp + CMAKE_FLAGS "" + TRY_COMP_OUTPUT) + + if(CROSS_COMP) + message(STATUS "cross compilation test for ${target} was successful") + set(${supported} TRUE PARENT_SCOPE) + else() + message(STATUS "cross compilation test for ${target} was NOT successful") + set(${supported} FALSE PARENT_SCOPE) + endif() + +endfunction() + +if(BOLT_ENABLE_RUNTIME) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set(HOST_NAME "X86") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") + set(HOST_NAME "AArch64") + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set(HOST_NAME "RISCV") endif() - include(ExternalProject) - ExternalProject_Add(bolt_rt - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime" - STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-stamps - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins - CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_BUILD_TYPE=Release - -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 + # Further filter BOLT runtime targets: check if the runtime can be compiled + set(BOLT_RT_TARGETS_TO_BUILD) + if(CMAKE_C_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*") + foreach(tgt ${BOLT_TARGETS_TO_BUILD}) + bolt_rt_target_supported(${tgt} supported) + if(${supported}) + list(APPEND BOLT_RT_TARGETS_TO_BUILD ${tgt}) + endif() + endforeach() + else() + message(WARNING "BOLT runtime libraries require Clang") + endif() +endif() + +if(BOLT_ENABLE_RUNTIME) + + foreach(tgt ${BOLT_RT_TARGETS_TO_BUILD}) + message(STATUS "Building BOLT runtime libraries for ${tgt}") + set(extra_args "") + if(CMAKE_SYSROOT) + list(APPEND extra_args -DCMAKE_SYSROOT=${CMAKE_SYSROOT}) + endif() + + # set up paths: target-specific libs will be generated under lib/${tgt}/ + set(BOLT_RT_LIBRARY_DIR "${LLVM_LIBRARY_DIR}") + set(SUBDIR "${tgt}") + cmake_path(APPEND BOLT_RT_LIBRARY_DIR ${BOLT_RT_LIBRARY_DIR} ${SUBDIR}) + file(MAKE_DIRECTORY ${BOLT_RT_LIBRARY_DIR}) + + if(${tgt} STREQUAL ${HOST_NAME}) + set(BOLT_RT_FLAGS) + elseif(${tgt} STREQUAL "AArch64") + set(BOLT_RT_FLAGS "--target=aarch64-linux-gnu") + elseif(${tgt} STREQUAL "X86") + set(BOLT_RT_FLAGS "--target=x86_64-linux-gnu") + elseif(${tgt} STREQUAL "RISCV") + set(BOLT_RT_FLAGS "--target=riscv64-linux-gnu") + endif() + + include(ExternalProject) + ExternalProject_Add(bolt_rt_${tgt} + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/runtime" + STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-${tgt}-stamps + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-${tgt}-bins + CMAKE_ARGS + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_BUILD_TYPE=Release + -DBOLT_RT_FLAGS=${BOLT_RT_FLAGS} + -DBOLT_RT_TARGET=${tgt} + -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} + -DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX} + -DLLVM_LIBRARY_DIR=${BOLT_RT_LIBRARY_DIR} + -DBOLT_BUILT_STANDALONE=${BOLT_BUILT_STANDALONE} + ${extra_args} + INSTALL_COMMAND "" + BUILD_ALWAYS True ) - install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-bins/cmake_install.cmake \)" - COMPONENT bolt) - 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") + install(CODE "execute_process\(COMMAND \${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=\${CMAKE_INSTALL_PREFIX} -P ${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-${tgt}-bins/cmake_install.cmake \)" + COMPONENT bolt) + add_llvm_install_targets(install-bolt_rt_${tgt} + DEPENDS bolt_rt_${tgt} bolt + COMPONENT bolt) + set(LIBBOLT_RT_INSTR "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-${tgt}-bins/lib/libbolt_rt_instr.a") + set(LIBBOLT_RT_HUGIFY "${CMAKE_CURRENT_BINARY_DIR}/bolt_rt-${tgt}-bins/lib/libbolt_rt_hugify.a") + endforeach() endif() find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld") diff --git a/bolt/cmake/test/test.cpp b/bolt/cmake/test/test.cpp new file mode 100644 index 0000000000000..4e43f4be13959 --- /dev/null +++ b/bolt/cmake/test/test.cpp @@ -0,0 +1,3 @@ +#include + +int main() { return 0; } diff --git a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h index fc1db7369eb4a..e757bb4b848b9 100644 --- a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h +++ b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h @@ -61,14 +61,19 @@ class RuntimeLibrary { /// Get the full path to a runtime library specified by \p LibFileName and \p /// ToolPath. static std::string getLibPathByToolPath(StringRef ToolPath, + StringRef ToolSubPath, StringRef LibFileName); + /// Create architecture-specific ToolSubPath to be used in the full path + static std::string createToolSubPath(StringRef ArchName); + /// Get the full path to a runtime library by the install directory. - static std::string getLibPathByInstalled(StringRef LibFileName); + static std::string getLibPathByInstalled(StringRef ToolSubPath, 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); + static std::string getLibPath(StringRef ToolPath, StringRef ToolSubPath, + StringRef LibFileName); /// Load a static runtime library specified by \p LibPath. static void loadLibrary(StringRef LibPath, BOLTLinker &Linker, diff --git a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp index 026f8d35c55c6..fd8172fb2932f 100644 --- a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp @@ -63,7 +63,14 @@ void HugifyRuntimeLibrary::link(BinaryContext &BC, StringRef ToolPath, BOLTLinker &Linker, BOLTLinker::SectionsMapper MapSections) { - std::string LibPath = getLibPath(ToolPath, opts::RuntimeHugifyLib); + // If the default filename is selected, add architecture-specific Target + // subdirectory to it. + std::string ToolSubPath = ""; + if (opts::RuntimeHugifyLib == "libbolt_rt_hugify.a") { + ToolSubPath = createToolSubPath(BC.TheTriple->getArchName().str().c_str()); + } + std::string LibPath = + getLibPath(ToolPath, ToolSubPath, opts::RuntimeHugifyLib); loadLibrary(LibPath, Linker, MapSections); assert(!RuntimeStartAddress && diff --git a/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp index 53a0c811b41d5..a16529e68376d 100644 --- a/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/InstrumentationRuntimeLibrary.cpp @@ -197,7 +197,15 @@ void InstrumentationRuntimeLibrary::emitBinary(BinaryContext &BC, void InstrumentationRuntimeLibrary::link( BinaryContext &BC, StringRef ToolPath, BOLTLinker &Linker, BOLTLinker::SectionsMapper MapSections) { - std::string LibPath = getLibPath(ToolPath, opts::RuntimeInstrumentationLib); + + // If the default filename is selected, add architecture-specific Target + // subdirectory to it. + std::string ToolSubPath = ""; + if (opts::RuntimeInstrumentationLib == "libbolt_rt_instr.a") { + ToolSubPath = createToolSubPath(BC.TheTriple->getArchName().str().c_str()); + } + std::string LibPath = + getLibPath(ToolPath, ToolSubPath, opts::RuntimeInstrumentationLib); loadLibrary(LibPath, Linker, MapSections); if (BC.isMachO()) diff --git a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp index 336c6768a7f71..adae849f369ab 100644 --- a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp @@ -27,6 +27,7 @@ using namespace bolt; void RuntimeLibrary::anchor() {} std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath, + StringRef ToolSubPath, StringRef LibFileName) { StringRef Dir = llvm::sys::path::parent_path(ToolPath); SmallString<128> LibPath = llvm::sys::path::parent_path(Dir); @@ -37,28 +38,45 @@ std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath, LibPath = llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); } + llvm::sys::path::append(LibPath, ToolSubPath); llvm::sys::path::append(LibPath, LibFileName); return std::string(LibPath); } -std::string RuntimeLibrary::getLibPathByInstalled(StringRef LibFileName) { +std::string RuntimeLibrary::createToolSubPath(StringRef ArchName) { + std::string ToolSubPath = ""; + if (ArchName == "x86_64") + ToolSubPath = "X86"; + else if (ArchName == "aarch64") + ToolSubPath = "AArch64"; + else if (ArchName == "riscv64") + ToolSubPath = "RISCV"; + else + llvm_unreachable("Unsupported architecture"); + + return ToolSubPath; +} + +std::string RuntimeLibrary::getLibPathByInstalled(StringRef ToolSubPath, StringRef LibFileName) { SmallString<128> LibPath(CMAKE_INSTALL_FULL_LIBDIR); + llvm::sys::path::append(LibPath, ToolSubPath); llvm::sys::path::append(LibPath, LibFileName); return std::string(LibPath); } std::string RuntimeLibrary::getLibPath(StringRef ToolPath, + StringRef ToolSubPath, StringRef LibFileName) { if (llvm::sys::fs::exists(LibFileName)) { return std::string(LibFileName); } - std::string ByTool = getLibPathByToolPath(ToolPath, LibFileName); + std::string ByTool = getLibPathByToolPath(ToolPath, ToolSubPath, LibFileName); if (llvm::sys::fs::exists(ByTool)) { return ByTool; } - std::string ByInstalled = getLibPathByInstalled(LibFileName); + std::string ByInstalled = getLibPathByInstalled(ToolSubPath, LibFileName); if (llvm::sys::fs::exists(ByInstalled)) { return ByInstalled; } diff --git a/bolt/runtime/CMakeLists.txt b/bolt/runtime/CMakeLists.txt index 40f4fbc9f30d5..da58bc4ea4103 100644 --- a/bolt/runtime/CMakeLists.txt +++ b/bolt/runtime/CMakeLists.txt @@ -29,18 +29,18 @@ if(NOT BOLT_BUILT_STANDALONE) 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 +# In case of compiling with clang, the '--target' option is passed in BOLT_RT_FLAGS. +set(BOLT_RT_FLAGS ${BOLT_RT_FLAGS} -ffreestanding -fno-exceptions -fno-rtti -fno-stack-protector -fPIC -mgeneral-regs-only) -if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") +if(${BOLT_RT_TARGET} STREQUAL "X86") set(BOLT_RT_FLAGS ${BOLT_RT_FLAGS} "-mno-sse") endif() -if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") +if(${BOLT_RT_TARGET} STREQUAL "AArch64") check_cxx_compiler_flag("-mno-outline-atomics" CXX_SUPPORTS_OUTLINE_ATOMICS) if (CXX_SUPPORTS_OUTLINE_ATOMICS) set(BOLT_RT_FLAGS ${BOLT_RT_FLAGS} "-mno-outline-atomics") @@ -53,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 "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") -install(TARGETS bolt_rt_hugify DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") +install(TARGETS bolt_rt_instr DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/${BOLT_RT_TARGET}") +install(TARGETS bolt_rt_hugify DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/${BOLT_RT_TARGET}") if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" AND CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_library(bolt_rt_instr_osx STATIC diff --git a/bolt/tools/driver/CMakeLists.txt b/bolt/tools/driver/CMakeLists.txt index 9bf9ff85edc7b..a06fa90b268fa 100644 --- a/bolt/tools/driver/CMakeLists.txt +++ b/bolt/tools/driver/CMakeLists.txt @@ -6,7 +6,9 @@ set(LLVM_LINK_COMPONENTS ) if (BOLT_ENABLE_RUNTIME) - set(BOLT_DRIVER_DEPS "bolt_rt") + foreach(tgt ${BOLT_RT_TARGETS_TO_BUILD}) + set(BOLT_DRIVER_DEPS ${BOLT_DRIVER_DEPS} "bolt_rt_${tgt}") + endforeach() else() set(BOLT_DRIVER_DEPS "") endif()