LLVM API Documentation
00001 //===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===// 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 defines the CallGraphSCCPass class, which is used for passes which 00011 // are implemented as bottom-up traversals on the call graph. Because there may 00012 // be cycles in the call graph, passes of this type operate on the call-graph in 00013 // SCC order: that is, they process function bottom-up, except for recursive 00014 // functions, which they process all at once. 00015 // 00016 // These passes are inherently interprocedural, and are required to keep the 00017 // call graph up-to-date if they do anything which could modify it. 00018 // 00019 //===----------------------------------------------------------------------===// 00020 00021 #ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H 00022 #define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H 00023 00024 #include "llvm/Analysis/CallGraph.h" 00025 #include "llvm/Pass.h" 00026 00027 namespace llvm { 00028 00029 class CallGraphNode; 00030 class CallGraph; 00031 class PMStack; 00032 class CallGraphSCC; 00033 00034 class CallGraphSCCPass : public Pass { 00035 public: 00036 explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {} 00037 00038 /// createPrinterPass - Get a pass that prints the Module 00039 /// corresponding to a CallGraph. 00040 Pass *createPrinterPass(raw_ostream &O, 00041 const std::string &Banner) const override; 00042 00043 using llvm::Pass::doInitialization; 00044 using llvm::Pass::doFinalization; 00045 00046 /// doInitialization - This method is called before the SCC's of the program 00047 /// has been processed, allowing the pass to do initialization as necessary. 00048 virtual bool doInitialization(CallGraph &CG) { 00049 return false; 00050 } 00051 00052 /// runOnSCC - This method should be implemented by the subclass to perform 00053 /// whatever action is necessary for the specified SCC. Note that 00054 /// non-recursive (or only self-recursive) functions will have an SCC size of 00055 /// 1, where recursive portions of the call graph will have SCC size > 1. 00056 /// 00057 /// SCC passes that add or delete functions to the SCC are required to update 00058 /// the SCC list, otherwise stale pointers may be dereferenced. 00059 /// 00060 virtual bool runOnSCC(CallGraphSCC &SCC) = 0; 00061 00062 /// doFinalization - This method is called after the SCC's of the program has 00063 /// been processed, allowing the pass to do final cleanup as necessary. 00064 virtual bool doFinalization(CallGraph &CG) { 00065 return false; 00066 } 00067 00068 /// Assign pass manager to manager this pass 00069 void assignPassManager(PMStack &PMS, PassManagerType PMT) override; 00070 00071 /// Return what kind of Pass Manager can manage this pass. 00072 PassManagerType getPotentialPassManagerType() const override { 00073 return PMT_CallGraphPassManager; 00074 } 00075 00076 /// getAnalysisUsage - For this class, we declare that we require and preserve 00077 /// the call graph. If the derived class implements this method, it should 00078 /// always explicitly call the implementation here. 00079 void getAnalysisUsage(AnalysisUsage &Info) const override; 00080 }; 00081 00082 /// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. 00083 class CallGraphSCC { 00084 void *Context; // The CGPassManager object that is vending this. 00085 std::vector<CallGraphNode*> Nodes; 00086 public: 00087 CallGraphSCC(void *context) : Context(context) {} 00088 00089 void initialize(CallGraphNode*const*I, CallGraphNode*const*E) { 00090 Nodes.assign(I, E); 00091 } 00092 00093 bool isSingular() const { return Nodes.size() == 1; } 00094 unsigned size() const { return Nodes.size(); } 00095 00096 /// ReplaceNode - This informs the SCC and the pass manager that the specified 00097 /// Old node has been deleted, and New is to be used in its place. 00098 void ReplaceNode(CallGraphNode *Old, CallGraphNode *New); 00099 00100 typedef std::vector<CallGraphNode*>::const_iterator iterator; 00101 iterator begin() const { return Nodes.begin(); } 00102 iterator end() const { return Nodes.end(); } 00103 }; 00104 00105 } // End llvm namespace 00106 00107 #endif