//===----------------------------------------------------------------------===//
// CGPassManager
//
-/// CGPassManager manages FPPassManagers and CalLGraphSCCPasses.
+/// CGPassManager manages FPPassManagers and CallGraphSCCPasses.
namespace {
return "CallGraph Pass Manager";
}
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
// Print passes managed by this manager
void dumpPassStructure(unsigned Offset) {
errs().indent(Offset*2) << "Call Graph SCC Pass Manager\n";
bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC,
CallGraph &CG, bool &CallGraphUpToDate) {
bool Changed = false;
- if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass*>(P)) {
+ PMDataManager *PM = P->getAsPMDataManager();
+
+ if (PM == 0) {
+ CallGraphSCCPass *CGSP = (CallGraphSCCPass*)P;
if (!CallGraphUpToDate) {
RefreshCallGraph(CurSCC, CG, false);
CallGraphUpToDate = true;
}
- StartPassTimer(CGSP);
+ Timer *T = StartPassTimer(CGSP);
Changed = CGSP->runOnSCC(CurSCC);
- StopPassTimer(CGSP);
+ StopPassTimer(CGSP, T);
// After the CGSCCPass is done, when assertions are enabled, use
// RefreshCallGraph to verify that the callgraph was correctly updated.
return Changed;
}
- StartPassTimer(P);
- FPPassManager *FPP = dynamic_cast<FPPassManager *>(P);
- assert(FPP && "Invalid CGPassManager member");
+
+ assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
+ "Invalid CGPassManager member");
+ FPPassManager *FPP = (FPPassManager*)P;
// Run pass P on all functions in the current SCC.
for (unsigned i = 0, e = CurSCC.size(); i != e; ++i) {
if (Function *F = CurSCC[i]->getFunction()) {
dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName());
+ Timer *T = StartPassTimer(FPP);
Changed |= FPP->runOnFunction(*F);
+ StopPassTimer(FPP, T);
}
}
- StopPassTimer(P);
// The function pass(es) modified the IR, they may have clobbered the
// callgraph.
if (Changed && CallGraphUpToDate) {
- DEBUG(errs() << "CGSCCPASSMGR: Pass Dirtied SCC: "
+ DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: "
<< P->getPassName() << '\n');
CallGraphUpToDate = false;
}
CallGraph &CG, bool CheckingMode) {
DenseMap<Value*, CallGraphNode*> CallSites;
- DEBUG(errs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
+ DEBUG(dbgs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
<< " nodes:\n";
for (unsigned i = 0, e = CurSCC.size(); i != e; ++i)
CurSCC[i]->dump();
// CGN with those actually in the function.
// Get the set of call sites currently in the function.
- for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ){
+ for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ) {
// If this call site is null, then the function pass deleted the call
// entirely and the WeakVH nulled it out.
if (I->first == 0 ||
assert(!CheckingMode &&
"CallGraphSCCPass did not update the CallGraph correctly!");
- // Just remove the edge from the set of callees.
+ // Just remove the edge from the set of callees, keep track of whether
+ // I points to the last element of the vector.
+ bool WasLast = I + 1 == E;
CGN->removeCallEdge(I);
+
+ // If I pointed to the last element of the vector, we have to bail out:
+ // iterator checking rejects comparisons of the resultant pointer with
+ // end.
+ if (WasLast)
+ break;
E = CGN->end();
continue;
}
}
DEBUG(if (MadeChange) {
- errs() << "CGSCCPASSMGR: Refreshed SCC is now:\n";
+ dbgs() << "CGSCCPASSMGR: Refreshed SCC is now:\n";
for (unsigned i = 0, e = CurSCC.size(); i != e; ++i)
CurSCC[i]->dump();
} else {
- errs() << "CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
+ dbgs() << "CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
}
);
}
PassNo != e; ++PassNo) {
Pass *P = getContainedPass(PassNo);
- dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, "");
+ // If we're in -debug-pass=Executions mode, construct the SCC node list,
+ // otherwise avoid constructing this string as it is expensive.
+ if (isPassDebuggingExecutionsOrMore()) {
+ std::string Functions;
+#ifndef NDEBUG
+ raw_string_ostream OS(Functions);
+ for (unsigned i = 0, e = CurSCC.size(); i != e; ++i) {
+ if (i) OS << ", ";
+ CurSCC[i]->print(OS);
+ }
+ OS.flush();
+#endif
+ dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, Functions);
+ }
dumpRequiredSet(P);
initializeAnalysisImpl(P);
/// Initialize CG
bool CGPassManager::doInitialization(CallGraph &CG) {
bool Changed = false;
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) {
- Changed |= CGSP->doInitialization(CG);
+ for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
+ if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
+ assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
+ "Invalid CGPassManager member");
+ Changed |= ((FPPassManager*)PM)->doInitialization(CG.getModule());
} else {
- FPPassManager *FP = dynamic_cast<FPPassManager *>(P);
- assert (FP && "Invalid CGPassManager member");
- Changed |= FP->doInitialization(CG.getModule());
+ Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG);
}
}
return Changed;
/// Finalize CG
bool CGPassManager::doFinalization(CallGraph &CG) {
bool Changed = false;
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) {
- Changed |= CGSP->doFinalization(CG);
+ for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
+ if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
+ assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
+ "Invalid CGPassManager member");
+ Changed |= ((FPPassManager*)PM)->doFinalization(CG.getModule());
} else {
- FPPassManager *FP = dynamic_cast<FPPassManager *>(P);
- assert (FP && "Invalid CGPassManager member");
- Changed |= FP->doFinalization(CG.getModule());
+ Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG);
}
}
return Changed;
PMS.top()->getPassManagerType() > PMT_CallGraphPassManager)
PMS.pop();
- assert (!PMS.empty() && "Unable to handle Call Graph Pass");
- CGPassManager *CGP = dynamic_cast<CGPassManager *>(PMS.top());
-
- // Create new Call Graph SCC Pass Manager if it does not exist.
- if (!CGP) {
-
- assert (!PMS.empty() && "Unable to create Call Graph Pass Manager");
+ assert(!PMS.empty() && "Unable to handle Call Graph Pass");
+ CGPassManager *CGP;
+
+ if (PMS.top()->getPassManagerType() == PMT_CallGraphPassManager)
+ CGP = (CGPassManager*)PMS.top();
+ else {
+ // Create new Call Graph SCC Pass Manager if it does not exist.
+ assert(!PMS.empty() && "Unable to create Call Graph Pass Manager");
PMDataManager *PMD = PMS.top();
// [1] Create new Call Graph Pass Manager
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
- Pass *P = dynamic_cast<Pass *>(CGP);
+ Pass *P = CGP;
TPM->schedulePass(P);
// [4] Push new manager into PMS