LLVM API Documentation
00001 //===- CallGraphSCCPass.cpp - Pass that operates BU on call graph ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the CallGraphSCCPass class, which is used for passes 00011 // which are implemented as bottom-up traversals on the call graph. Because 00012 // there may be cycles in the call graph, passes of this type operate on the 00013 // call-graph in SCC order: that is, they process function bottom-up, except for 00014 // recursive functions, which they process all at once. 00015 // 00016 //===----------------------------------------------------------------------===// 00017 00018 #include "llvm/CallGraphSCCPass.h" 00019 #include "llvm/Analysis/CallGraph.h" 00020 #include "llvm/ADT/SCCIterator.h" 00021 #include "llvm/PassManagers.h" 00022 #include "llvm/Function.h" 00023 using namespace llvm; 00024 00025 //===----------------------------------------------------------------------===// 00026 // CGPassManager 00027 // 00028 /// CGPassManager manages FPPassManagers and CalLGraphSCCPasses. 00029 00030 namespace { 00031 00032 class CGPassManager : public ModulePass, public PMDataManager { 00033 00034 public: 00035 static char ID; 00036 explicit CGPassManager(int Depth) 00037 : ModulePass(&ID), PMDataManager(Depth) { } 00038 00039 /// run - Execute all of the passes scheduled for execution. Keep track of 00040 /// whether any of the passes modifies the module, and if so, return true. 00041 bool runOnModule(Module &M); 00042 00043 bool doInitialization(CallGraph &CG); 00044 bool doFinalization(CallGraph &CG); 00045 00046 /// Pass Manager itself does not invalidate any analysis info. 00047 void getAnalysisUsage(AnalysisUsage &Info) const { 00048 // CGPassManager walks SCC and it needs CallGraph. 00049 Info.addRequired<CallGraph>(); 00050 Info.setPreservesAll(); 00051 } 00052 00053 virtual const char *getPassName() const { 00054 return "CallGraph Pass Manager"; 00055 } 00056 00057 // Print passes managed by this manager 00058 void dumpPassStructure(unsigned Offset) { 00059 llvm::cerr << std::string(Offset*2, ' ') << "Call Graph SCC Pass Manager\n"; 00060 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 00061 Pass *P = getContainedPass(Index); 00062 P->dumpPassStructure(Offset + 1); 00063 dumpLastUses(P, Offset+1); 00064 } 00065 } 00066 00067 Pass *getContainedPass(unsigned N) { 00068 assert ( N < PassVector.size() && "Pass number out of range!"); 00069 Pass *FP = static_cast<Pass *>(PassVector[N]); 00070 return FP; 00071 } 00072 00073 virtual PassManagerType getPassManagerType() const { 00074 return PMT_CallGraphPassManager; 00075 } 00076 }; 00077 00078 } 00079 00080 char CGPassManager::ID = 0; 00081 /// run - Execute all of the passes scheduled for execution. Keep track of 00082 /// whether any of the passes modifies the module, and if so, return true. 00083 bool CGPassManager::runOnModule(Module &M) { 00084 CallGraph &CG = getAnalysis<CallGraph>(); 00085 bool Changed = doInitialization(CG); 00086 00087 // Walk SCC 00088 for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG); 00089 I != E; ++I) { 00090 00091 // Run all passes on current SCC 00092 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 00093 Pass *P = getContainedPass(Index); 00094 00095 dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, ""); 00096 dumpRequiredSet(P); 00097 00098 initializeAnalysisImpl(P); 00099 00100 StartPassTimer(P); 00101 if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) 00102 Changed |= CGSP->runOnSCC(*I); // TODO : What if CG is changed ? 00103 else { 00104 FPPassManager *FPP = dynamic_cast<FPPassManager *>(P); 00105 assert (FPP && "Invalid CGPassManager member"); 00106 00107 // Run pass P on all functions current SCC 00108 std::vector<CallGraphNode*> &SCC = *I; 00109 for (unsigned i = 0, e = SCC.size(); i != e; ++i) { 00110 Function *F = SCC[i]->getFunction(); 00111 if (F) { 00112 dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getNameStart()); 00113 Changed |= FPP->runOnFunction(*F); 00114 } 00115 } 00116 } 00117 StopPassTimer(P); 00118 00119 if (Changed) 00120 dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, ""); 00121 dumpPreservedSet(P); 00122 00123 verifyPreservedAnalysis(P); 00124 removeNotPreservedAnalysis(P); 00125 recordAvailableAnalysis(P); 00126 removeDeadPasses(P, "", ON_CG_MSG); 00127 } 00128 } 00129 Changed |= doFinalization(CG); 00130 return Changed; 00131 } 00132 00133 /// Initialize CG 00134 bool CGPassManager::doInitialization(CallGraph &CG) { 00135 bool Changed = false; 00136 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 00137 Pass *P = getContainedPass(Index); 00138 if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) 00139 Changed |= CGSP->doInitialization(CG); 00140 } 00141 return Changed; 00142 } 00143 00144 /// Finalize CG 00145 bool CGPassManager::doFinalization(CallGraph &CG) { 00146 bool Changed = false; 00147 for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { 00148 Pass *P = getContainedPass(Index); 00149 if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) 00150 Changed |= CGSP->doFinalization(CG); 00151 } 00152 return Changed; 00153 } 00154 00155 /// Assign pass manager to manage this pass. 00156 void CallGraphSCCPass::assignPassManager(PMStack &PMS, 00157 PassManagerType PreferredType) { 00158 // Find CGPassManager 00159 while (!PMS.empty() && 00160 PMS.top()->getPassManagerType() > PMT_CallGraphPassManager) 00161 PMS.pop(); 00162 00163 assert (!PMS.empty() && "Unable to handle Call Graph Pass"); 00164 CGPassManager *CGP = dynamic_cast<CGPassManager *>(PMS.top()); 00165 00166 // Create new Call Graph SCC Pass Manager if it does not exist. 00167 if (!CGP) { 00168 00169 assert (!PMS.empty() && "Unable to create Call Graph Pass Manager"); 00170 PMDataManager *PMD = PMS.top(); 00171 00172 // [1] Create new Call Graph Pass Manager 00173 CGP = new CGPassManager(PMD->getDepth() + 1); 00174 00175 // [2] Set up new manager's top level manager 00176 PMTopLevelManager *TPM = PMD->getTopLevelManager(); 00177 TPM->addIndirectPassManager(CGP); 00178 00179 // [3] Assign manager to manage this new manager. This may create 00180 // and push new managers into PMS 00181 Pass *P = dynamic_cast<Pass *>(CGP); 00182 TPM->schedulePass(P); 00183 00184 // [4] Push new manager into PMS 00185 PMS.push(CGP); 00186 } 00187 00188 CGP->add(this); 00189 } 00190 00191 /// getAnalysisUsage - For this class, we declare that we require and preserve 00192 /// the call graph. If the derived class implements this method, it should 00193 /// always explicitly call the implementation here. 00194 void CallGraphSCCPass::getAnalysisUsage(AnalysisUsage &AU) const { 00195 AU.addRequired<CallGraph>(); 00196 AU.addPreserved<CallGraph>(); 00197 }