diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -140,6 +140,7 @@ std::vector versionDefinitions; std::vector auxiliaryList; std::vector filterList; + std::vector passPlugins; std::vector searchPaths; std::vector symbolOrderingFile; std::vector thinLTOModulesToCompile; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1287,6 +1287,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()); diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -147,6 +147,8 @@ c.SampleProfile = std::string(config->ltoSampleProfile); c.UseNewPM = config->ltoNewPassManager; + for (StringRef pluginFn : config->passPlugins) + c.PassPlugins.push_back(std::string(pluginFn)); c.DebugPassManager = config->ltoDebugPassManager; c.DwoDir = std::string(config->dwoDir); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -716,3 +716,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: EEq<"load-pass-plugin", "Load passes from plugin library">; diff --git a/lld/test/CMakeLists.txt b/lld/test/CMakeLists.txt --- a/lld/test/CMakeLists.txt +++ b/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" diff --git a/lld/test/ELF/lto/ltopasses-extension.ll b/lld/test/ELF/lto/ltopasses-extension.ll new file mode 100644 --- /dev/null +++ b/lld/test/ELF/lto/ltopasses-extension.ll @@ -0,0 +1,13 @@ +; 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 -o /dev/null 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 +} diff --git a/lld/test/lit.cfg.py b/lld/test/lit.cfg.py --- a/lld/test/lit.cfg.py +++ b/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 diff --git a/lld/test/lit.site.cfg.py.in b/lld/test/lit.site.cfg.py.in --- a/lld/test/lit.site.cfg.py.in +++ b/lld/test/lit.site.cfg.py.in @@ -7,6 +7,8 @@ config.llvm_obj_root = "@LLVM_BINARY_DIR@" config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@") config.llvm_libs_dir = lit_config.substitute("@LLVM_LIBS_DIR@") +config.llvm_shlib_dir = "@SHLIBDIR@" +config.llvm_shlib_ext = "@SHLIBEXT@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@" config.lld_obj_root = "@LLD_BINARY_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@ import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/llvm/examples/Bye/Bye.cpp b/llvm/examples/Bye/Bye.cpp --- a/llvm/examples/Bye/Bye.cpp +++ b/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,