@@ -94,8 +94,7 @@ class PassTimingInfo {
94
94
95
95
static ManagedStatic<sys::SmartMutex<true >> TimingInfoMutex;
96
96
97
- PassTimingInfo::PassTimingInfo ()
98
- : TG(" pass" , " ... Pass execution timing report ..." ) {}
97
+ PassTimingInfo::PassTimingInfo () : TG(" pass" , " Pass execution timing report" ) {}
99
98
100
99
PassTimingInfo::~PassTimingInfo () {
101
100
// Deleting the timers accumulates their info into the TG member.
@@ -170,7 +169,8 @@ void reportAndResetTimings(raw_ostream *OutStream) {
170
169
171
170
// / Returns the timer for the specified pass invocation of \p PassID.
172
171
// / Each time it creates a new timer.
173
- Timer &TimePassesHandler::getPassTimer (StringRef PassID) {
172
+ Timer &TimePassesHandler::getPassTimer (StringRef PassID, bool IsPass) {
173
+ TimerGroup &TG = IsPass ? PassTG : AnalysisTG;
174
174
if (!PerRun) {
175
175
TimerVector &Timers = TimingData[PassID];
176
176
if (Timers.size () == 0 )
@@ -193,8 +193,9 @@ Timer &TimePassesHandler::getPassTimer(StringRef PassID) {
193
193
}
194
194
195
195
TimePassesHandler::TimePassesHandler (bool Enabled, bool PerRun)
196
- : TG(" pass" , " ... Pass execution timing report ..." ), Enabled(Enabled),
197
- PerRun (PerRun) {}
196
+ : PassTG(" pass" , " Pass execution timing report" ),
197
+ AnalysisTG (" analysis" , " Analysis execution timing report" ),
198
+ Enabled(Enabled), PerRun(PerRun) {}
198
199
199
200
TimePassesHandler::TimePassesHandler ()
200
201
: TimePassesHandler(TimePassesIsEnabled, TimePassesPerRun) {}
@@ -206,7 +207,16 @@ void TimePassesHandler::setOutStream(raw_ostream &Out) {
206
207
void TimePassesHandler::print () {
207
208
if (!Enabled)
208
209
return ;
209
- TG.print (OutStream ? *OutStream : *CreateInfoOutputFile (), true );
210
+ std::unique_ptr<raw_ostream> MaybeCreated;
211
+ raw_ostream *OS = OutStream;
212
+ if (OutStream) {
213
+ OS = OutStream;
214
+ } else {
215
+ MaybeCreated = CreateInfoOutputFile ();
216
+ OS = &*MaybeCreated;
217
+ }
218
+ PassTG.print (*OS, true );
219
+ AnalysisTG.print (*OS, true );
210
220
}
211
221
212
222
LLVM_DUMP_METHOD void TimePassesHandler::dump () const {
@@ -233,61 +243,77 @@ LLVM_DUMP_METHOD void TimePassesHandler::dump() const {
233
243
}
234
244
}
235
245
236
- void TimePassesHandler::startTimer (StringRef PassID) {
237
- Timer &MyTimer = getPassTimer (PassID);
238
- TimerStack.push_back (&MyTimer);
239
- if (!MyTimer.isRunning ())
240
- MyTimer.startTimer ();
246
+ static bool shouldIgnorePass (StringRef PassID) {
247
+ return isSpecialPass (PassID,
248
+ {" PassManager" , " PassAdaptor" , " AnalysisManagerProxy" ,
249
+ " ModuleInlinerWrapperPass" , " DevirtSCCRepeatedPass" });
241
250
}
242
251
243
- void TimePassesHandler::stopTimer (StringRef PassID) {
244
- assert (TimerStack.size () > 0 && " empty stack in popTimer" );
245
- Timer *MyTimer = TimerStack.pop_back_val ();
246
- assert (MyTimer && " timer should be present" );
247
- if (MyTimer->isRunning ())
248
- MyTimer->stopTimer ();
252
+ void TimePassesHandler::startPassTimer (StringRef PassID) {
253
+ if (shouldIgnorePass (PassID))
254
+ return ;
255
+ assert (!ActivePassTimer && " should only have one pass timer at a time" );
256
+ Timer &MyTimer = getPassTimer (PassID, /* IsPass*/ true );
257
+ ActivePassTimer = &MyTimer;
258
+ assert (!MyTimer.isRunning ());
259
+ MyTimer.startTimer ();
249
260
}
250
261
251
- void TimePassesHandler::runBeforePass (StringRef PassID) {
252
- if (isSpecialPass (PassID,
253
- {" PassManager" , " PassAdaptor" , " AnalysisManagerProxy" }))
262
+ void TimePassesHandler::stopPassTimer (StringRef PassID) {
263
+ if (shouldIgnorePass (PassID))
254
264
return ;
265
+ assert (ActivePassTimer);
266
+ assert (ActivePassTimer->isRunning ());
267
+ ActivePassTimer->stopTimer ();
268
+ ActivePassTimer = nullptr ;
269
+ }
255
270
256
- startTimer (PassID);
271
+ void TimePassesHandler::startAnalysisTimer (StringRef PassID) {
272
+ // Stop the previous analysis timer to prevent double counting when an
273
+ // analysis requests another analysis.
274
+ if (!AnalysisActiveTimerStack.empty ()) {
275
+ assert (AnalysisActiveTimerStack.back ()->isRunning ());
276
+ AnalysisActiveTimerStack.back ()->stopTimer ();
277
+ }
257
278
258
- LLVM_DEBUG (dbgs () << " after runBeforePass(" << PassID << " )\n " );
259
- LLVM_DEBUG (dump ());
279
+ Timer &MyTimer = getPassTimer (PassID, /* IsPass*/ false );
280
+ AnalysisActiveTimerStack.push_back (&MyTimer);
281
+ if (!MyTimer.isRunning ())
282
+ MyTimer.startTimer ();
260
283
}
261
284
262
- void TimePassesHandler::runAfterPass (StringRef PassID) {
263
- if ( isSpecialPass (PassID,
264
- { " PassManager " , " PassAdaptor " , " AnalysisManagerProxy " }))
265
- return ;
266
-
267
- stopTimer (PassID );
285
+ void TimePassesHandler::stopAnalysisTimer (StringRef PassID) {
286
+ assert (!AnalysisActiveTimerStack. empty () && " empty stack in popTimer " );
287
+ Timer *MyTimer = AnalysisActiveTimerStack. pop_back_val ();
288
+ assert (MyTimer && " timer should be present " ) ;
289
+ if (MyTimer-> isRunning ())
290
+ MyTimer-> stopTimer ();
268
291
269
- LLVM_DEBUG (dbgs () << " after runAfterPass(" << PassID << " )\n " );
270
- LLVM_DEBUG (dump ());
292
+ // Restart the previously stopped timer.
293
+ if (!AnalysisActiveTimerStack.empty ()) {
294
+ assert (!AnalysisActiveTimerStack.back ()->isRunning ());
295
+ AnalysisActiveTimerStack.back ()->startTimer ();
296
+ }
271
297
}
272
298
273
299
void TimePassesHandler::registerCallbacks (PassInstrumentationCallbacks &PIC) {
274
300
if (!Enabled)
275
301
return ;
276
302
277
303
PIC.registerBeforeNonSkippedPassCallback (
278
- [this ](StringRef P, Any) { this ->runBeforePass (P); });
304
+ [this ](StringRef P, Any) { this ->startPassTimer (P); });
279
305
PIC.registerAfterPassCallback (
280
306
[this ](StringRef P, Any, const PreservedAnalyses &) {
281
- this ->runAfterPass (P);
307
+ this ->stopPassTimer (P);
282
308
});
283
309
PIC.registerAfterPassInvalidatedCallback (
284
310
[this ](StringRef P, const PreservedAnalyses &) {
285
- this ->runAfterPass (P);
311
+ this ->stopPassTimer (P);
286
312
});
287
313
PIC.registerBeforeAnalysisCallback (
288
- [this ](StringRef P, Any) { this ->runBeforePass (P); });
314
+ [this ](StringRef P, Any) { this ->startAnalysisTimer (P); });
289
315
PIC.registerAfterAnalysisCallback (
290
- [this ](StringRef P, Any) { this ->runAfterPass (P); });
316
+ [this ](StringRef P, Any) { this ->stopAnalysisTimer (P); });
291
317
}
292
318
293
319
} // namespace llvm
0 commit comments