bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC, CallGraph &CG, bool &CallGraphUpToDate, bool &DevirtualizedCall) { bool Changed = false; PMDataManager *PM = P->getAsPMDataManager(); if (!PM) { CallGraphSCCPass *CGSP = (CallGraphSCCPass*)P; if (!CallGraphUpToDate) { DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false); CallGraphUpToDate = true; } { TimeRegion PassTimer(getPassTimer(CGSP)); Changed = CGSP->runOnSCC(CurSCC); } // After the CGSCCPass is done, when assertions are enabled, use // RefreshCallGraph to verify that the callgraph was correctly updated. #ifndef NDEBUG if (Changed) RefreshCallGraph(CurSCC, CG, true); #endif return Changed; } assert(PM->getPassManagerType() == PMT_FunctionPassManager && "Invalid CGPassManager member"); FPPassManager *FPP = (FPPassManager*)P; // Run pass P on all functions in the current SCC. for (CallGraphSCC::iterator I = CurSCC.begin(), E = CurSCC.end(); I != E; ++I) { if (Function *F = (*I)->getFunction()) { dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName()); { TimeRegion PassTimer(getPassTimer(FPP)); Changed |= FPP->runOnFunction(*F); } F->getContext().yield(); } } // The function pass(es) modified the IR, they may have clobbered the // callgraph. if (Changed && CallGraphUpToDate) { DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: " << P->getPassName() << '\n'); CallGraphUpToDate = false; } return Changed; }
/// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. bool CGPassManager::runOnModule(Module &M) { CallGraph &CG = getAnalysis<CallGraph>(); bool Changed = doInitialization(CG); // Walk SCC for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG); I != E; ++I) { // Run all passes on current SCC for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { Pass *P = getContainedPass(Index); AnalysisUsage AnUsage; P->getAnalysisUsage(AnUsage); dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, ""); dumpAnalysisSetInfo("Required", P, AnUsage.getRequiredSet()); initializeAnalysisImpl(P); StartPassTimer(P); if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) Changed |= CGSP->runOnSCC(*I); // TODO : What if CG is changed ? else { FPPassManager *FPP = dynamic_cast<FPPassManager *>(P); assert (FPP && "Invalid CGPassManager member"); // Run pass P on all functions current SCC std::vector<CallGraphNode*> &SCC = *I; for (unsigned i = 0, e = SCC.size(); i != e; ++i) { Function *F = SCC[i]->getFunction(); if (F) { dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getNameStart()); Changed |= FPP->runOnFunction(*F); } } } StopPassTimer(P); if (Changed) dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, ""); dumpAnalysisSetInfo("Preserved", P, AnUsage.getPreservedSet()); verifyPreservedAnalysis(P); removeNotPreservedAnalysis(P); recordAvailableAnalysis(P); removeDeadPasses(P, "", ON_CG_MSG); } } Changed |= doFinalization(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); } else { FPPassManager *FP = dynamic_cast<FPPassManager *>(P); assert (FP && "Invalid CGPassManager member"); Changed |= FP->doFinalization(CG.getModule()); } } return Changed; }
bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC, CallGraph &CG, bool &CallGraphUpToDate, bool &DevirtualizedCall) { bool Changed = false; PMDataManager *PM = P->getAsPMDataManager(); Module &M = CG.getModule(); if (!PM) { CallGraphSCCPass *CGSP = (CallGraphSCCPass *)P; if (!CallGraphUpToDate) { DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false); CallGraphUpToDate = true; } { unsigned InstrCount, SCCCount = 0; bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); TimeRegion PassTimer(getPassTimer(CGSP)); if (EmitICRemark) InstrCount = initSizeRemarkInfo(M); Changed = CGSP->runOnSCC(CurSCC); if (EmitICRemark) { // FIXME: Add getInstructionCount to CallGraphSCC. SCCCount = M.getInstructionCount(); // Is there a difference in the number of instructions in the module? if (SCCCount != InstrCount) { // Yep. Emit a remark and update InstrCount. int64_t Delta = static_cast<int64_t>(SCCCount) - static_cast<int64_t>(InstrCount); emitInstrCountChangedRemark(P, M, Delta, InstrCount); InstrCount = SCCCount; } } } // After the CGSCCPass is done, when assertions are enabled, use // RefreshCallGraph to verify that the callgraph was correctly updated. #ifndef NDEBUG if (Changed) RefreshCallGraph(CurSCC, CG, true); #endif return Changed; } assert(PM->getPassManagerType() == PMT_FunctionPassManager && "Invalid CGPassManager member"); FPPassManager *FPP = (FPPassManager*)P; // Run pass P on all functions in the current SCC. for (CallGraphNode *CGN : CurSCC) { if (Function *F = CGN->getFunction()) { dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName()); { TimeRegion PassTimer(getPassTimer(FPP)); Changed |= FPP->runOnFunction(*F); } F->getContext().yield(); } } // The function pass(es) modified the IR, they may have clobbered the // callgraph. if (Changed && CallGraphUpToDate) { LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: " << P->getPassName() << '\n'); CallGraphUpToDate = false; } return Changed; }