Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -144,6 +144,7 @@ std::vector undefined; std::vector dynamicList; std::vector buildIdVector; + std::vector passPlugins; llvm::MapVector, uint64_t> callGraphProfile; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -1284,6 +1284,8 @@ error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() + "'"); + config->passPlugins = args::getStrings(args, OPT_load_pass_plugins); + // Parse -mllvm options. for (auto *arg : args.filtered(OPT_mllvm)) parseClangOption(arg->getValue(), arg->getSpelling()); Index: lld/ELF/LTO.cpp =================================================================== --- lld/ELF/LTO.cpp +++ lld/ELF/LTO.cpp @@ -144,6 +144,8 @@ c.SampleProfile = std::string(config->ltoSampleProfile); c.UseNewPM = config->ltoNewPassManager; + for (const llvm::StringRef &PluginFN : config->passPlugins) + c.PassPlugins.push_back(std::string(PluginFN)); c.DebugPassManager = config->ltoDebugPassManager; c.DwoDir = std::string(config->dwoDir); Index: lld/ELF/Options.td =================================================================== --- lld/ELF/Options.td +++ lld/ELF/Options.td @@ -714,3 +714,5 @@ "Perform additional validation of the written dynamic relocations", "Do not perform additional validation of the written dynamic relocations">, Flags<[HelpHidden]>; + +defm load_pass_plugins: Eq<"load-pass-plugin", "Load passes from plugin library">; Index: lld/test/CMakeLists.txt =================================================================== --- lld/test/CMakeLists.txt +++ lld/test/CMakeLists.txt @@ -12,6 +12,9 @@ LLVM_ENABLE_LIBXML2 LLD_DEFAULT_LD_LLD_IS_MINGW LLVM_HAVE_LIBXAR + LLVM_BUILD_EXAMPLES + LLVM_ENABLE_PLUGINS + LLVM_BYE_LINK_INTO_TOOLS ) configure_lit_site_cfg( @@ -60,6 +63,11 @@ split-file yaml2obj ) + if (NOT WIN32) + list(APPEND LLD_TEST_DEPS + Bye + ) + endif() endif() add_lit_testsuite(check-lld "Running lld test suite" Index: lld/test/ELF/lto/ltopasses-extension.ll =================================================================== --- /dev/null +++ lld/test/ELF/lto/ltopasses-extension.ll @@ -0,0 +1,14 @@ +; REQUIRES: x86, plugins, examples +; UNSUPPORTED: windows +; RUN: opt -module-summary %s -o %t.o +; RUN: ld.lld -%loadnewpmbye --lto-newpm-passes="goodbye" -mllvm=%loadbye -mllvm=-wave-goodbye %t.o 2>&1 | FileCheck %s +; RUN: ld.lld -mllvm=%loadbye -mllvm=-wave-goodbye %t.o --plugin-opt=legacy-pass-manager 2>&1 | FileCheck %s +; CHECK: Bye + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +@junk = global i32 0 + +define i32* @somefunk() { + ret i32* @junk +} Index: lld/test/lit.cfg.py =================================================================== --- lld/test/lit.cfg.py +++ lld/test/lit.cfg.py @@ -115,6 +115,24 @@ if config.sizeof_void_p == 8: config.available_features.add("llvm-64-bits") +if config.has_plugins: + config.available_features.add('plugins') + +if config.build_examples: + config.available_features.add('examples') + +if config.linked_bye_extension: + config.substitutions.append(('%loadbye', '')) + config.substitutions.append(('%loadnewpmbye', '')) +else: + config.substitutions.append(('%loadbye', + '-load={}/Bye{}'.format(config.llvm_shlib_dir, + config.llvm_shlib_ext))) + config.substitutions.append(('%loadnewpmbye', + '-load-pass-plugin={}/Bye{}' + .format(config.llvm_shlib_dir, + config.llvm_shlib_ext))) + tar_executable = lit.util.which('tar', config.environment['PATH']) if tar_executable: env = os.environ Index: lld/test/lit.site.cfg.py.in =================================================================== --- lld/test/lit.site.cfg.py.in +++ lld/test/lit.site.cfg.py.in @@ -5,6 +5,8 @@ config.have_dia_sdk = lit.util.pythonize_bool("@LLVM_ENABLE_DIA_SDK@") config.llvm_src_root = "@LLVM_SOURCE_DIR@" config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_shlib_dir = "@SHLIBDIR@" +config.llvm_shlib_ext = "@SHLIBEXT@" config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" @@ -19,6 +21,9 @@ config.have_libxml2 = @LLVM_ENABLE_LIBXML2@ config.sizeof_void_p = @CMAKE_SIZEOF_VOID_P@ config.ld_lld_default_mingw = @LLD_DEFAULT_LD_LLD_IS_MINGW@ +config.build_examples = @LLVM_BUILD_EXAMPLES@ +config.has_plugins = @LLVM_ENABLE_PLUGINS@ +config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@ # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. Index: llvm/examples/Bye/Bye.cpp =================================================================== --- llvm/examples/Bye/Bye.cpp +++ llvm/examples/Bye/Bye.cpp @@ -50,6 +50,11 @@ [](const llvm::PassManagerBuilder &Builder, llvm::legacy::PassManagerBase &PM) { PM.add(new LegacyBye()); }); +static llvm::RegisterStandardPasses RegisterByeLTO( + llvm::PassManagerBuilder::EP_ModuleOptimizerEarly, + [](const llvm::PassManagerBuilder &Builder, + llvm::legacy::PassManagerBase &PM) { PM.add(new LegacyBye()); }); + /* New PM Registration */ llvm::PassPluginLibraryInfo getByePluginInfo() { return {LLVM_PLUGIN_API_VERSION, "Bye", LLVM_VERSION_STRING,