[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