11#include "llvm/ADT/SmallVector.h"
12#include "llvm/Support/Threading.h"
25 PassTiming(TimingScope &timingScope) : rootScope(timingScope) {}
26 PassTiming(std::unique_ptr<TimingManager> tm)
27 : ownedTimingManager(std::move(tm)),
28 ownedTimingScope(ownedTimingManager->getRootScope()),
29 rootScope(ownedTimingScope) {}
42 std::unique_ptr<TimingManager> ownedTimingManager;
43 TimingScope ownedTimingScope;
49 TimingScope &rootScope;
55 void runBeforePipeline(std::optional<OperationName> name,
56 const PipelineParentInfo &parentInfo)
override {
57 auto tid = llvm::get_threadid();
58 auto &activeTimers = activeThreadTimers[tid];
62 TimingScope *parentScope;
63 auto it = parentTimerIndices.find(parentInfo);
64 if (it != parentTimerIndices.end())
65 parentScope = &activeThreadTimers[parentInfo.parentThreadID][it->second];
67 parentScope = &rootScope;
71 const void *timerId = name ? name->getAsOpaquePointer() :
nullptr;
72 activeTimers.push_back(parentScope->
nest(timerId, [name] {
73 return (
"'" + (name ? name->getStringRef() :
"any") +
"' Pipeline").str();
77 void runAfterPipeline(std::optional<OperationName>,
78 const PipelineParentInfo &)
override {
79 auto &activeTimers = activeThreadTimers[llvm::get_threadid()];
80 assert(!activeTimers.empty() &&
"expected active timer");
81 activeTimers.pop_back();
88 void runBeforePass(Pass *pass, Operation *)
override {
89 auto tid = llvm::get_threadid();
90 auto &activeTimers = activeThreadTimers[tid];
91 auto &parentScope = activeTimers.empty() ? rootScope : activeTimers.back();
93 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass)) {
94 parentTimerIndices[{tid, pass}] = activeTimers.size();
97 [adaptor]() { return adaptor->getAdaptorName(); });
98 if (adaptor->getPassManagers().size() <= 1)
100 activeTimers.push_back(std::move(scope));
102 activeTimers.push_back(
104 [pass]() { return std::string(pass->getName()); }));
108 void runAfterPass(Pass *pass, Operation *)
override {
109 auto tid = llvm::get_threadid();
110 if (isa<OpToOpPassAdaptor>(pass))
111 parentTimerIndices.erase({tid, pass});
112 auto &activeTimers = activeThreadTimers[tid];
113 assert(!activeTimers.empty() &&
"expected active timer");
114 activeTimers.pop_back();
117 void runAfterPassFailed(Pass *pass, Operation *op)
override {
118 runAfterPass(pass, op);
125 void runBeforeAnalysis(StringRef name, TypeID
id, Operation *)
override {
126 auto tid = llvm::get_threadid();
127 auto &activeTimers = activeThreadTimers[tid];
128 auto &parentScope = activeTimers.empty() ? rootScope : activeTimers.back();
129 activeTimers.push_back(parentScope.
nest(
130 id.getAsOpaquePointer(), [name] { return
"(A) " + name.str(); }));
133 void runAfterAnalysis(StringRef, TypeID, Operation *)
override {
134 auto &activeTimers = activeThreadTimers[llvm::get_threadid()];
135 assert(!activeTimers.empty() &&
"expected active timer");
136 activeTimers.pop_back();
156 if (!tm->getRootTimer())
164 auto tm = std::make_unique<DefaultTimingManager>();
165 tm->setEnabled(
true);
PassInstrumentation provides several entry points into the pass manager infrastructure.
void enableTiming()
Add an instrumentation to time the execution of passes and the computation of analyses.
void addInstrumentation(std::unique_ptr< PassInstrumentation > pi)
Add the provided instrumentation to the pass manager.
const Pass * getThreadingSiblingOrThis() const
Returns the thread sibling of this pass, or the pass itself it has no sibling.
An RAII-style wrapper around a timer that ensures the timer is properly started and stopped.
TimingScope nest(Args... args)
Create a nested timing scope.
void hide()
Hide the timer in timing reports and directly show its children.
Include the generated interface declarations.
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap