LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CallGraphSCCPass.cpp

Go to the documentation of this file.
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 }



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.