Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -492,29 +492,68 @@ option(LLVM_USE_SPLIT_DWARF "Use -gsplit-dwarf when compiling llvm." OFF) -option(LLVM_POLLY_LINK_INTO_TOOLS "Statically link Polly into tools (if available)" ON) -option(LLVM_POLLY_BUILD "Build LLVM with Polly" ON) - -if (EXISTS ${LLVM_MAIN_SRC_DIR}/tools/polly/CMakeLists.txt) - set(POLLY_IN_TREE TRUE) -elseif(LLVM_EXTERNAL_POLLY_SOURCE_DIR) - set(POLLY_IN_TREE TRUE) -else() - set(POLLY_IN_TREE FALSE) +set(LLVM_ALL_EXTENSIONS "Polly") +set(LLVM_EXTENSIONS "" CACHE STRING + "Semicolon-separated list of extensions to link into tools, or \"all\"") + +# Expand to official extensions +if(LLVM_EXTENSIONS STREQUAL "all") + set(LLVM_EXTENSIONS "") + foreach(llvm_extension ${LLVM_ALL_EXTENSIONS}) + string(TOLOWER ${llvm_extension} llvm_extension_dirname) + if(LLVM_ENABLE_PROJECTS_USED) + set(llvm_extension_dir "${CMAKE_CURRENT_SOURCE_DIR}/../${llvm_extension_dirname}") + else() + set(llvm_extension_dir "${CMAKE_CURRENT_SOURCE_DIR}/tools/${llvm_extension_dirname}") + endif() + if (EXISTS ${llvm_extension_dir}/CMakeLists.txt) + list(APPEND LLVM_EXTENSIONS ${llvm_extension_lib}) + endif() + endforeach() endif() -if (LLVM_POLLY_BUILD AND POLLY_IN_TREE) - set(WITH_POLLY ON) -else() - set(WITH_POLLY OFF) -endif() +# load extra configuration variables from extensions +foreach(llvm_extension ${LLVM_EXTENSIONS}) + string(TOLOWER ${llvm_extension} llvm_extension_dirname) + if(LLVM_ENABLE_PROJECTS_USED) + if(NOT ${llvm_extension_dirname} IN_LIST LLVM_ENABLE_PROJECTS) + message(FATAL_ERROR "LLVM_EXTENSIONS requests ${llvm_extension_dirname} but this project is not listed in LLVM_ENABLE_PROJECTS") + else() + set(llvm_extension_dir "${CMAKE_CURRENT_SOURCE_DIR}/../${llvm_extension_dirname}") + endif() + else() + set(llvm_extension_dir "${CMAKE_CURRENT_SOURCE_DIR}/tools/${llvm_extension_dirname}") + endif() + if(NOT EXISTS "${llvm_extension_dir}" OR NOT IS_DIRECTORY "${llvm_extension_dir}") + message(FATAL_ERROR "LLVM_EXTENSIONS requests ${llvm_extension} but directory not found: ${llvm_extension_dir}") + endif() + include(${llvm_extension_dir}/cmake/extension.cmake OPTIONAL) +endforeach() -if (LLVM_POLLY_LINK_INTO_TOOLS AND WITH_POLLY) - set(LINK_POLLY_INTO_TOOLS ON) -else() - set(LINK_POLLY_INTO_TOOLS OFF) +# generate xfor file for extension handling +file(WRITE "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp" "//extension handlers\n") +foreach(llvm_extension ${LLVM_EXTENSIONS}) + string(TOLOWER ${llvm_extension} llvm_extension_namespace) + string(TOUPPER ${llvm_extension} llvm_extension_upper) + string(SUBSTRING ${llvm_extension_upper} 0 1 llvm_extension_upper_first) + string(SUBSTRING ${llvm_extension_namespace} 1 -1 llvm_extension_lower_tail) + string(CONCAT llvm_extension_project ${llvm_extension_upper_first} ${llvm_extension_lower_tail}) + file(APPEND "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp" "HANDLE_EXTENSION(${llvm_extension_namespace}, ${llvm_extension_project})\n") +endforeach() +file(APPEND "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp" "#undef HANDLE_EXTENSION\n") + +# only replace if tehre's an actual change +if(EXISTS "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def") + file(SHA256 "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def" llvm_extension_def_orig_checksum) + file(SHA256 "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp" llvm_extension_def_new_checksum) + if(NOT llvm_extension_def_orig_checksum EQUAL llvm_extension_def_new_checksum) + file(RENAME "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp" "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def") + else() + file(REMOVE "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp") + endif() endif() + # Define an option controlling whether we should build for 32-bit on 64-bit # platforms, where supported. if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 ) Index: docs/CMake.rst =================================================================== --- docs/CMake.rst +++ docs/CMake.rst @@ -367,6 +367,11 @@ This feature allows to have one build for only LLVM and another for clang+llvm using the same source checkout. +**LLVM_EXTENSIONS**:STRING + Semicolon-separated list of projects to consider as extension. An extension ``Ext`` + is an LLVM project that registers new passes through ``initialize##Ext##Passes`` and + ``Register##Ext##Passes``. + **LLVM_EXTERNAL_PROJECTS**:STRING Semicolon-separated list of additional external projects to build as part of llvm. For each project LLVM_EXTERNAL__SOURCE_DIR have to be specified Index: include/llvm/Config/llvm-config.h.cmake =================================================================== --- include/llvm/Config/llvm-config.h.cmake +++ include/llvm/Config/llvm-config.h.cmake @@ -17,9 +17,6 @@ /* Define if LLVM_ENABLE_DUMP is enabled */ #cmakedefine LLVM_ENABLE_DUMP -/* Define if we link Polly to the tools */ -#cmakedefine LINK_POLLY_INTO_TOOLS - /* Target triple LLVM will generate code for by default */ #cmakedefine LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}" Index: tools/CMakeLists.txt =================================================================== --- tools/CMakeLists.txt +++ tools/CMakeLists.txt @@ -9,13 +9,13 @@ # traversing each directory. create_llvm_tool_options() -# Build polly before the tools: the tools link against polly when -# LINK_POLLY_INTO_TOOLS is set. -if(WITH_POLLY) - add_llvm_external_project(polly) -else() - set(LLVM_TOOL_POLLY_BUILD Off) -endif() +# Add extensions before the tools: the tools link against extension libs +foreach(llvm_extension ${LLVM_EXTENSIONS}) + string(TOLOWER ${llvm_extension} llvm_project_name) + if(NOT ${llvm_project_name} IN_LIST LLVM_EXTERNAL_PROJECTS) + add_llvm_external_project(${llvm_project_name}) + endif() +endforeach() if(NOT LLVM_BUILD_LLVM_DYLIB AND NOT LLVM_BUILD_LLVM_C_DYLIB) set(LLVM_TOOL_LLVM_SHLIB_BUILD Off) Index: tools/bugpoint/CMakeLists.txt =================================================================== --- tools/bugpoint/CMakeLists.txt +++ tools/bugpoint/CMakeLists.txt @@ -37,8 +37,6 @@ ) export_executable_symbols(bugpoint) -if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) - target_link_libraries(bugpoint PRIVATE Polly) - # Ensure LLVMTarget can resolve dependences in Polly. - target_link_libraries(bugpoint PRIVATE LLVMTarget) -endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) +if(LLVM_EXTENSION_LIBS) + target_link_libraries(bugpoint PRIVATE ${LLVM_EXTENSION_LIBS} ${LLVM_EXTENSION_BUGPOINT_LIBS}) +endif() Index: tools/bugpoint/bugpoint.cpp =================================================================== --- tools/bugpoint/bugpoint.cpp +++ tools/bugpoint/bugpoint.cpp @@ -109,11 +109,8 @@ }; } -#ifdef LINK_POLLY_INTO_TOOLS -namespace polly { -void initializePollyPasses(llvm::PassRegistry &Registry); -} -#endif +#define HANDLE_EXTENSION(Ns, Ext) namespace Ns { void initialize##Ext##Passes(llvm::PassRegistry &Registry); } +#include "llvm/Support/Extension.def" int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT @@ -134,9 +131,8 @@ initializeInstrumentation(Registry); initializeTarget(Registry); -#ifdef LINK_POLLY_INTO_TOOLS - polly::initializePollyPasses(Registry); -#endif +#define HANDLE_EXTENSION(Ns, Ext) Ns::initialize##Ext##Passes(Registry); +#include "llvm/Support/Extension.def" if (std::getenv("bar") == (char*) -1) { InitializeAllTargets(); Index: tools/clang/tools/driver/CMakeLists.txt =================================================================== --- tools/clang/tools/driver/CMakeLists.txt +++ tools/clang/tools/driver/CMakeLists.txt @@ -123,6 +123,6 @@ endif() endif() -if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) - target_link_libraries(clang PRIVATE Polly) -endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) +if(LLVM_EXTENSION_LIBS) + target_link_libraries(clang PRIVATE ${LLVM_EXTENSION_LIBS} ${LLVM_EXTENSION_CLANG_LIBS}) +endif() Index: tools/clang/tools/driver/cc1_main.cpp =================================================================== --- tools/clang/tools/driver/cc1_main.cpp +++ tools/clang/tools/driver/cc1_main.cpp @@ -69,11 +69,8 @@ exit(GenCrashDiag ? 70 : 1); } -#ifdef LINK_POLLY_INTO_TOOLS -namespace polly { -void initializePollyPasses(llvm::PassRegistry &Registry); -} -#endif +#define HANDLE_EXTENSION(Ns, Ext) namespace Ns { void initialize##Ext##Passes(llvm::PassRegistry &Registry); } +#include "llvm/Support/Extension.def" #ifdef CLANG_HAVE_RLIMITS #if defined(__linux__) && defined(__PIE__) @@ -183,10 +180,8 @@ llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); -#ifdef LINK_POLLY_INTO_TOOLS - llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); - polly::initializePollyPasses(Registry); -#endif +#define HANDLE_EXTENSION(Ns, Ext) { llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); Ns::initialize##Ext##Passes(Registry); } +#include "llvm/Support/Extension.def" // Buffer diagnostics from argument parsing so that we can output them using a // well formed diagnostic object. Index: tools/opt/CMakeLists.txt =================================================================== --- tools/opt/CMakeLists.txt +++ tools/opt/CMakeLists.txt @@ -38,6 +38,6 @@ ) export_executable_symbols(opt) -if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) - target_link_libraries(opt PRIVATE Polly) -endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) +if(LLVM_EXTENSION_LIBS) + target_link_libraries(opt PRIVATE ${LLVM_EXTENSION_LIBS} ${LLVM_EXTENSION_OPT_LIBS}) +endif() Index: tools/opt/NewPMDriver.cpp =================================================================== --- tools/opt/NewPMDriver.cpp +++ tools/opt/NewPMDriver.cpp @@ -202,11 +202,8 @@ }); } -#ifdef LINK_POLLY_INTO_TOOLS -namespace polly { -void RegisterPollyPasses(PassBuilder &); -} -#endif +#define HANDLE_EXTENSION(Ns, Ext) namespace Ns { void Register##Ext##Passes(PassBuilder &); } +#include "llvm/Support/Extension.def" bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut, @@ -290,9 +287,8 @@ return false; }); -#ifdef LINK_POLLY_INTO_TOOLS - polly::RegisterPollyPasses(PB); -#endif +#define HANDLE_EXTENSION(Ns, Ext) Ns::Register##Ext##Passes(PB); +#include "llvm/Support/Extension.def" // Specially handle the alias analysis manager so that we can register // a custom pipeline of AA passes with it. Index: tools/opt/opt.cpp =================================================================== --- tools/opt/opt.cpp +++ tools/opt/opt.cpp @@ -470,11 +470,8 @@ getCodeModel(), GetCodeGenOptLevel()); } -#ifdef LINK_POLLY_INTO_TOOLS -namespace polly { -void initializePollyPasses(llvm::PassRegistry &Registry); -} -#endif +#define HANDLE_EXTENSION(Ns, Ext) namespace Ns { void initialize##Ext##Passes(llvm::PassRegistry &Registry); } +#include "llvm/Support/Extension.def" //===----------------------------------------------------------------------===// // main for opt @@ -529,9 +526,8 @@ initializeWasmEHPreparePass(Registry); initializeWriteBitcodePassPass(Registry); -#ifdef LINK_POLLY_INTO_TOOLS - polly::initializePollyPasses(Registry); -#endif +#define HANDLE_EXTENSION(Ns, Ext) Ns::initialize##Ext##Passes(Registry); +#include "llvm/Support/Extension.def" cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); Index: tools/polly/cmake/extension.cmake =================================================================== --- tools/polly/cmake/extension.cmake +++ tools/polly/cmake/extension.cmake @@ -0,0 +1,2 @@ +# register per-tool extra dependencies here +list(APPEND LLVM_EXTENSION_BUGPOINT_LIBS LLVMTarget) Index: utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn =================================================================== --- utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn +++ utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn @@ -321,7 +321,6 @@ output = "$target_gen_dir/llvm-config.h" values = [ "LLVM_ENABLE_DUMP=", - "LINK_POLLY_INTO_TOOLS=", "LLVM_DEFAULT_TARGET_TRIPLE=$llvm_target_triple", "LLVM_HAS_ATOMICS=1", "LLVM_HOST_TRIPLE=$llvm_current_triple",