1249259Sdim//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file defines the CallGraphSCCPass class, which is used for passes which 11249259Sdim// are implemented as bottom-up traversals on the call graph. Because there may 12249259Sdim// be cycles in the call graph, passes of this type operate on the call-graph in 13249259Sdim// SCC order: that is, they process function bottom-up, except for recursive 14249259Sdim// functions, which they process all at once. 15249259Sdim// 16249259Sdim// These passes are inherently interprocedural, and are required to keep the 17249259Sdim// call graph up-to-date if they do anything which could modify it. 18249259Sdim// 19249259Sdim//===----------------------------------------------------------------------===// 20249259Sdim 21249259Sdim#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H 22249259Sdim#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H 23249259Sdim 24249259Sdim#include "llvm/Analysis/CallGraph.h" 25249259Sdim#include "llvm/Pass.h" 26249259Sdim 27249259Sdimnamespace llvm { 28249259Sdim 29249259Sdimclass CallGraphNode; 30249259Sdimclass CallGraph; 31249259Sdimclass PMStack; 32249259Sdimclass CallGraphSCC; 33249259Sdim 34249259Sdimclass CallGraphSCCPass : public Pass { 35249259Sdimpublic: 36249259Sdim explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {} 37249259Sdim 38249259Sdim /// createPrinterPass - Get a pass that prints the Module 39249259Sdim /// corresponding to a CallGraph. 40249259Sdim Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; 41249259Sdim 42249259Sdim using llvm::Pass::doInitialization; 43249259Sdim using llvm::Pass::doFinalization; 44249259Sdim 45249259Sdim /// doInitialization - This method is called before the SCC's of the program 46249259Sdim /// has been processed, allowing the pass to do initialization as necessary. 47249259Sdim virtual bool doInitialization(CallGraph &CG) { 48249259Sdim return false; 49249259Sdim } 50249259Sdim 51249259Sdim /// runOnSCC - This method should be implemented by the subclass to perform 52249259Sdim /// whatever action is necessary for the specified SCC. Note that 53249259Sdim /// non-recursive (or only self-recursive) functions will have an SCC size of 54249259Sdim /// 1, where recursive portions of the call graph will have SCC size > 1. 55249259Sdim /// 56249259Sdim /// SCC passes that add or delete functions to the SCC are required to update 57249259Sdim /// the SCC list, otherwise stale pointers may be dereferenced. 58249259Sdim /// 59249259Sdim virtual bool runOnSCC(CallGraphSCC &SCC) = 0; 60249259Sdim 61249259Sdim /// doFinalization - This method is called after the SCC's of the program has 62249259Sdim /// been processed, allowing the pass to do final cleanup as necessary. 63249259Sdim virtual bool doFinalization(CallGraph &CG) { 64249259Sdim return false; 65249259Sdim } 66249259Sdim 67249259Sdim /// Assign pass manager to manager this pass 68249259Sdim virtual void assignPassManager(PMStack &PMS, 69249259Sdim PassManagerType PMT); 70249259Sdim 71249259Sdim /// Return what kind of Pass Manager can manage this pass. 72249259Sdim virtual PassManagerType getPotentialPassManagerType() const { 73249259Sdim return PMT_CallGraphPassManager; 74249259Sdim } 75249259Sdim 76249259Sdim /// getAnalysisUsage - For this class, we declare that we require and preserve 77249259Sdim /// the call graph. If the derived class implements this method, it should 78249259Sdim /// always explicitly call the implementation here. 79249259Sdim virtual void getAnalysisUsage(AnalysisUsage &Info) const; 80249259Sdim}; 81249259Sdim 82249259Sdim/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. 83249259Sdimclass CallGraphSCC { 84249259Sdim void *Context; // The CGPassManager object that is vending this. 85249259Sdim std::vector<CallGraphNode*> Nodes; 86249259Sdimpublic: 87249259Sdim CallGraphSCC(void *context) : Context(context) {} 88249259Sdim 89249259Sdim void initialize(CallGraphNode*const*I, CallGraphNode*const*E) { 90249259Sdim Nodes.assign(I, E); 91249259Sdim } 92249259Sdim 93249259Sdim bool isSingular() const { return Nodes.size() == 1; } 94249259Sdim unsigned size() const { return Nodes.size(); } 95249259Sdim 96249259Sdim /// ReplaceNode - This informs the SCC and the pass manager that the specified 97249259Sdim /// Old node has been deleted, and New is to be used in its place. 98249259Sdim void ReplaceNode(CallGraphNode *Old, CallGraphNode *New); 99249259Sdim 100249259Sdim typedef std::vector<CallGraphNode*>::const_iterator iterator; 101249259Sdim iterator begin() const { return Nodes.begin(); } 102249259Sdim iterator end() const { return Nodes.end(); } 103249259Sdim}; 104249259Sdim 105249259Sdim} // End llvm namespace 106249259Sdim 107249259Sdim#endif 108