[PATCH] D102909: [NPM] Ability to add a pass before a previously registered one

Lucas Prates via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 21 02:56:20 PDT 2021


pratlucas created this revision.
Herald added a subscriber: dexonsmith.
pratlucas requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This patch introduces the `addPassBefore` method to `PassManager`,
allowing a pass to be registered before another specific one that
may have been registered before it.

This is specially useful for pass plugins, which do not go through the
Pass Registry and lack some of the granularity for controlling when
they should be run.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D102909

Files:
  llvm/include/llvm/IR/PassManager.h
  llvm/unittests/IR/PassManagerTest.cpp


Index: llvm/unittests/IR/PassManagerTest.cpp
===================================================================
--- llvm/unittests/IR/PassManagerTest.cpp
+++ llvm/unittests/IR/PassManagerTest.cpp
@@ -703,6 +703,18 @@
   FuncT Func;
 };
 
+struct LambdaModulePass : public PassInfoMixin<LambdaPass> {
+  using FuncT = std::function<PreservedAnalyses(Module &, ModuleAnalysisManager &)>;
+
+  LambdaModulePass(FuncT Func) : Func(std::move(Func)) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
+    return Func(M, AM);
+  }
+
+  FuncT Func;
+};
+
 TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
   FunctionAnalysisManager FAM;
   ModuleAnalysisManager MAM;
@@ -950,4 +962,43 @@
   FPM.addPass(TestSimplifyCFGWrapperPass(InnerFPM));
   FPM.run(*F, FAM);
 }
+
+TEST_F(PassManagerTest, AddPassBefore) {
+  ModuleAnalysisManager MAM;
+  int ModuleAnalysisRuns = 0;
+  PassInstrumentationCallbacks PIC;
+  MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
+  MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
+
+  ModulePassManager MPM1;
+
+  int TestModulePassRunCount1 = 0;
+  int CustomModulePassRunCount1 = 0;
+  MPM1.addPass(TestModulePass(TestModulePassRunCount1));
+  MPM1.addPass(LambdaModulePass([&](Module &, ModuleAnalysisManager &){
+    EXPECT_EQ(1, TestModulePassRunCount1);
+    CustomModulePassRunCount1++;
+    return PreservedAnalyses::all();
+  }));
+
+  MPM1.run(*M, MAM);
+  EXPECT_EQ(1, TestModulePassRunCount1);
+  EXPECT_EQ(1, CustomModulePassRunCount1);
+
+  ModulePassManager MPM2;
+
+  int TestModulePassRunCount2 = 0;
+  int CustomModulePassRunCount2 = 0;
+  MPM2.addPass(TestModulePass(TestModulePassRunCount2));
+  MPM2.addPassBefore(LambdaModulePass([&](Module &, ModuleAnalysisManager &){
+    EXPECT_EQ(0, TestModulePassRunCount2);
+    CustomModulePassRunCount2++;
+    return PreservedAnalyses::all();
+  }), "{anonymous}::TestModulePass");
+
+  MPM2.run(*M, MAM);
+  EXPECT_EQ(1, TestModulePassRunCount2);
+  EXPECT_EQ(1, CustomModulePassRunCount2);
+}
+
 }
Index: llvm/include/llvm/IR/PassManager.h
===================================================================
--- llvm/include/llvm/IR/PassManager.h
+++ llvm/include/llvm/IR/PassManager.h
@@ -559,6 +559,17 @@
       Passes.emplace_back(std::move(P));
   }
 
+  template <typename PassT>
+  std::enable_if_t<!std::is_same<PassT, PassManager>::value>
+  addPassBefore(PassT Pass, StringRef Other) {
+    using PassModelT =
+        detail::PassModel<IRUnitT, PassT, PreservedAnalyses, AnalysisManagerT,
+                          ExtraArgTs...>;
+    auto It = std::find_if(Passes.begin(), Passes.end(),
+      [&](const auto& Pass) { return Pass->name() == Other; });
+    Passes.emplace(It, new PassModelT(std::move(Pass)));
+  }
+
   /// Returns if the pass manager contains any passes.
   bool isEmpty() const { return Passes.empty(); }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D102909.346970.patch
Type: text/x-patch
Size: 2903 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210521/82867cb2/attachment.bin>


More information about the llvm-commits mailing list