[llvm] 3084a8f - [Plugins] Add -plugin-arg and PassPluginLibraryInfo::ParseArguments (#227414)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 11:59:14 PDT 2026


Author: Fangrui Song
Date: 2026-09-29T18:59:03Z
New Revision: 3084a8ffb386822a584f4658d8351a24aa3d965e

URL: https://github.com/llvm/llvm-project/commit/3084a8ffb386822a584f4658d8351a24aa3d965e
DIFF: https://github.com/llvm/llvm-project/commit/3084a8ffb386822a584f4658d8351a24aa3d965e.diff

LOG: [Plugins] Add -plugin-arg and PassPluginLibraryInfo::ParseArguments (#227414)

opt and llc load -load-pass-plugin plugins from a cl::opt callback while
parsing argv, so that the options a plugin registers are recognized
later on the command line. cl::callback is to be removed to enable
migration to a TableGen-based option representation

(https://discourse.llvm.org/t/rfc-declare-library-command-line-options-in-tablegen-one-struct-per-library/91877/5).
To prepare for loading plugins after parsing, give plugins their own
arguments.

Add `-plugin-arg=<plugin>,<arg>`, which passes <arg> (split at the first
comma, so it may contain commas) to the new
PassPluginLibraryInfo::ParseArguments callback of the plugin named
<plugin> (LLVM_PLUGIN_API_VERSION 3). Plugins that define cl::opt (Polly
and the Bye and IRTransforms examples) parse their arguments with the
new parsePassPluginCommandLine.

opt also passes -plugin-arg arguments to statically linked extensions
(Extension.def), so Polly's options have the same spelling in both build
modes:

```
opt -plugin-arg=Polly,-polly-tile-sizes=1,64 ...                                 # linked
opt -load-pass-plugin=LLVMPolly.so -plugin-arg=Polly,-polly-tile-sizes=1,64 ...  # plugin
```

opt now registers plugins and linked extensions in one loop, so
optMain's PassBuilderCallbacks run after linked extensions.

Extracted from #226773

Added: 
    

Modified: 
    llvm/docs/NewPassManager.md
    llvm/docs/ReleaseNotes.md
    llvm/examples/Bye/Bye.cpp
    llvm/examples/IRTransforms/SimplifyCFG.cpp
    llvm/include/llvm/Plugins/PassPlugin.h
    llvm/lib/Plugins/PassPlugin.cpp
    llvm/test/Feature/codegen-plugin-passes.mir
    llvm/test/Feature/codegen-plugin.ll
    llvm/test/Feature/load_extension.ll
    llvm/tools/llc/lib/llcdriver.cpp
    llvm/tools/opt/NewPMDriver.cpp
    llvm/tools/opt/NewPMDriver.h
    llvm/tools/opt/optdriver.cpp
    polly/lib/Support/RegisterPasses.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/NewPassManager.md b/llvm/docs/NewPassManager.md
index f9b819c2591c8..1c264c3eaad6d 100644
--- a/llvm/docs/NewPassManager.md
+++ b/llvm/docs/NewPassManager.md
@@ -174,8 +174,10 @@ backend adding passes to various parts of the pipeline.
 
 Pass plugins can also add passes into default pipelines. Different tools have
 
diff erent ways of loading dynamic pass plugins. For example, `opt
--load-pass-plugin=path/to/plugin.so` loads a pass plugin into `opt`. For
-information on writing a pass plugin, see {doc}`WritingAnLLVMNewPMPass`.
+-load-pass-plugin=path/to/plugin.so` loads a pass plugin into `opt`, and
+`-plugin-arg=Name,-opt` passes `-opt` to the `ParseArguments` callback of the
+plugin or statically linked extension named `Name`. For information on writing a pass plugin, see
+{doc}`WritingAnLLVMNewPMPass`.
 
 ## Using Analyses
 

diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 41b2fa83d380f..f66c80ecea9a2 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -330,6 +330,10 @@ Makes programs 10x faster by doing Special New Thing.
 
 ### Changes to the LLVM tools
 
+* `opt` and `llc` accept `-plugin-arg=<plugin>,<arg>`, which passes `<arg>` to the new `PassPluginLibraryInfo::ParseArguments` callback of the pass plugin named `<plugin>`.
+  A plugin that defines `cl::opt` can call `parsePassPluginCommandLine` from `ParseArguments`, as the `Bye` example and Polly do.
+  `LLVM_PLUGIN_API_VERSION` is now 3.
+
 * llvm-mca no longer defaults -mcpu to "native"
 
 * llvm-rc now supports `/showIncludes` to report header and resource-file

diff  --git a/llvm/examples/Bye/Bye.cpp b/llvm/examples/Bye/Bye.cpp
index fbe3b75920679..a328993a163ec 100644
--- a/llvm/examples/Bye/Bye.cpp
+++ b/llvm/examples/Bye/Bye.cpp
@@ -14,6 +14,9 @@ static cl::opt<bool> Wave("wave-goodbye", cl::init(false),
 static cl::opt<bool> LastWords("last-words", cl::init(false),
                                cl::desc("say last words (suppress codegen)"));
 
+static cl::opt<std::string> Greeting("bye-greeting",
+                                     cl::desc("also print this greeting"));
+
 namespace {
 
 bool runBye(Function &F) {
@@ -21,6 +24,10 @@ bool runBye(Function &F) {
     errs() << "Bye: ";
     errs().write_escaped(F.getName()) << '\n';
   }
+  if (!Greeting.empty()) {
+    errs() << Greeting << ": ";
+    errs().write_escaped(F.getName()) << '\n';
+  }
   return false;
 }
 
@@ -77,10 +84,15 @@ static RegisterPass<LegacyBye> X("goodbye", "Good Bye World Pass",
                                  false /* Only looks at CFG */,
                                  false /* Analysis Pass */);
 
+static Error parseArguments(ArrayRef<const char *> Args) {
+  return parsePassPluginCommandLine("Bye", Args);
+}
+
 /* New PM Registration */
 llvm::PassPluginLibraryInfo getByePluginInfo() {
-  return {LLVM_PLUGIN_API_VERSION, "Bye", LLVM_VERSION_STRING,
-          registerPassBuilderCallbacks, preCodeGenCallback};
+  return {LLVM_PLUGIN_API_VERSION, "Bye",
+          LLVM_VERSION_STRING,     registerPassBuilderCallbacks,
+          preCodeGenCallback,      parseArguments};
 }
 
 #ifndef LLVM_BYE_LINK_INTO_TOOLS

diff  --git a/llvm/examples/IRTransforms/SimplifyCFG.cpp b/llvm/examples/IRTransforms/SimplifyCFG.cpp
index eb82ae9ad00d8..e964663f99212 100644
--- a/llvm/examples/IRTransforms/SimplifyCFG.cpp
+++ b/llvm/examples/IRTransforms/SimplifyCFG.cpp
@@ -40,6 +40,7 @@
 #include "llvm/Passes/PassBuilder.h"
 #include "llvm/Plugins/PassPlugin.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace PatternMatch;
@@ -391,9 +392,15 @@ struct SimplifyCFGPass : public OptionalPassInfoMixin<SimplifyCFGPass> {
 };
 } // namespace
 
+static Error parseArguments(ArrayRef<const char *> Args) {
+  return parsePassPluginCommandLine("SimplifyCFG", Args);
+}
+
 /* New PM Registration */
 llvm::PassPluginLibraryInfo getExampleIRTransformsPluginInfo() {
-  return {LLVM_PLUGIN_API_VERSION, "SimplifyCFG", LLVM_VERSION_STRING,
+  return {LLVM_PLUGIN_API_VERSION,
+          "SimplifyCFG",
+          LLVM_VERSION_STRING,
           [](PassBuilder &PB) {
             PB.registerPipelineParsingCallback(
                 [](StringRef Name, llvm::FunctionPassManager &PM,
@@ -404,7 +411,9 @@ llvm::PassPluginLibraryInfo getExampleIRTransformsPluginInfo() {
                   }
                   return false;
                 });
-          }};
+          },
+          nullptr,
+          parseArguments};
 }
 
 #ifndef LLVM_EXAMPLEIRTRANSFORMS_LINK_INTO_TOOLS

diff  --git a/llvm/include/llvm/Plugins/PassPlugin.h b/llvm/include/llvm/Plugins/PassPlugin.h
index 7c2d1a5de799f..82f8bf3ef51a6 100644
--- a/llvm/include/llvm/Plugins/PassPlugin.h
+++ b/llvm/include/llvm/Plugins/PassPlugin.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_PLUGINS_PASSPLUGIN_H
 #define LLVM_PLUGINS_PASSPLUGIN_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Compiler.h"
@@ -33,7 +34,7 @@ class TargetMachine;
 /// against that of the plugin. A mismatch is an error. The supported version
 /// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo
 /// struct, i.e. when callbacks are added, removed, or reordered.
-#define LLVM_PLUGIN_API_VERSION 2
+#define LLVM_PLUGIN_API_VERSION 3
 
 extern "C" {
 /// Information about the plugin required to load its passes
@@ -61,6 +62,10 @@ struct PassPluginLibraryInfo {
   /// callbacks from running.
   bool (*PreCodeGenCallback)(Module &, TargetMachine &, CodeGenFileType,
                              raw_pwrite_stream &OS) = nullptr;
+
+  /// Callback receiving the arguments given to the plugin, e.g. by
+  /// -plugin-arg=<PluginName>,<arg>, in order.
+  Error (*ParseArguments)(ArrayRef<const char *> Args) = nullptr;
 };
 }
 
@@ -89,6 +94,8 @@ class PassPlugin {
   /// Get the plugin API version
   uint32_t getAPIVersion() const { return Info.APIVersion; }
 
+  const PassPluginLibraryInfo &getInfo() const { return Info; }
+
   /// Invoke the PassBuilder callback registration
   void registerPassBuilderCallbacks(PassBuilder &PB) const {
     if (Info.RegisterPassBuilderCallbacks)
@@ -112,6 +119,16 @@ class PassPlugin {
   sys::DynamicLibrary Library;
   PassPluginLibraryInfo Info;
 };
+
+/// Passes each "<PluginName>,<arg>" in \p Args to the \c ParseArguments
+/// callback of the extension in \p Infos with that name. If two extensions have
+/// the same name, the last one receives the arguments.
+LLVM_ABI Error passPluginArguments(ArrayRef<PassPluginLibraryInfo> Infos,
+                                   ArrayRef<std::string> Args);
+
+// Deprecated: a migration aid for plugins that still use cl::opt.
+LLVM_ABI Error parsePassPluginCommandLine(const char *PluginName,
+                                          ArrayRef<const char *> Args);
 } // namespace llvm
 
 // The function returns a struct with default initializers.

diff  --git a/llvm/lib/Plugins/PassPlugin.cpp b/llvm/lib/Plugins/PassPlugin.cpp
index 9034060380e68..03d18d931376f 100644
--- a/llvm/lib/Plugins/PassPlugin.cpp
+++ b/llvm/lib/Plugins/PassPlugin.cpp
@@ -7,6 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Plugins/PassPlugin.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <cstdint>
@@ -47,3 +50,43 @@ Expected<PassPlugin> PassPlugin::load(StringRef Filename) {
 
   return P;
 }
+
+Error llvm::passPluginArguments(ArrayRef<PassPluginLibraryInfo> Infos,
+                                ArrayRef<std::string> Args) {
+  DenseMap<StringRef, unsigned> Index;
+  for (auto [I, Info] : enumerate(Infos))
+    Index[Info.PluginName] = I;
+  // The argument follows the first comma, so it is NUL-terminated.
+  SmallVector<SmallVector<const char *, 0>, 0> PluginArgs(Infos.size());
+  for (const std::string &Arg : Args) {
+    auto [Name, Rest] = StringRef(Arg).split(',');
+    if (Rest.empty())
+      return createStringError("expected <plugin>,<arg> in -plugin-arg=" + Arg);
+    auto It = Index.find(Name);
+    if (It == Index.end())
+      return createStringError("no pass plugin named '" + Name +
+                               "' is loaded, in -plugin-arg=" + Arg);
+    PluginArgs[It->second].push_back(Rest.data());
+  }
+  for (auto [Info, PArgs] : zip_equal(Infos, PluginArgs)) {
+    if (PArgs.empty())
+      continue;
+    if (!Info.ParseArguments)
+      return createStringError("pass plugin '" + Twine(Info.PluginName) +
+                               "' does not accept arguments");
+    if (Error E = Info.ParseArguments(PArgs))
+      return E;
+  }
+  return Error::success();
+}
+
+Error llvm::parsePassPluginCommandLine(const char *PluginName,
+                                       ArrayRef<const char *> Args) {
+  SmallVector<const char *, 0> Argv = {PluginName};
+  append_range(Argv, Args);
+  std::string Msg;
+  raw_string_ostream OS(Msg);
+  if (!cl::ParseCommandLineOptions(Argv.size(), Argv.data(), "", &OS))
+    return createStringError(StringRef(Msg).trim());
+  return Error::success();
+}

diff  --git a/llvm/test/Feature/codegen-plugin-passes.mir b/llvm/test/Feature/codegen-plugin-passes.mir
index 4b4ac5c54e59c..097081752fa34 100644
--- a/llvm/test/Feature/codegen-plugin-passes.mir
+++ b/llvm/test/Feature/codegen-plugin-passes.mir
@@ -4,7 +4,7 @@
 # UNSUPPORTED: target={{.*windows.*}}
 # Plugins are currently broken on AIX, at least in the CI.
 # XFAIL: target={{.*}}-aix{{.*}}
-# RUN: llc -mtriple=x86_64-- %loadnewpmbye -passes=goodbye -wave-goodbye %s -o /dev/null 2>&1 | FileCheck %s
+# RUN: llc -mtriple=x86_64-- %loadnewpmbye -passes=goodbye -plugin-arg=Bye,-wave-goodbye %s -o /dev/null 2>&1 | FileCheck %s
 # RUN: llc -mtriple=x86_64-- %loadnewpmbye -passes=goodbye --print-pipeline-passes -filetype=null %s | FileCheck %s --check-prefix=PIPELINE
 
 # CHECK: Bye: somefunk

diff  --git a/llvm/test/Feature/codegen-plugin.ll b/llvm/test/Feature/codegen-plugin.ll
index cd36ef14d8ec3..571c7e348520e 100644
--- a/llvm/test/Feature/codegen-plugin.ll
+++ b/llvm/test/Feature/codegen-plugin.ll
@@ -1,7 +1,7 @@
 ; REQUIRES: x86-registered-target
 ; RUN: llc < %s %loadnewpmbye | FileCheck %s --check-prefix=CHECK-ASM
-; RUN: llc < %s %loadnewpmbye -last-words | FileCheck %s --check-prefix=CHECK-ACTIVE
-; RUN: not llc < %s %loadnewpmbye -last-words -filetype=obj 2>&1 | FileCheck %s --check-prefix=CHECK-ERR
+; RUN: llc < %s %loadnewpmbye -plugin-arg=Bye,-last-words | FileCheck %s --check-prefix=CHECK-ACTIVE
+; RUN: not llc < %s %loadnewpmbye -plugin-arg=Bye,-last-words -filetype=obj 2>&1 | FileCheck %s --check-prefix=CHECK-ERR
 ; REQUIRES: plugins, examples
 ; UNSUPPORTED: target={{.*windows.*}}
 ; Plugins are currently broken on AIX, at least in the CI.

diff  --git a/llvm/test/Feature/load_extension.ll b/llvm/test/Feature/load_extension.ll
index 6f99e99cb6345..80f0ca8a33c8a 100644
--- a/llvm/test/Feature/load_extension.ll
+++ b/llvm/test/Feature/load_extension.ll
@@ -1,6 +1,9 @@
 ; REQUIRES: x86-registered-target
 ; RUN: opt %s %loadnewpmbye %loadbye -passes="goodbye" -wave-goodbye -disable-output 2>&1 | FileCheck %s
-; RUN: opt %s %loadnewpmbye -passes="goodbye" -wave-goodbye -disable-output 2>&1 | FileCheck %s
+; RUN: opt %s %loadnewpmbye -passes="goodbye" -plugin-arg=Bye,-wave-goodbye -disable-output 2>&1 | FileCheck %s
+;; A plugin receives all of its -plugin-arg arguments. -plugin-arg splits at
+;; the first comma only, so the value may contain commas.
+; RUN: opt %s %loadnewpmbye -passes="goodbye" -plugin-arg=Bye,-wave-goodbye -plugin-arg=Bye,-bye-greeting=See,you -disable-output 2>&1 | FileCheck %s --check-prefix=BOTH
 ; RUN: opt -module-summary %s -o %t.o
 ; RUN: llvm-lto2 run %t.o %loadbye %loadnewpmbye -wave-goodbye -o %t -r %t.o,somefunk,plx -r %t.o,junk,plx 2>&1 | FileCheck %s
 ; RUN: llvm-lto2 run %t.o %loadbye %loadnewpmbye -opt-pipeline="goodbye" -wave-goodbye -o %t -r %t.o,somefunk,plx -r %t.o,junk,plx 2>&1 | FileCheck %s
@@ -9,6 +12,8 @@
 ; Plugins are currently broken on AIX, at least in the CI.
 ; XFAIL: target={{.*}}-aix{{.*}}
 ; CHECK: Bye
+; BOTH:      Bye: somefunk
+; BOTH-NEXT: See,you: somefunk
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"

diff  --git a/llvm/tools/llc/lib/llcdriver.cpp b/llvm/tools/llc/lib/llcdriver.cpp
index 6f19f1dbe295a..3036e69e066ca 100644
--- a/llvm/tools/llc/lib/llcdriver.cpp
+++ b/llvm/tools/llc/lib/llcdriver.cpp
@@ -15,6 +15,7 @@
 #include "NewPMDriver.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/SmallVectorExtras.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/RuntimeLibcallInfo.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -216,6 +217,11 @@ static cl::opt<std::string> RemarksFormat(
 static cl::list<std::string> PassPlugins("load-pass-plugin",
                                          cl::desc("Load plugin library"));
 
+static cl::list<std::string>
+    PluginArgs("plugin-arg",
+               cl::desc("Pass <arg> to the pass plugin named <plugin>"),
+               cl::value_desc("plugin>,<arg"));
+
 static cl::opt<bool> EnableNewPassManager(
     "enable-new-pm", cl::desc("Enable the new pass manager"), cl::init(false));
 
@@ -409,6 +415,12 @@ extern "C" int llcMain(int argc, char **argv) {
 
   cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
 
+  if (Error E = passPluginArguments(
+          map_to_vector(PluginList,
+                        [](const PassPlugin &P) { return P.getInfo(); }),
+          PluginArgs))
+    reportFatalUsageError(std::move(E));
+
   if (!PassPipeline.empty() && !getRunPassNames().empty()) {
     errs() << "The `llc -run-pass=...` syntax for the new pass manager is "
               "not supported, please use `llc -passes=<pipeline>` (or the `-p` "

diff  --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index a920f154db21c..e19dc61e772a3 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -376,16 +376,11 @@ static void registerEPCallbacks(PassBuilder &PB) {
         });
 }
 
-#define HANDLE_EXTENSION(Ext)                                                  \
-  llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
-#include "llvm/Support/Extension.def"
-#undef HANDLE_EXTENSION
-
 bool llvm::runPassPipeline(
     StringRef Arg0, Module &M, TargetMachine *TM, TargetLibraryInfoImpl *TLII,
     ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut,
     ToolOutputFile *OptRemarkFile, StringRef PassPipeline,
-    ArrayRef<PassPlugin> PassPlugins,
+    ArrayRef<PassPluginLibraryInfo> Extensions,
     ArrayRef<std::function<void(PassBuilder &)>> PassBuilderCallbacks,
     OutputKind OK, VerifierKind VK, bool ShouldPreserveAssemblyUseListOrder,
     bool ShouldPreserveBitcodeUseListOrder, bool EmitSummaryIndex,
@@ -488,19 +483,15 @@ bool llvm::runPassPipeline(
   PassBuilder PB(TM, PTO, P, &PIC);
   registerEPCallbacks(PB);
 
-  // For any loaded plugins, let them register pass builder callbacks.
-  for (auto &PassPlugin : PassPlugins)
-    PassPlugin.registerPassBuilderCallbacks(PB);
+  // Let plugins and linked extensions register pass builder callbacks.
+  for (const PassPluginLibraryInfo &Info : Extensions)
+    if (Info.RegisterPassBuilderCallbacks)
+      Info.RegisterPassBuilderCallbacks(PB);
 
   // Load any explicitly specified plugins.
   for (auto &PassCallback : PassBuilderCallbacks)
     PassCallback(PB);
 
-#define HANDLE_EXTENSION(Ext)                                                  \
-  get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
-#include "llvm/Support/Extension.def"
-#undef HANDLE_EXTENSION
-
   // Specially handle the alias analysis manager so that we can register
   // a custom pipeline of AA passes with it.
   AAManager AA;

diff  --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/NewPMDriver.h
index 042d5d4bbfe47..d5d0d851013a5 100644
--- a/llvm/tools/opt/NewPMDriver.h
+++ b/llvm/tools/opt/NewPMDriver.h
@@ -25,8 +25,8 @@
 namespace llvm {
 class PassBuilder;
 class StringRef;
+struct PassPluginLibraryInfo;
 class Module;
-class PassPlugin;
 class TargetMachine;
 class ToolOutputFile;
 class TargetLibraryInfoImpl;
@@ -69,7 +69,7 @@ bool runPassPipeline(
     StringRef Arg0, Module &M, TargetMachine *TM, TargetLibraryInfoImpl *TLII,
     ToolOutputFile *Out, ToolOutputFile *ThinLinkOut,
     ToolOutputFile *OptRemarkFile, StringRef PassPipeline,
-    ArrayRef<PassPlugin> PassPlugins,
+    ArrayRef<PassPluginLibraryInfo> Extensions,
     ArrayRef<std::function<void(PassBuilder &)>> PassBuilderCallbacks,
     opt_tool::OutputKind OK, opt_tool::VerifierKind VK,
     bool ShouldPreserveAssemblyUseListOrder,

diff  --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index 2a219c4e5d568..3b7edb013af84 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -62,6 +62,11 @@
 #include <algorithm>
 #include <memory>
 #include <optional>
+
+#define HANDLE_EXTENSION(Ext)                                                  \
+  llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
+#include "llvm/Support/Extension.def"
+
 using namespace llvm;
 using namespace opt_tool;
 
@@ -285,6 +290,11 @@ static cl::list<std::string>
     PassPlugins("load-pass-plugin",
                 cl::desc("Load passes from plugin library"));
 
+static cl::list<std::string>
+    PluginArgs("plugin-arg",
+               cl::desc("Pass <arg> to the pass plugin named <plugin>"),
+               cl::value_desc("plugin>,<arg"));
+
 //===----------------------------------------------------------------------===//
 // CodeGen-related helper functions.
 //
@@ -443,12 +453,12 @@ optMain(int argc, char **argv,
   initializeReplaceWithVeclibLegacyPass(Registry);
   initializeJMCInstrumenterPass(Registry);
 
-  SmallVector<PassPlugin, 1> PluginList;
+  SmallVector<PassPluginLibraryInfo, 0> Extensions;
   PassPlugins.setCallback([&](const std::string &PluginPath) {
     auto Plugin = PassPlugin::load(PluginPath);
     if (!Plugin)
       reportFatalUsageError(Plugin.takeError());
-    PluginList.emplace_back(Plugin.get());
+    Extensions.push_back(Plugin->getInfo());
   });
 
   // Register the Target and CPU printer for --version.
@@ -457,6 +467,11 @@ optMain(int argc, char **argv,
   cl::ParseCommandLineOptions(
       argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n");
 
+#define HANDLE_EXTENSION(Ext) Extensions.push_back(get##Ext##PluginInfo());
+#include "llvm/Support/Extension.def"
+  if (Error E = passPluginArguments(Extensions, PluginArgs))
+    reportFatalUsageError(std::move(E));
+
   LLVMContext Context;
 
   // TODO: remove shouldForceLegacyPM().
@@ -472,7 +487,7 @@ optMain(int argc, char **argv,
     return 1;
   }
 
-  if (!UseNPM && PluginList.size()) {
+  if (!UseNPM && !PassPlugins.empty()) {
     errs() << argv[0] << ": " << PassPlugins.ArgStr
            << " specified with legacy PM.\n";
     return 1;
@@ -800,7 +815,7 @@ optMain(int argc, char **argv,
     // layer.
     if (!runPassPipeline(
             argv[0], *M, TM.get(), &TLII, Out.get(), ThinLinkOut.get(),
-            RemarksFile.get(), Pipeline, PluginList, PassBuilderCallbacks, OK,
+            RemarksFile.get(), Pipeline, Extensions, PassBuilderCallbacks, OK,
             VK, /* ShouldPreserveAssemblyUseListOrder */ false,
             /* ShouldPreserveBitcodeUseListOrder */ true, EmitSummaryIndex,
             EmitModuleHash, EnableDebugify, VerifyDebugInfoPreserve,

diff  --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index a00176bb653aa..a0480d9f936b2 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -50,6 +50,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/IPO.h"
 
 using namespace llvm;
@@ -690,7 +691,14 @@ void registerPollyPasses(PassBuilder &PB) {
 }
 } // namespace polly
 
+static Error parseArguments(ArrayRef<const char *> Args) {
+  return parsePassPluginCommandLine("Polly", Args);
+}
+
 llvm::PassPluginLibraryInfo getPollyPluginInfo() {
-  return {LLVM_PLUGIN_API_VERSION, "Polly", LLVM_VERSION_STRING,
-          polly::registerPollyPasses};
+  llvm::PassPluginLibraryInfo Info = {LLVM_PLUGIN_API_VERSION, "Polly",
+                                      LLVM_VERSION_STRING,
+                                      polly::registerPollyPasses};
+  Info.ParseArguments = parseArguments;
+  return Info;
 }


        


More information about the llvm-commits mailing list