From 32012eb11b235e1560a253664095676ea8ebd027 Mon Sep 17 00:00:00 2001 From: Jakob Koschel Date: Thu, 24 Mar 2022 07:52:16 +0100 Subject: [PATCH] [ELF] Enable new passmanager plugin support for LTO Add cli options for new passmanager plugin support to lld. Currently it is not possible to load dynamic NewPM plugins with lld. This is an incremental update to D76866. While that patch only added cli options for llvm-lto2, this adds them for lld as well. This is especially useful for running dynamic plugins on the linux kernel with LTO. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D120490 --- lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 2 ++ lld/ELF/LTO.cpp | 2 ++ lld/ELF/Options.td | 2 ++ lld/test/CMakeLists.txt | 8 ++++++++ lld/test/ELF/lto/ltopasses-extension.ll | 13 +++++++++++++ lld/test/lit.cfg.py | 18 ++++++++++++++++++ lld/test/lit.site.cfg.py.in | 5 +++++ llvm/examples/Bye/Bye.cpp | 5 +++++ 9 files changed, 56 insertions(+) create mode 100644 lld/test/ELF/lto/ltopasses-extension.ll diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 59df5ee5..4992238 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -140,6 +140,7 @@ struct Configuration { 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 index ebf0de0..dd785cc 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1287,6 +1287,8 @@ static void readConfigs(opt::InputArgList &args) { 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 index 9ac21dd..f1a74cf 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -147,6 +147,8 @@ static lto::Config createConfig() { 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 index 43c163b..a69f255 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -716,3 +716,5 @@ defm check_dynamic_relocations: BB<"check-dynamic-relocations", "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 index 6fb1750..bfd731f 100644 --- a/lld/test/CMakeLists.txt +++ b/lld/test/CMakeLists.txt @@ -12,6 +12,9 @@ llvm_canonicalize_cmake_booleans( 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 @@ if (NOT LLD_BUILT_STANDALONE) 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 index 0000000..1792448 --- /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 index 22012b5..e0b8a82 100644 --- a/lld/test/lit.cfg.py +++ b/lld/test/lit.cfg.py @@ -115,6 +115,24 @@ if config.have_dia_sdk: 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 index ffc762d..c86e547 100644 --- a/lld/test/lit.site.cfg.py.in +++ b/lld/test/lit.site.cfg.py.in @@ -7,6 +7,8 @@ config.llvm_src_root = "@LLVM_SOURCE_DIR@" 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_libxar = @LLVM_HAVE_LIBXAR@ 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 index b75fbeb..ba50f94 100644 --- a/llvm/examples/Bye/Bye.cpp +++ b/llvm/examples/Bye/Bye.cpp @@ -50,6 +50,11 @@ static llvm::RegisterStandardPasses RegisterBye( [](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, -- 2.7.4