1*9880d681SAndroid Build Coastguard Worker //===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file defines the CallGraphSCCPass class, which is used for passes which 11*9880d681SAndroid Build Coastguard Worker // are implemented as bottom-up traversals on the call graph. Because there may 12*9880d681SAndroid Build Coastguard Worker // be cycles in the call graph, passes of this type operate on the call-graph in 13*9880d681SAndroid Build Coastguard Worker // SCC order: that is, they process function bottom-up, except for recursive 14*9880d681SAndroid Build Coastguard Worker // functions, which they process all at once. 15*9880d681SAndroid Build Coastguard Worker // 16*9880d681SAndroid Build Coastguard Worker // These passes are inherently interprocedural, and are required to keep the 17*9880d681SAndroid Build Coastguard Worker // call graph up-to-date if they do anything which could modify it. 18*9880d681SAndroid Build Coastguard Worker // 19*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H 22*9880d681SAndroid Build Coastguard Worker #define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/CallGraph.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/PassSupport.h" 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker namespace llvm { 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker class CallGraphNode; 31*9880d681SAndroid Build Coastguard Worker class CallGraph; 32*9880d681SAndroid Build Coastguard Worker class PMStack; 33*9880d681SAndroid Build Coastguard Worker class CallGraphSCC; 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker class CallGraphSCCPass : public Pass { 36*9880d681SAndroid Build Coastguard Worker public: CallGraphSCCPass(char & pid)37*9880d681SAndroid Build Coastguard Worker explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {} 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker /// createPrinterPass - Get a pass that prints the Module 40*9880d681SAndroid Build Coastguard Worker /// corresponding to a CallGraph. 41*9880d681SAndroid Build Coastguard Worker Pass *createPrinterPass(raw_ostream &O, 42*9880d681SAndroid Build Coastguard Worker const std::string &Banner) const override; 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker using llvm::Pass::doInitialization; 45*9880d681SAndroid Build Coastguard Worker using llvm::Pass::doFinalization; 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker /// doInitialization - This method is called before the SCC's of the program 48*9880d681SAndroid Build Coastguard Worker /// has been processed, allowing the pass to do initialization as necessary. doInitialization(CallGraph & CG)49*9880d681SAndroid Build Coastguard Worker virtual bool doInitialization(CallGraph &CG) { 50*9880d681SAndroid Build Coastguard Worker return false; 51*9880d681SAndroid Build Coastguard Worker } 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker /// runOnSCC - This method should be implemented by the subclass to perform 54*9880d681SAndroid Build Coastguard Worker /// whatever action is necessary for the specified SCC. Note that 55*9880d681SAndroid Build Coastguard Worker /// non-recursive (or only self-recursive) functions will have an SCC size of 56*9880d681SAndroid Build Coastguard Worker /// 1, where recursive portions of the call graph will have SCC size > 1. 57*9880d681SAndroid Build Coastguard Worker /// 58*9880d681SAndroid Build Coastguard Worker /// SCC passes that add or delete functions to the SCC are required to update 59*9880d681SAndroid Build Coastguard Worker /// the SCC list, otherwise stale pointers may be dereferenced. 60*9880d681SAndroid Build Coastguard Worker /// 61*9880d681SAndroid Build Coastguard Worker virtual bool runOnSCC(CallGraphSCC &SCC) = 0; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker /// doFinalization - This method is called after the SCC's of the program has 64*9880d681SAndroid Build Coastguard Worker /// been processed, allowing the pass to do final cleanup as necessary. doFinalization(CallGraph & CG)65*9880d681SAndroid Build Coastguard Worker virtual bool doFinalization(CallGraph &CG) { 66*9880d681SAndroid Build Coastguard Worker return false; 67*9880d681SAndroid Build Coastguard Worker } 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker /// Assign pass manager to manager this pass 70*9880d681SAndroid Build Coastguard Worker void assignPassManager(PMStack &PMS, PassManagerType PMT) override; 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker /// Return what kind of Pass Manager can manage this pass. getPotentialPassManagerType()73*9880d681SAndroid Build Coastguard Worker PassManagerType getPotentialPassManagerType() const override { 74*9880d681SAndroid Build Coastguard Worker return PMT_CallGraphPassManager; 75*9880d681SAndroid Build Coastguard Worker } 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker /// getAnalysisUsage - For this class, we declare that we require and preserve 78*9880d681SAndroid Build Coastguard Worker /// the call graph. If the derived class implements this method, it should 79*9880d681SAndroid Build Coastguard Worker /// always explicitly call the implementation here. 80*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &Info) const override; 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker protected: 83*9880d681SAndroid Build Coastguard Worker /// Optional passes call this function to check whether the pass should be 84*9880d681SAndroid Build Coastguard Worker /// skipped. This is the case when optimization bisect is over the limit. 85*9880d681SAndroid Build Coastguard Worker bool skipSCC(CallGraphSCC &SCC) const; 86*9880d681SAndroid Build Coastguard Worker }; 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker /// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. 89*9880d681SAndroid Build Coastguard Worker class CallGraphSCC { 90*9880d681SAndroid Build Coastguard Worker const CallGraph &CG; // The call graph for this SCC. 91*9880d681SAndroid Build Coastguard Worker void *Context; // The CGPassManager object that is vending this. 92*9880d681SAndroid Build Coastguard Worker std::vector<CallGraphNode*> Nodes; 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker public: CallGraphSCC(CallGraph & cg,void * context)95*9880d681SAndroid Build Coastguard Worker CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {} 96*9880d681SAndroid Build Coastguard Worker initialize(CallGraphNode * const * I,CallGraphNode * const * E)97*9880d681SAndroid Build Coastguard Worker void initialize(CallGraphNode *const *I, CallGraphNode *const *E) { 98*9880d681SAndroid Build Coastguard Worker Nodes.assign(I, E); 99*9880d681SAndroid Build Coastguard Worker } 100*9880d681SAndroid Build Coastguard Worker isSingular()101*9880d681SAndroid Build Coastguard Worker bool isSingular() const { return Nodes.size() == 1; } size()102*9880d681SAndroid Build Coastguard Worker unsigned size() const { return Nodes.size(); } 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker /// ReplaceNode - This informs the SCC and the pass manager that the specified 105*9880d681SAndroid Build Coastguard Worker /// Old node has been deleted, and New is to be used in its place. 106*9880d681SAndroid Build Coastguard Worker void ReplaceNode(CallGraphNode *Old, CallGraphNode *New); 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker typedef std::vector<CallGraphNode *>::const_iterator iterator; begin()109*9880d681SAndroid Build Coastguard Worker iterator begin() const { return Nodes.begin(); } end()110*9880d681SAndroid Build Coastguard Worker iterator end() const { return Nodes.end(); } 111*9880d681SAndroid Build Coastguard Worker getCallGraph()112*9880d681SAndroid Build Coastguard Worker const CallGraph &getCallGraph() { return CG; } 113*9880d681SAndroid Build Coastguard Worker }; 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker void initializeDummyCGSCCPassPass(PassRegistry &); 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker /// This pass is required by interprocedural register allocation. It forces 118*9880d681SAndroid Build Coastguard Worker /// codegen to follow bottom up order on call graph. 119*9880d681SAndroid Build Coastguard Worker class DummyCGSCCPass : public CallGraphSCCPass { 120*9880d681SAndroid Build Coastguard Worker public: 121*9880d681SAndroid Build Coastguard Worker static char ID; DummyCGSCCPass()122*9880d681SAndroid Build Coastguard Worker DummyCGSCCPass() : CallGraphSCCPass(ID) { 123*9880d681SAndroid Build Coastguard Worker PassRegistry &Registry = *PassRegistry::getPassRegistry(); 124*9880d681SAndroid Build Coastguard Worker initializeDummyCGSCCPassPass(Registry); 125*9880d681SAndroid Build Coastguard Worker }; runOnSCC(CallGraphSCC & SCC)126*9880d681SAndroid Build Coastguard Worker bool runOnSCC(CallGraphSCC &SCC) override { return false; } getAnalysisUsage(AnalysisUsage & AU)127*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 128*9880d681SAndroid Build Coastguard Worker AU.setPreservesAll(); 129*9880d681SAndroid Build Coastguard Worker } 130*9880d681SAndroid Build Coastguard Worker }; 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker } // End llvm namespace 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker #endif 135