Index: clang/include/clang/Basic/CodeGenOptions.h =================================================================== --- clang/include/clang/Basic/CodeGenOptions.h +++ clang/include/clang/Basic/CodeGenOptions.h @@ -17,6 +17,7 @@ #include "clang/Basic/DebugInfoOptions.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/XRayInstr.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Regex.h" #include "llvm/Target/TargetOptions.h" @@ -288,6 +289,9 @@ std::vector DefaultFunctionAttrs; + /// List of dynamic shared object files to be loaded as pass plugins. + SmallVector PassPlugins; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1613,6 +1613,9 @@ def fno_rwpi : Flag<["-"], "fno-rwpi">, Group; def fplugin_EQ : Joined<["-"], "fplugin=">, Group, Flags<[DriverOption]>, MetaVarName<"">, HelpText<"Load the named plugin (dynamic shared object)">; +def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">, + Group, Flags<[CC1Option]>, MetaVarName<"">, + HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">; def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group; def fno_preserve_as_comments : Flag<["-"], "fno-preserve-as-comments">, Group, Flags<[CC1Option]>, HelpText<"Do not preserve comments in inline assembly">; Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -37,6 +37,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Passes/PassBuilder.h" +#include "llvm/Passes/PassPlugin.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" @@ -962,6 +963,16 @@ PassBuilder PB(TM.get(), PGOOpt); + // Attempt to load pass plugins and register their callbacks with PB. + for (auto &PluginFN : CodeGenOpts.PassPlugins) { + if (auto PassPlugin = PassPlugin::Load(PluginFN)) { + PassPlugin->registerPassBuilderCallbacks(PB); + } else { + errs() << "Failed to load passes from '" << PluginFN + << "'. Request ignored.\n"; + } + } + LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager); FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager); CGSCCAnalysisManager CGAM(CodeGenOpts.DebugPassManager); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -5066,6 +5066,13 @@ A->claim(); } + // Forward -fpass-plugin=name.so to -cc1. + for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) { + CmdArgs.push_back( + Args.MakeArgString(Twine("-fpass-plugin=") + A->getValue())); + A->claim(); + } + // Setup statistics file output. SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D); if (!StatsFile.empty()) Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1322,6 +1322,9 @@ Opts.DefaultFunctionAttrs = Args.getAllArgValues(OPT_default_function_attr); + for (auto &&V : Args.getAllArgValues(OPT_fpass_plugin_EQ)) + Opts.PassPlugins.push_back(std::move(V)); + return Success; }