EnableTiming("time-passes",
cl::desc("Time each pass, printing elapsed time for each on exit"));
-// Create method. If Timing is enabled, this creates and returns a new timing
-// object, otherwise it returns null.
-//
-TimingInfo *TimingInfo::create() {
- return EnableTiming ? new TimingInfo() : 0;
+// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to
+// a non null value (if the -time-passes option is enabled) or it leaves it
+// null. It may be called multiple times.
+void TimingInfo::createTheTimeInfo() {
+ if (!EnableTiming || TheTimeInfo) return;
+
+ // Constructed the first time this is called, iff -time-passes is enabled.
+ // This guarantees that the object will be constructed before static globals,
+ // thus it will be destroyed before them.
+ static TimingInfo TTI;
+ TheTimeInfo = &TTI;
}
void PMDebug::PrintArgumentInformation(const Pass *P) {
// Private ctor, must use 'create' member
TimingInfo() : TG("... Pass execution timing report ...") {}
public:
- // Create method. If Timing is enabled, this creates and returns a new timing
- // object, otherwise it returns null.
- //
- static TimingInfo *create();
-
// TimingDtor - Print out information about timing information
~TimingInfo() {
// Delete all of the timers...
// TimerGroup is deleted next, printing the report.
}
+ // createTheTimeInfo - This method either initializes the TheTimeInfo pointer
+ // to a non null value (if the -time-passes option is enabled) or it leaves it
+ // null. It may be called multiple times.
+ static void createTheTimeInfo();
+
void passStarted(Pass *P) {
if (dynamic_cast<AnalysisResolver*>(P)) return;
std::map<Pass*, Timer>::iterator I = TimingData.find(P);
}
};
+static TimingInfo *TheTimeInfo;
+
//===----------------------------------------------------------------------===//
// Declare the PassManagerTraits which will be specialized...
//
closeBatcher();
CurrentAnalyses.clear();
+ TimingInfo::createTheTimeInfo();
+
// Add any immutable passes to the CurrentAnalyses set...
for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) {
ImmutablePass *IPass = ImmutablePasses[i];
}
// Run the sub pass!
- startPass(P);
+ if (TheTimeInfo) TheTimeInfo->passStarted(P);
bool Changed = runPass(P, M);
- endPass(P);
+ if (TheTimeInfo) TheTimeInfo->passEnded(P);
MadeChanges |= Changed;
// Check for memory leaks by the pass...
}
}
}
+
return MadeChanges;
}
return 0;
}
- // {start/end}Pass - Called when a pass is started, it just propagates
- // information up to the top level PassManagerT object to tell it that a pass
- // has started or ended. This is used to gather timing information about
- // passes.
- //
- void startPass(Pass *P) {
- if (Parent) Parent->startPass(P);
- else PassStarted(P);
- }
- void endPass(Pass *P) {
- if (Parent) Parent->endPass(P);
- else PassEnded(P);
- }
-
// markPassUsed - Inform higher level pass managers (and ourselves)
// that these analyses are being used by this pass. This is used to
// make sure that analyses are not free'd before we have to use
return P->runOnBasicBlock(*M);
}
- // Dummy implementation of PassStarted/PassEnded
- static void PassStarted(Pass *P) {}
- static void PassEnded(Pass *P) {}
-
// getPMName() - Return the name of the unit the PassManager operates on for
// debugging.
const char *getPMName() const { return "BasicBlock"; }
return P->runOnFunction(*F);
}
- // Dummy implementation of PassStarted/PassEnded
- static void PassStarted(Pass *P) {}
- static void PassEnded(Pass *P) {}
-
// getPMName() - Return the name of the unit the PassManager operates on for
// debugging.
const char *getPMName() const { return "Function"; }
const char *getPMName() const { return "Module"; }
virtual const char *getPassName() const { return "Module Pass Manager"; }
- // TimingInformation - This data member maintains timing information for each
- // of the passes that is executed.
- //
- TimingInfo *TimeInfo;
-
- // PassStarted/Ended - This callback is notified any time a pass is started
- // or stops. This is used to collect timing information about the different
- // passes being executed.
- //
- void PassStarted(Pass *P) {
- if (TimeInfo) TimeInfo->passStarted(P);
- }
- void PassEnded(Pass *P) {
- if (TimeInfo) TimeInfo->passEnded(P);
- }
-
// run - Implement the PassManager interface...
bool run(Module &M) {
- TimeInfo = TimingInfo::create();
- bool Result = ((PassManagerT<Module>*)this)->runOnUnit(&M);
- if (TimeInfo) {
- delete TimeInfo;
- TimeInfo = 0;
- }
- return Result;
+ return ((PassManagerT<Module>*)this)->runOnUnit(&M);
}
-
- // PassManagerTraits constructor - Create a timing info object if the user
- // specified timing info should be collected on the command line.
- //
- PassManagerTraits() : TimeInfo(0) {}
};