diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -139,6 +139,9 @@ /// with llvm-lto2. std::unique_ptr ResolutionFile; + /// Plugins to be loaded by PassManager. + std::vector PassPlugins; + /// Tunable parameters for passes in the default pipelines. PipelineTuningOptions PTO; diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/SubtargetFeature.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Passes/PassBuilder.h" +#include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" @@ -177,6 +178,17 @@ PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC); AAManager AA; + // Load pass plugins if available + for (auto &P : Conf.PassPlugins) { + auto PassPlugin = PassPlugin::Load(P); + if (PassPlugin) { + PassPlugin->registerPassBuilderCallbacks(PB); + } else { + report_fatal_error("Unable to load pass plugin '" + P + "': " + + toString(PassPlugin.takeError())); + } + } + // Parse a custom AA pipeline if asked to. if (auto Err = PB.parseAAPipeline(AA, "default")) report_fatal_error("Error parsing default AA pipeline"); diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -23,6 +23,7 @@ #include "llvm/Object/Error.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -207,6 +208,8 @@ static std::string stats_file; // Asserts that LTO link has whole program visibility static bool whole_program_visibility = false; + // List of new PM pass plugins + static std::vector pass_plugins; // Optimization remarks filename, accepted passes and hotness options static std::string RemarksFilename; @@ -306,6 +309,14 @@ RemarksFormat = std::string(opt.substr(strlen("opt-remarks-format="))); } else if (opt.startswith("stats-file=")) { stats_file = std::string(opt.substr(strlen("stats-file="))); + } else if (opt.startswith("load=")) { + std::string Error, Path(opt.substr(strlen("load="))); + + if (sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + message(LDPL_ERROR, "Unable to load plugin: %s", Error.c_str()); + } else if (opt.startswith("load-pass-plugin=")) { + pass_plugins.push_back( + std::string(opt.substr(strlen("load-pass-plugin=")))); } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -941,6 +952,8 @@ Conf.UseNewPM = options::new_pass_manager; // Debug new pass manager if requested Conf.DebugPassManager = options::debug_pass_manager; + // Pass plugins to load + Conf.PassPlugins = std::move(options::pass_plugins); Conf.HasWholeProgramVisibility = options::whole_program_visibility;