[llvm] [Pass] Support start/stop in instrumentation (PR #70912)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 2 19:47:18 PST 2024


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/70912

>From 92045a69f4ff83eadbbf6a6226b984c2f5b735e5 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 3 Jan 2024 10:34:33 +0800
Subject: [PATCH] [CodeGen][NewPM] Support start/stop in CodeGen

---
 .../include/llvm/CodeGen/CodeGenPassBuilder.h | 24 ++++++++++++------
 llvm/include/llvm/IR/PassInstrumentation.h    |  6 +++++
 llvm/lib/CodeGen/TargetPassConfig.cpp         | 25 +++++++++----------
 llvm/lib/IR/PassInstrumentation.cpp           |  8 ++++++
 llvm/lib/Passes/PassBuilder.cpp               |  4 ++-
 5 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index 32d6e5f91f7b09..e26d43ab477363 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -171,8 +171,9 @@ template <typename DerivedT> class CodeGenPassBuilder {
   // Function object to maintain state while adding codegen IR passes.
   class AddIRPass {
   public:
-    AddIRPass(ModulePassManager &MPM, bool DebugPM, bool Check = true)
-        : MPM(MPM) {
+    AddIRPass(ModulePassManager &MPM, PassInstrumentationCallbacks &PIC,
+              bool DebugPM, bool Check = true)
+        : MPM(MPM), PIC(PIC) {
       if (Check)
         AddingFunctionPasses = false;
     }
@@ -186,7 +187,8 @@ template <typename DerivedT> class CodeGenPassBuilder {
     operator()(PassT &&Pass) {
       if (AddingFunctionPasses && !*AddingFunctionPasses)
         AddingFunctionPasses = true;
-      FPM.addPass(std::forward<PassT>(Pass));
+      if (PIC.StartStopCallback(PIC.getPassNameForClassName(PassT::name())))
+        FPM.addPass(std::forward<PassT>(Pass));
     }
 
     // Add Module Pass
@@ -196,12 +198,14 @@ template <typename DerivedT> class CodeGenPassBuilder {
     operator()(PassT &&Pass) {
       assert((!AddingFunctionPasses || !*AddingFunctionPasses) &&
              "could not add module pass after adding function pass");
-      MPM.addPass(std::forward<PassT>(Pass));
+      if (PIC.StartStopCallback(PIC.getPassNameForClassName(PassT::name())))
+        MPM.addPass(std::forward<PassT>(Pass));
     }
 
   private:
     ModulePassManager &MPM;
     FunctionPassManager FPM;
+    PassInstrumentationCallbacks &PIC;
     // The codegen IR pipeline are mostly function passes with the exceptions of
     // a few loop and module passes. `AddingFunctionPasses` make sures that
     // we could only add module passes at the beginning of the pipeline. Once
@@ -215,7 +219,9 @@ template <typename DerivedT> class CodeGenPassBuilder {
   // Function object to maintain state while adding codegen machine passes.
   class AddMachinePass {
   public:
-    AddMachinePass(MachineFunctionPassManager &PM) : PM(PM) {}
+    AddMachinePass(MachineFunctionPassManager &PM,
+                   PassInstrumentationCallbacks &PIC)
+        : PM(PM), PIC(PIC) {}
 
     template <typename PassT> void operator()(PassT &&Pass) {
       static_assert(
@@ -224,7 +230,8 @@ template <typename DerivedT> class CodeGenPassBuilder {
       for (auto &C : BeforeCallbacks)
         if (!C(&PassT::Key))
           return;
-      PM.addPass(std::forward<PassT>(Pass));
+      if (PIC.StartStopCallback(PIC.getPassNameForClassName(PassT::name())))
+        PM.addPass(std::forward<PassT>(Pass));
       for (auto &C : AfterCallbacks)
         C(&PassT::Key);
     }
@@ -246,6 +253,7 @@ template <typename DerivedT> class CodeGenPassBuilder {
 
   private:
     MachineFunctionPassManager &PM;
+    PassInstrumentationCallbacks &PIC;
     SmallVector<llvm::unique_function<bool(AnalysisKey *)>, 4> BeforeCallbacks;
     SmallVector<llvm::unique_function<void(AnalysisKey *)>, 4> AfterCallbacks;
   };
@@ -482,12 +490,12 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
     ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
     raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
     CodeGenFileType FileType) const {
-  AddIRPass addIRPass(MPM, Opt.DebugPM);
+  AddIRPass addIRPass(MPM, *PIC, Opt.DebugPM);
   // `ProfileSummaryInfo` is always valid.
   addIRPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
   addISelPasses(addIRPass);
 
-  AddMachinePass addPass(MFPM);
+  AddMachinePass addPass(MFPM, *PIC);
   if (auto Err = addCoreISelPasses(addPass))
     return std::move(Err);
 
diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h
index 519a5e46b4373b..ae493c740908d1 100644
--- a/llvm/include/llvm/IR/PassInstrumentation.h
+++ b/llvm/include/llvm/IR/PassInstrumentation.h
@@ -84,6 +84,7 @@ class PassInstrumentationCallbacks {
   using AfterAnalysisFunc = void(StringRef, Any);
   using AnalysisInvalidatedFunc = void(StringRef, Any);
   using AnalysesClearedFunc = void(StringRef);
+  using StartStopFunc = bool(StringRef);
 
 public:
   PassInstrumentationCallbacks() = default;
@@ -152,6 +153,11 @@ class PassInstrumentationCallbacks {
   void addClassToPassName(StringRef ClassName, StringRef PassName);
   /// Get the pass name for a given pass class name.
   StringRef getPassNameForClassName(StringRef ClassName);
+  /// Inverse of getPassNameForClassName
+  StringRef getClassNameForPassName(StringRef PassName);
+
+  /// Helper callback to support options like start-before.
+  llvm::unique_function<StartStopFunc> StartStopCallback;
 
 private:
   friend class PassInstrumentation;
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index faa5466b69e8b3..9ff312b8bd8e88 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -526,17 +526,16 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
       getPassNameAndInstanceNum(StopAfterOpt);
 
   if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&
-      StopAfter.empty())
+      StopAfter.empty()) {
+    PIC.StartStopCallback = [](StringRef) { return true; };
     return;
+  }
+
+  StartBefore = PIC.getClassNameForPassName(StartBefore);
+  StartAfter = PIC.getClassNameForPassName(StartAfter);
+  StopBefore = PIC.getClassNameForPassName(StopBefore);
+  StopAfter = PIC.getClassNameForPassName(StopAfter);
 
-  std::tie(StartBefore, std::ignore) =
-      LLVMTM.getPassNameFromLegacyName(StartBefore);
-  std::tie(StartAfter, std::ignore) =
-      LLVMTM.getPassNameFromLegacyName(StartAfter);
-  std::tie(StopBefore, std::ignore) =
-      LLVMTM.getPassNameFromLegacyName(StopBefore);
-  std::tie(StopAfter, std::ignore) =
-      LLVMTM.getPassNameFromLegacyName(StopAfter);
   if (!StartBefore.empty() && !StartAfter.empty())
     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
                        Twine(StartAfterOptName) + Twine(" specified!"));
@@ -544,11 +543,11 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
                        Twine(StopAfterOptName) + Twine(" specified!"));
 
-  PIC.registerShouldRunOptionalPassCallback(
+  PIC.StartStopCallback =
       [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
        EnableNext = std::optional<bool>(), StartBeforeCount = 0u,
-       StartAfterCount = 0u, StopBeforeCount = 0u,
-       StopAfterCount = 0u](StringRef P, Any) mutable {
+       StartAfterCount = 0u, StopBeforeCount = 0u, StopAfterCount = 0u,
+       &PIC](StringRef P) mutable {
         bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);
         bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);
         bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);
@@ -576,7 +575,7 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
         if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
           EnableCurrent = false;
         return EnableCurrent;
-      });
+      };
 }
 
 void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
diff --git a/llvm/lib/IR/PassInstrumentation.cpp b/llvm/lib/IR/PassInstrumentation.cpp
index 6d5f3acb7a4d35..e64c30132793a4 100644
--- a/llvm/lib/IR/PassInstrumentation.cpp
+++ b/llvm/lib/IR/PassInstrumentation.cpp
@@ -28,6 +28,14 @@ PassInstrumentationCallbacks::getPassNameForClassName(StringRef ClassName) {
   return ClassToPassName[ClassName];
 }
 
+StringRef
+PassInstrumentationCallbacks::getClassNameForPassName(StringRef PassName) {
+  for (const auto &P : ClassToPassName)
+    if (P.second == PassName)
+      return P.first();
+  return StringRef();
+}
+
 AnalysisKey PassInstrumentationAnalysis::Key;
 
 bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) {
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f94bd422c6b592..494ddd54da400d 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -87,6 +87,7 @@
 #include "llvm/CodeGen/SafeStack.h"
 #include "llvm/CodeGen/SelectOptimize.h"
 #include "llvm/CodeGen/SjLjEHPrepare.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/CodeGen/TypePromotion.h"
 #include "llvm/CodeGen/WasmEHPrepare.h"
 #include "llvm/CodeGen/WinEHPrepare.h"
@@ -406,7 +407,8 @@ AnalysisKey NoOpLoopAnalysis::Key;
 /// We currently only use this for --print-before/after.
 bool shouldPopulateClassToPassNames() {
   return PrintPipelinePasses || !printBeforePasses().empty() ||
-         !printAfterPasses().empty() || !isFilterPassesEmpty();
+         !printAfterPasses().empty() || !isFilterPassesEmpty() ||
+         TargetPassConfig::hasLimitedCodeGenPipeline();
 }
 
 // A pass for testing -print-on-crash.



More information about the llvm-commits mailing list