Skip to content

Commit 864a53b

Browse files
authored
Reapply "Use global TimerGroups for both new pass manager and old pass manager timers" (#131173) (#131217)
This reverts commit 31ebe66. The reason for the test failure is likely due to `Name2PairMap::getTimerGroup(...)` not holding a lock.
1 parent d0c8695 commit 864a53b

File tree

6 files changed

+49
-36
lines changed

6 files changed

+49
-36
lines changed

clang/test/Misc/time-passes.c

-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@
1919
// NPM: InstCombinePass{{$}}
2020
// NPM-NOT: InstCombinePass #
2121
// TIME: Total{{$}}
22-
// NPM: Pass execution timing report
2322

2423
int foo(int x, int y) { return x + y; }

llvm/include/llvm/IR/PassTimingInfo.h

+11-7
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,18 @@ Timer *getPassTimer(Pass *);
3939
/// This class implements -time-passes functionality for new pass manager.
4040
/// It provides the pass-instrumentation callbacks that measure the pass
4141
/// execution time. They collect timing info into individual timers as
42-
/// passes are being run. At the end of its life-time it prints the resulting
43-
/// timing report.
42+
/// passes are being run.
4443
class TimePassesHandler {
4544
/// Value of this type is capable of uniquely identifying pass invocations.
4645
/// It is a pair of string Pass-Identifier (which for now is common
4746
/// to all the instance of a given pass) + sequential invocation counter.
4847
using PassInvocationID = std::pair<StringRef, unsigned>;
4948

5049
/// Groups of timers for passes and analyses.
51-
TimerGroup PassTG;
52-
TimerGroup AnalysisTG;
50+
TimerGroup &PassTG =
51+
NamedRegionTimer::getNamedTimerGroup(PassGroupName, PassGroupDesc);
52+
TimerGroup &AnalysisTG = NamedRegionTimer::getNamedTimerGroup(
53+
AnalysisGroupName, AnalysisGroupDesc);
5354

5455
using TimerVector = llvm::SmallVector<std::unique_ptr<Timer>, 4>;
5556
/// Map of timers for pass invocations
@@ -71,12 +72,15 @@ class TimePassesHandler {
7172
bool PerRun;
7273

7374
public:
75+
static constexpr StringRef PassGroupName = "pass";
76+
static constexpr StringRef AnalysisGroupName = "analysis";
77+
static constexpr StringRef PassGroupDesc = "Pass execution timing report";
78+
static constexpr StringRef AnalysisGroupDesc =
79+
"Analysis execution timing report";
80+
7481
TimePassesHandler();
7582
TimePassesHandler(bool Enabled, bool PerRun = false);
7683

77-
/// Destructor handles the print action if it has not been handled before.
78-
~TimePassesHandler() { print(); }
79-
8084
/// Prints out timing information and then resets the timers.
8185
void print();
8286

llvm/include/llvm/Support/Timer.h

+5
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ struct NamedRegionTimer : public TimeRegion {
169169
explicit NamedRegionTimer(StringRef Name, StringRef Description,
170170
StringRef GroupName,
171171
StringRef GroupDescription, bool Enabled = true);
172+
173+
// Create or get a TimerGroup stored in the same global map owned by
174+
// NamedRegionTimer.
175+
static TimerGroup &getNamedTimerGroup(StringRef GroupName,
176+
StringRef GroupDescription);
172177
};
173178

174179
/// The TimerGroup class is used to group together related timers into a single

llvm/lib/IR/PassTimingInfo.cpp

+9-21
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,9 @@ class PassTimingInfo {
6363
private:
6464
StringMap<unsigned> PassIDCountMap; ///< Map that counts instances of passes
6565
DenseMap<PassInstanceID, std::unique_ptr<Timer>> TimingData; ///< timers for pass instances
66-
TimerGroup TG;
66+
TimerGroup *PassTG = nullptr;
6767

6868
public:
69-
/// Default constructor for yet-inactive timeinfo.
70-
/// Use \p init() to activate it.
71-
PassTimingInfo();
72-
73-
/// Print out timing information and release timers.
74-
~PassTimingInfo();
75-
7669
/// Initializes the static \p TheTimeInfo member to a non-null value when
7770
/// -time-passes is enabled. Leaves it null otherwise.
7871
///
@@ -94,14 +87,6 @@ class PassTimingInfo {
9487

9588
static ManagedStatic<sys::SmartMutex<true>> TimingInfoMutex;
9689

97-
PassTimingInfo::PassTimingInfo() : TG("pass", "Pass execution timing report") {}
98-
99-
PassTimingInfo::~PassTimingInfo() {
100-
// Deleting the timers accumulates their info into the TG member.
101-
// Then TG member is (implicitly) deleted, actually printing the report.
102-
TimingData.clear();
103-
}
104-
10590
void PassTimingInfo::init() {
10691
if (TheTimeInfo || !TimePassesIsEnabled)
10792
return;
@@ -110,12 +95,16 @@ void PassTimingInfo::init() {
11095
// This guarantees that the object will be constructed after static globals,
11196
// thus it will be destroyed before them.
11297
static ManagedStatic<PassTimingInfo> TTI;
98+
if (!TTI->PassTG)
99+
TTI->PassTG = &NamedRegionTimer::getNamedTimerGroup(
100+
TimePassesHandler::PassGroupName, TimePassesHandler::PassGroupDesc);
113101
TheTimeInfo = &*TTI;
114102
}
115103

116104
/// Prints out timing information and then resets the timers.
117105
void PassTimingInfo::print(raw_ostream *OutStream) {
118-
TG.print(OutStream ? *OutStream : *CreateInfoOutputFile(), true);
106+
assert(PassTG && "PassTG is null, did you call PassTimingInfo::Init()?");
107+
PassTG->print(OutStream ? *OutStream : *CreateInfoOutputFile(), true);
119108
}
120109

121110
Timer *PassTimingInfo::newPassTimer(StringRef PassID, StringRef PassDesc) {
@@ -124,7 +113,8 @@ Timer *PassTimingInfo::newPassTimer(StringRef PassID, StringRef PassDesc) {
124113
// Appending description with a pass-instance number for all but the first one
125114
std::string PassDescNumbered =
126115
num <= 1 ? PassDesc.str() : formatv("{0} #{1}", PassDesc, num).str();
127-
return new Timer(PassID, PassDescNumbered, TG);
116+
assert(PassTG && "PassTG is null, did you call PassTimingInfo::Init()?");
117+
return new Timer(PassID, PassDescNumbered, *PassTG);
128118
}
129119

130120
Timer *PassTimingInfo::getPassTimer(Pass *P, PassInstanceID Pass) {
@@ -193,9 +183,7 @@ Timer &TimePassesHandler::getPassTimer(StringRef PassID, bool IsPass) {
193183
}
194184

195185
TimePassesHandler::TimePassesHandler(bool Enabled, bool PerRun)
196-
: PassTG("pass", "Pass execution timing report"),
197-
AnalysisTG("analysis", "Analysis execution timing report"),
198-
Enabled(Enabled), PerRun(PerRun) {}
186+
: Enabled(Enabled), PerRun(PerRun) {}
199187

200188
TimePassesHandler::TimePassesHandler()
201189
: TimePassesHandler(TimePassesIsEnabled, TimePassesPerRun) {}

llvm/lib/Support/Timer.cpp

+22-5
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,28 @@ class Name2PairMap {
222222
StringRef GroupDescription) {
223223
sys::SmartScopedLock<true> L(timerLock());
224224

225-
std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
226-
227-
if (!GroupEntry.first)
228-
GroupEntry.first = new TimerGroup(GroupName, GroupDescription);
229-
225+
std::pair<TimerGroup *, Name2TimerMap> &GroupEntry =
226+
getGroupEntry(GroupName, GroupDescription);
230227
Timer &T = GroupEntry.second[Name];
231228
if (!T.isInitialized())
232229
T.init(Name, Description, *GroupEntry.first);
233230
return T;
234231
}
232+
233+
TimerGroup &getTimerGroup(StringRef GroupName, StringRef GroupDescription) {
234+
sys::SmartScopedLock<true> L(timerLock());
235+
return *getGroupEntry(GroupName, GroupDescription).first;
236+
}
237+
238+
private:
239+
std::pair<TimerGroup *, Name2TimerMap> &
240+
getGroupEntry(StringRef GroupName, StringRef GroupDescription) {
241+
std::pair<TimerGroup *, Name2TimerMap> &GroupEntry = Map[GroupName];
242+
if (!GroupEntry.first)
243+
GroupEntry.first = new TimerGroup(GroupName, GroupDescription);
244+
245+
return GroupEntry;
246+
}
235247
};
236248

237249
}
@@ -244,6 +256,11 @@ NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef Description,
244256
: &namedGroupedTimers().get(Name, Description, GroupName,
245257
GroupDescription)) {}
246258

259+
TimerGroup &NamedRegionTimer::getNamedTimerGroup(StringRef GroupName,
260+
StringRef GroupDescription) {
261+
return namedGroupedTimers().getTimerGroup(GroupName, GroupDescription);
262+
}
263+
247264
//===----------------------------------------------------------------------===//
248265
// TimerGroup Implementation
249266
//===----------------------------------------------------------------------===//

llvm/unittests/IR/TimePassesTest.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ TEST(TimePassesTest, CustomOut) {
161161
PI.runBeforePass(Pass2, M);
162162
PI.runAfterPass(Pass2, M, PreservedAnalyses::all());
163163

164-
// Generate report by deleting the handler.
165-
TimePasses.reset();
164+
// Clear and generate report again.
165+
TimePasses->print();
166166

167167
// There should be Pass2 in this report and no Pass1.
168168
EXPECT_FALSE(TimePassesStr.str().empty());

0 commit comments

Comments
 (0)