[BOLT] Enable standalone build (#97130)

Continue from #87196 as author did not have much time, I have taken over
working on this PR. We would like to have this so it'll be easier to
package for Nix.

Can be tested by copying cmake, bolt, third-party, and llvm directories
out into their own directory with this PR applied and then build bolt.

---------

Co-authored-by: pca006132 <john.lck40@gmail.com>
This commit is contained in:
Tristan Ross 2024-07-25 08:18:14 -07:00 committed by GitHub
parent 51d4980a13
commit abc2eae682
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 199 additions and 26 deletions

View File

@ -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")

View File

@ -58,7 +58,16 @@ protected:
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.

View File

@ -1,3 +1,5 @@
add_compile_definitions(CMAKE_INSTALL_FULL_LIBDIR="${CMAKE_INSTALL_FULL_LIBDIR}")
add_subdirectory(Core)
add_subdirectory(Passes)
add_subdirectory(Profile)

View File

@ -32,9 +32,9 @@ cl::opt<bool>
"(which is what --hot-text relies on)."),
cl::cat(BoltOptCategory));
static cl::opt<std::string> RuntimeHugifyLib(
"runtime-hugify-lib",
cl::desc("specify file name of the runtime hugify library"),
static cl::opt<std::string>
RuntimeHugifyLib("runtime-hugify-lib",
cl::desc("specify path of the runtime hugify library"),
cl::init("libbolt_rt_hugify.a"), cl::cat(BoltOptCategory));
} // namespace opts

View File

@ -26,7 +26,7 @@ namespace opts {
cl::opt<std::string> 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<bool> InstrumentationFileAppendPID;

View File

@ -26,7 +26,7 @@ using namespace bolt;
void RuntimeLibrary::anchor() {}
std::string RuntimeLibrary::getLibPath(StringRef ToolPath,
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);
@ -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<std::unique_ptr<MemoryBuffer>> MaybeBuf =

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
)

View File

@ -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
"<unknown>";
#endif

View File

@ -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()

View File

@ -92,10 +92,22 @@ link_fdata_cmd = os.path.join(config.test_source_root, "link_fdata.py")
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"),

View File

@ -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)