[llvm] 6975ab7 - [Clang] Reimplement time tracing of NewPassManager by PassInstrumentation framework

Junduo Dong via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 11 07:56:35 PDT 2022


Author: Junduo Dong
Date: 2022-09-11T05:42:55-07:00
New Revision: 6975ab71260c79ddc7a616814678913e67ea417c

URL: https://github.com/llvm/llvm-project/commit/6975ab71260c79ddc7a616814678913e67ea417c
DIFF: https://github.com/llvm/llvm-project/commit/6975ab71260c79ddc7a616814678913e67ea417c.diff

LOG: [Clang] Reimplement time tracing of NewPassManager by PassInstrumentation framework

The previous implementation of time tracing in NewPassManager is direct but messive.

The key codes are like the demo below:
```
  /// Runs the function pass across every function in the module.
  PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
                        LazyCallGraph &CG, CGSCCUpdateResult &UR) {
      /// ...
      PreservedAnalyses PassPA;
      {
        TimeTraceScope TimeScope(Pass.name());
        PassPA = Pass.run(F, FAM);
      }
      /// ...
 }
```

It can be bothered to judge where should we add the tracing codes by hands.

With the PassInstrumentation framework, we can easily add `Before/After` callback
functions to add time tracing codes.

Differential Revision: https://reviews.llvm.org/D131960

Added: 
    

Modified: 
    llvm/include/llvm/IR/PassInstrumentation.h
    llvm/include/llvm/IR/PassManager.h
    llvm/include/llvm/Passes/StandardInstrumentations.h
    llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
    llvm/lib/Analysis/CGSCCPassManager.cpp
    llvm/lib/IR/PassManager.cpp
    llvm/lib/Passes/StandardInstrumentations.cpp
    llvm/lib/Transforms/Scalar/LoopPassManager.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h
index 27dd075bbdb25..519a5e46b4373 100644
--- a/llvm/include/llvm/IR/PassInstrumentation.h
+++ b/llvm/include/llvm/IR/PassInstrumentation.h
@@ -107,13 +107,21 @@ class PassInstrumentationCallbacks {
     BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
   }
 
-  template <typename CallableT> void registerAfterPassCallback(CallableT C) {
-    AfterPassCallbacks.emplace_back(std::move(C));
+  template <typename CallableT>
+  void registerAfterPassCallback(CallableT C, bool ToFront = false) {
+    if (ToFront)
+      AfterPassCallbacks.insert(AfterPassCallbacks.begin(), std::move(C));
+    else
+      AfterPassCallbacks.emplace_back(std::move(C));
   }
 
   template <typename CallableT>
-  void registerAfterPassInvalidatedCallback(CallableT C) {
-    AfterPassInvalidatedCallbacks.emplace_back(std::move(C));
+  void registerAfterPassInvalidatedCallback(CallableT C, bool ToFront = false) {
+    if (ToFront)
+      AfterPassInvalidatedCallbacks.insert(
+          AfterPassInvalidatedCallbacks.begin(), std::move(C));
+    else
+      AfterPassInvalidatedCallbacks.emplace_back(std::move(C));
   }
 
   template <typename CallableT>
@@ -122,8 +130,12 @@ class PassInstrumentationCallbacks {
   }
 
   template <typename CallableT>
-  void registerAfterAnalysisCallback(CallableT C) {
-    AfterAnalysisCallbacks.emplace_back(std::move(C));
+  void registerAfterAnalysisCallback(CallableT C, bool ToFront = false) {
+    if (ToFront)
+      AfterAnalysisCallbacks.insert(AfterAnalysisCallbacks.begin(),
+                                    std::move(C));
+    else
+      AfterAnalysisCallbacks.emplace_back(std::move(C));
   }
 
   template <typename CallableT>

diff  --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index fa6be6a2dfb9a..21a0af64da4e2 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -514,11 +514,7 @@ class PassManager : public PassInfoMixin<
       if (!PI.runBeforePass<IRUnitT>(*Pass, IR))
         continue;
 
-      PreservedAnalyses PassPA;
-      {
-        TimeTraceScope TimeScope(Pass->name(), IR.getName());
-        PassPA = Pass->run(IR, AM, ExtraArgs...);
-      }
+      PreservedAnalyses PassPA = Pass->run(IR, AM, ExtraArgs...);
 
       // Call onto PassInstrumentation's AfterPass callbacks immediately after
       // running the pass.

diff  --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index c9c1ca17b237b..166acc6252ca2 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -23,6 +23,7 @@
 #include "llvm/IR/PassTimingInfo.h"
 #include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Transforms/IPO/SampleProfileProbe.h"
 
 #include <string>
@@ -405,6 +406,24 @@ class VerifyInstrumentation {
   void registerCallbacks(PassInstrumentationCallbacks &PIC);
 };
 
+/// This class implements --time-trace functionality for new pass manager.
+/// It provides the pass-instrumentation callbacks that measure the pass
+/// execution time. They collect time tracing info by TimeProfiler.
+class TimeProfilingPassesHandler {
+public:
+  TimeProfilingPassesHandler();
+  // We intend this to be unique per-compilation, thus no copies.
+  TimeProfilingPassesHandler(const TimeProfilingPassesHandler &) = delete;
+  void operator=(const TimeProfilingPassesHandler &) = delete;
+
+  void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+  // Implementation of pass instrumentation callbacks.
+  void runBeforePass(StringRef PassID, Any IR);
+  void runAfterPass();
+};
+
 // Class that holds transitions between basic blocks.  The transitions
 // are contained in a map of values to names of basic blocks.
 class DCData {
@@ -505,6 +524,7 @@ class StandardInstrumentations {
   PrintIRInstrumentation PrintIR;
   PrintPassInstrumentation PrintPass;
   TimePassesHandler TimePasses;
+  TimeProfilingPassesHandler TimeProfilingPasses;
   OptNoneInstrumentation OptNone;
   OptBisectInstrumentation OptBisect;
   PreservedCFGCheckerInstrumentation PreservedCFGChecker;

diff  --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index 1df510474ca7f..3cdd68ad9acb8 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -392,11 +392,7 @@ Optional<PreservedAnalyses> LoopPassManager::runSinglePass(
   if (!PI.runBeforePass<Loop>(*Pass, L))
     return None;
 
-  PreservedAnalyses PA;
-  {
-    TimeTraceScope TimeScope(Pass->name(), IR.getName());
-    PA = Pass->run(IR, AM, AR, U);
-  }
+  PreservedAnalyses PA = Pass->run(IR, AM, AR, U);
 
   // do not pass deleted Loop into the instrumentation
   if (U.skipCurrentLoop())

diff  --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp
index b2e7422bbf8bf..7a802fe9fe020 100644
--- a/llvm/lib/Analysis/CGSCCPassManager.cpp
+++ b/llvm/lib/Analysis/CGSCCPassManager.cpp
@@ -84,11 +84,7 @@ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &,
     if (!PI.runBeforePass(*Pass, *C))
       continue;
 
-    PreservedAnalyses PassPA;
-    {
-      TimeTraceScope TimeScope(Pass->name());
-      PassPA = Pass->run(*C, AM, G, UR);
-    }
+    PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR);
 
     if (UR.InvalidatedSCCs.count(C))
       PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
@@ -277,11 +273,7 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
           if (!PI.runBeforePass<LazyCallGraph::SCC>(*Pass, *C))
             continue;
 
-          PreservedAnalyses PassPA;
-          {
-            TimeTraceScope TimeScope(Pass->name());
-            PassPA = Pass->run(*C, CGAM, CG, UR);
-          }
+          PreservedAnalyses PassPA = Pass->run(*C, CGAM, CG, UR);
 
           if (UR.InvalidatedSCCs.count(C))
             PI.runAfterPassInvalidated<LazyCallGraph::SCC>(*Pass, PassPA);
@@ -548,12 +540,7 @@ PreservedAnalyses CGSCCToFunctionPassAdaptor::run(LazyCallGraph::SCC &C,
     if (!PI.runBeforePass<Function>(*Pass, F))
       continue;
 
-    PreservedAnalyses PassPA;
-    {
-      TimeTraceScope TimeScope(Pass->name());
-      PassPA = Pass->run(F, FAM);
-    }
-
+    PreservedAnalyses PassPA = Pass->run(F, FAM);
     PI.runAfterPass<Function>(*Pass, F, PassPA);
 
     // We know that the function pass couldn't have invalidated any other

diff  --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp
index 3025c3853d5fe..97698990434a6 100644
--- a/llvm/lib/IR/PassManager.cpp
+++ b/llvm/lib/IR/PassManager.cpp
@@ -121,12 +121,7 @@ PreservedAnalyses ModuleToFunctionPassAdaptor::run(Module &M,
     if (!PI.runBeforePass<Function>(*Pass, F))
       continue;
 
-    PreservedAnalyses PassPA;
-    {
-      TimeTraceScope TimeScope(Pass->name(), F.getName());
-      PassPA = Pass->run(F, FAM);
-    }
-
+    PreservedAnalyses PassPA = Pass->run(F, FAM);
     PI.runAfterPass(*Pass, F, PassPA);
 
     // We know that the function pass couldn't have invalidated any other

diff  --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 1ac557d975cec..d88333a307682 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -1144,6 +1144,34 @@ void InLineChangePrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) {
     TextChangeReporter<IRDataT<EmptyData>>::registerRequiredCallbacks(PIC);
 }
 
+TimeProfilingPassesHandler::TimeProfilingPassesHandler() {}
+
+void TimeProfilingPassesHandler::registerCallbacks(
+    PassInstrumentationCallbacks &PIC) {
+  if (!getTimeTraceProfilerInstance())
+    return;
+  PIC.registerBeforeNonSkippedPassCallback(
+      [this](StringRef P, Any IR) { this->runBeforePass(P, IR); });
+  PIC.registerAfterPassCallback(
+      [this](StringRef P, Any IR, const PreservedAnalyses &) {
+        this->runAfterPass();
+      },
+      true);
+  PIC.registerAfterPassInvalidatedCallback(
+      [this](StringRef P, const PreservedAnalyses &) { this->runAfterPass(); },
+      true);
+  PIC.registerBeforeAnalysisCallback(
+      [this](StringRef P, Any IR) { this->runBeforePass(P, IR); });
+  PIC.registerAfterAnalysisCallback(
+      [this](StringRef P, Any IR) { this->runAfterPass(); }, true);
+}
+
+void TimeProfilingPassesHandler::runBeforePass(StringRef PassID, Any IR) {
+  timeTraceProfilerBegin(PassID, getIRName(IR));
+}
+
+void TimeProfilingPassesHandler::runAfterPass() { timeTraceProfilerEnd(); }
+
 namespace {
 
 class DisplayNode;
@@ -2061,6 +2089,13 @@ void StandardInstrumentations::registerCallbacks(
   PrintChangedDiff.registerCallbacks(PIC);
   WebsiteChangeReporter.registerCallbacks(PIC);
   PrintCrashIR.registerCallbacks(PIC);
+  // TimeProfiling records the pass running time cost.
+  // Its 'BeforePassCallback' can be appended at the tail of all the
+  // BeforeCallbacks by calling `registerCallbacks` in the end.
+  // Its 'AfterPassCallback' is put at the front of all the
+  // AfterCallbacks by its `registerCallbacks`. This is necessary
+  // to ensure that other callbacks are not included in the timings.
+  TimeProfilingPasses.registerCallbacks(PIC);
 }
 
 template class ChangeReporter<std::string>;

diff  --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
index d20d275ea60c4..b30e45aa5b7b1 100644
--- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
@@ -291,11 +291,7 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
     if (!PI.runBeforePass<Loop>(*Pass, *L))
       continue;
 
-    PreservedAnalyses PassPA;
-    {
-      TimeTraceScope TimeScope(Pass->name());
-      PassPA = Pass->run(*L, LAM, LAR, Updater);
-    }
+    PreservedAnalyses PassPA = Pass->run(*L, LAM, LAR, Updater);
 
     // Do not pass deleted Loop into the instrumentation.
     if (Updater.skipCurrentLoop())


        


More information about the llvm-commits mailing list