[PATCH] D130889: [llvm] Introduce a pass plugin registry and loader

2022-08-01 Thread Philippe Virouleau via Phabricator via cfe-commits
viroulep created this revision.
viroulep added reviewers: w2yehia, mehdi_amini, pcc.
Herald added subscribers: ormris, steven_wu, hiraditya, arichardson, mgorny, 
emaste.
Herald added a reviewer: MaskRay.
Herald added a project: All.
viroulep requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, StephenFan.
Herald added projects: clang, LLVM.

This basically extends what has been done for opt in 
https://reviews.llvm.org/D121566.

The general issue is that, at the moment and except for opt, you can't use 
command line options defined by plugins when using only -load-pass-plugin (or 
-fpass-plugin), and you have to also load the library with the "old" entry 
point through -load to have them recognized.

This is due to the fact that parsing command line options occurs before plugins 
are loaded through -load-pass-plugin, and basically each tool has its own way 
of dealing with the loading of pass plugins.
The patch tries to mimic what was done for the existing `-load` command line 
option and aims at providing common entry points for the lib and tools:

- tools make sure to register the loaded plugin (through the option or manually)
- any part of the lib/tools can query the registry to have the plugins register 
their callbacks.

As a result -load-pass-plugin has a behavior that matches the -load option, and 
tools can simply include the header defining the -load-pass-plugin option if 
they want to have the feature.

I'm not exactly sure why -load-pass-plugin wasn't created with the same 
behavior as -load, which makes me think I may be missing something: if the 
implementation I suggest doesn't look good to you I'd be happy to look into 
something else (hopefully the general idea of having a single load for old/new 
plugins does sound good to you).

This patch touches a couple of tools (clang, llvm-lto2, opt) in addition to 
llvm; I tried to include only a couple of appropriate reviewers; my apologies 
if I missed someone, please feel free to add more relevant people if you think 
it's necessary!


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130889

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CMakeLists.txt
  clang/lib/Frontend/CompilerInstance.cpp
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/LTO.cpp
  lld/test/ELF/lto/ltopasses-extension.ll
  lld/test/lit.cfg.py
  llvm/include/llvm/LTO/Config.h
  llvm/include/llvm/Passes/PassPluginLoader.h
  llvm/include/llvm/Passes/PassPluginRegistry.h
  llvm/lib/LTO/LTOBackend.cpp
  llvm/lib/Passes/CMakeLists.txt
  llvm/lib/Passes/PassPluginLoader.cpp
  llvm/lib/Passes/PassPluginRegistry.cpp
  llvm/tools/llvm-lto2/llvm-lto2.cpp
  llvm/tools/opt/NewPMDriver.cpp
  llvm/tools/opt/NewPMDriver.h
  llvm/tools/opt/opt.cpp

Index: llvm/tools/opt/opt.cpp
===
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -39,7 +39,8 @@
 #include "llvm/LinkAllPasses.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/MC/TargetRegistry.h"
-#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassPluginLoader.h"
+#include "llvm/Passes/PassPluginRegistry.h"
 #include "llvm/Remarks/HotnessThresholdParser.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
@@ -278,10 +279,6 @@
 cl::desc("The format used for serializing remarks (default: YAML)"),
 cl::value_desc("format"), cl::init("yaml"));
 
-static cl::list
-PassPlugins("load-pass-plugin",
-cl::desc("Load passes from plugin library"));
-
 namespace llvm {
 cl::opt
 PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
@@ -533,17 +530,6 @@
   initializeExampleIRTransforms(Registry);
 #endif
 
-  SmallVector PluginList;
-  PassPlugins.setCallback([&](const std::string &PluginPath) {
-auto Plugin = PassPlugin::Load(PluginPath);
-if (!Plugin) {
-  errs() << "Failed to load passes from '" << PluginPath
- << "'. Request ignored.\n";
-  return;
-}
-PluginList.emplace_back(Plugin.get());
-  });
-
   cl::ParseCommandLineOptions(argc, argv,
 "llvm .bc -> .bc modular optimizer and analysis printer\n");
 
@@ -556,7 +542,7 @@
   const bool UseNPM = (EnableNewPassManager && !shouldForceLegacyPM()) ||
   PassPipeline.getNumOccurrences() > 0;
 
-  if (!UseNPM && PluginList.size()) {
+  if (!UseNPM && PassPluginRegistry::getPlugins().size()) {
 errs() << argv[0] << ": " << PassPlugins.ArgStr
<< " specified with legacy PM.\n";
 return 1;
@@ -781,7 +767,7 @@
 // layer.
 return runPassPipeline(argv[0], *M, TM.get(), &TLII, Out.get(),
ThinLinkOut.get(), RemarksFile.get(), Pipeline,
-   Passes, PluginList, OK, VK, PreserveAssemblyUseListOrder,
+   Passes, OK, VK, PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex,
Em

[PATCH] D130889: [llvm] Introduce a pass plugin registry and loader

2022-08-08 Thread Philippe Virouleau via Phabricator via cfe-commits
viroulep added a comment.

Thanks for your review @w2yehia!




Comment at: llvm/lib/Passes/PassPluginLoader.cpp:23
+void PassPluginLoader::operator=(const std::string &Filename) {
+  sys::SmartScopedLock Lock(*PluginsLock);
+  auto PassPlugin = PassPlugin::Load(Filename);

w2yehia wrote:
> why do we need a lock? 
> Is there a use case where multiple threads enter this function.
> Right now, the only place we create a `PassPluginLoader` is in 
> `cl::opt PassPlugins`.
That's a very good question that I couldn't answer: I based the implementation 
on what is done over in [[ 
https://github.com/llvm/llvm-project/blame/main/llvm/lib/Support/PluginLoader.cpp
 | PluginLoader ]], but I too wondered why it was guarded ([[ 
https://github.com/llvm/llvm-project/commit/bee30f58fb3f65d980fa15c14aa9546145521619
 | this commit ]] introduces it but I couldn't find more details).

I'm fine with removing it unless someone can provide a use case where we need 
it; I'll update the patch!



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130889/new/

https://reviews.llvm.org/D130889

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130889: [llvm] Introduce a pass plugin registry and loader

2022-08-08 Thread Philippe Virouleau via Phabricator via cfe-commits
viroulep updated this revision to Diff 450844.
viroulep added a comment.

I took into account @w2yehia's comment, and I also noticed there was no test in 
clang for the `-fpass-plugin` option, so I added one.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130889/new/

https://reviews.llvm.org/D130889

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CMakeLists.txt
  clang/lib/Frontend/CompilerInstance.cpp
  clang/test/CMakeLists.txt
  clang/test/Frontend/load_pass_plugin.ll
  clang/test/lit.cfg.py
  clang/test/lit.site.cfg.py.in
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/LTO.cpp
  lld/test/ELF/lto/ltopasses-extension.ll
  lld/test/lit.cfg.py
  llvm/include/llvm/LTO/Config.h
  llvm/include/llvm/Passes/PassPluginLoader.h
  llvm/include/llvm/Passes/PassPluginRegistry.h
  llvm/lib/LTO/LTOBackend.cpp
  llvm/lib/Passes/CMakeLists.txt
  llvm/lib/Passes/PassPluginLoader.cpp
  llvm/lib/Passes/PassPluginRegistry.cpp
  llvm/tools/llvm-lto2/llvm-lto2.cpp
  llvm/tools/opt/NewPMDriver.cpp
  llvm/tools/opt/NewPMDriver.h
  llvm/tools/opt/opt.cpp

Index: llvm/tools/opt/opt.cpp
===
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -39,7 +39,8 @@
 #include "llvm/LinkAllPasses.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/MC/TargetRegistry.h"
-#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassPluginLoader.h"
+#include "llvm/Passes/PassPluginRegistry.h"
 #include "llvm/Remarks/HotnessThresholdParser.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
@@ -278,10 +279,6 @@
 cl::desc("The format used for serializing remarks (default: YAML)"),
 cl::value_desc("format"), cl::init("yaml"));
 
-static cl::list
-PassPlugins("load-pass-plugin",
-cl::desc("Load passes from plugin library"));
-
 namespace llvm {
 cl::opt
 PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
@@ -533,17 +530,6 @@
   initializeExampleIRTransforms(Registry);
 #endif
 
-  SmallVector PluginList;
-  PassPlugins.setCallback([&](const std::string &PluginPath) {
-auto Plugin = PassPlugin::Load(PluginPath);
-if (!Plugin) {
-  errs() << "Failed to load passes from '" << PluginPath
- << "'. Request ignored.\n";
-  return;
-}
-PluginList.emplace_back(Plugin.get());
-  });
-
   cl::ParseCommandLineOptions(argc, argv,
 "llvm .bc -> .bc modular optimizer and analysis printer\n");
 
@@ -556,7 +542,7 @@
   const bool UseNPM = (EnableNewPassManager && !shouldForceLegacyPM()) ||
   PassPipeline.getNumOccurrences() > 0;
 
-  if (!UseNPM && PluginList.size()) {
+  if (!UseNPM && PassPluginRegistry::getPlugins().size()) {
 errs() << argv[0] << ": " << PassPlugins.ArgStr
<< " specified with legacy PM.\n";
 return 1;
@@ -781,7 +767,7 @@
 // layer.
 return runPassPipeline(argv[0], *M, TM.get(), &TLII, Out.get(),
ThinLinkOut.get(), RemarksFile.get(), Pipeline,
-   Passes, PluginList, OK, VK, PreserveAssemblyUseListOrder,
+   Passes, OK, VK, PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex,
EmitModuleHash, EnableDebugify,
VerifyDebugInfoPreserve)
Index: llvm/tools/opt/NewPMDriver.h
===
--- llvm/tools/opt/NewPMDriver.h
+++ llvm/tools/opt/NewPMDriver.h
@@ -25,7 +25,6 @@
 namespace llvm {
 class StringRef;
 class Module;
-class PassPlugin;
 class TargetMachine;
 class ToolOutputFile;
 class TargetLibraryInfoImpl;
@@ -72,8 +71,7 @@
  TargetLibraryInfoImpl *TLII, ToolOutputFile *Out,
  ToolOutputFile *ThinLinkOut, ToolOutputFile *OptRemarkFile,
  StringRef PassPipeline, ArrayRef PassInfos,
- ArrayRef PassPlugins, opt_tool::OutputKind OK,
- opt_tool::VerifierKind VK,
+ opt_tool::OutputKind OK, opt_tool::VerifierKind VK,
  bool ShouldPreserveAssemblyUseListOrder,
  bool ShouldPreserveBitcodeUseListOrder,
  bool EmitSummaryIndex, bool EmitModuleHash,
Index: llvm/tools/opt/NewPMDriver.cpp
===
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -27,7 +27,7 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/Passes/PassBuilder.h"
-#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassPluginRegistry.h"
 #include "llvm/Passes/StandardInstrumentations.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -288,7 +288,6 @@
ToolOutputFile *ThinLTOLinkOut,
ToolOutputFile *OptRemarkFile,