CallGraph.h revision 96c466b06ab0c830b07329c1b16037f585ccbe40
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project//===- CallGraph.h - Build a Module's call graph -----------------*- C++ -*--=// 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// This interface is used to build and manipulate a call graph, which is a very 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// useful tool for interprocedural optimization. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// Every method in a module is represented as a node in the call graph. The 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// callgraph node keeps track of which methods the are called by the method 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// corresponding to the node. 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// A call graph will contain nodes where the method that they correspond to is 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// null. This 'external' node is used to represent control flow that is not 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// represented (or analyzable) in the module. As such, the external node will 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// have edges to methods with the following properties: 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 1. All methods in the module without internal linkage, since they could 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// be called by methods outside of the our analysis capability. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 2. All methods whose address is used for something more than a direct call, 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// for example being stored into a memory location. Since they may be 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// called by an unknown caller later, they must be tracked as such. 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 20b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes// Similarly, methods have a call edge to the external node iff: 21b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes// 1. The method is external, reflecting the fact that they could call 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// anything without internal linkage or that has its address taken. 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 2. The method contains an indirect method call. 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// As an extension in the future, there may be multiple nodes with a null 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// method. These will be used when we can prove (through pointer analysis) that 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// an indirect call site can call only a specific set of methods. 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 29f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// Because of these properties, the CallGraph captures a conservative superset 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// of all of the caller-callee relationships, which is useful for 31f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// transformations. 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// The CallGraph class also attempts to figure out what the root of the 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// CallGraph is, which is currently does by looking for a method named 'main'. 35f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// If no method named 'main' is found, the external node is used as the entry 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// node, reflecting the fact that any method without internal linkage could 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// be called into (which is common for libraries). 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project//===----------------------------------------------------------------------===// 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#ifndef LLVM_ANALYSIS_CALLGRAPH_H 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#define LLVM_ANALYSIS_CALLGRAPH_H 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "Support/GraphTraits.h" 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "llvm/Pass.h" 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectclass Function; 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectclass Module; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectclass CallGraphNode; 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes//===----------------------------------------------------------------------===// 51fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes// CallGraph class definition 52f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson// 53fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughesclass CallGraph : public Pass { 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Module *Mod; // The module this call graph represents 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes typedef std::map<const Function *, CallGraphNode *> MethodMapTy; 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MethodMapTy MethodMap; // Map from a method to its node 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Root is root of the call graph, or the external node if a 'main' function 60fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes // couldn't be found. ExternalNode is equivalent to (*this)[0]. 61fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes // 62f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson CallGraphNode *Root, *ExternalNode; 63fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughespublic: 64fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes 65fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes //===--------------------------------------------------------------------- 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Accessors... 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project typedef MethodMapTy::iterator iterator; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project typedef MethodMapTy::const_iterator const_iterator; 70b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline CallGraphNode *getRoot() { return Root; } 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline const CallGraphNode *getRoot() const { return Root; } 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline iterator begin() { return MethodMap.begin(); } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline iterator end() { return MethodMap.end(); } 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline const_iterator begin() const { return MethodMap.begin(); } 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline const_iterator end() const { return MethodMap.end(); } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Subscripting operators, return the call graph node for the provided method 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline const CallGraphNode *operator[](const Function *F) const { 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project const_iterator I = MethodMap.find(F); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project assert(I != MethodMap.end() && "Method not in callgraph!"); 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return I->second; 84b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 85f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson inline CallGraphNode *operator[](const Function *F) { 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project const_iterator I = MethodMap.find(F); 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project assert(I != MethodMap.end() && "Method not in callgraph!"); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return I->second; 89b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 90b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 91b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes //===--------------------------------------------------------------------- 92b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes // Methods to keep a call graph up to date with a method that has been 93b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes // modified 94b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes // 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void addMethodToModule(Function *Meth); 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // removeMethodFromModule - Unlink the method from this module, returning it. 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Because this removes the method from the module, the call graph node is 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // destroyed. This is only valid if the method does not call any other 101f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // methods (ie, there are no edges in it's CGN). The easiest way to do this 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // is to dropAllReferences before calling this. 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Function *removeMethodFromModule(CallGraphNode *CGN); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Function *removeMethodFromModule(Function *Meth) { 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return removeMethodFromModule((*this)[Meth]); 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //===--------------------------------------------------------------------- 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Pass infrastructure interface glue code... 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static AnalysisID ID; // We are an analysis, we must have an ID 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CallGraph(AnalysisID AID) : Root(0) { assert(AID == ID); } 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ~CallGraph() { destroy(); } 117f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 118f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson virtual const char *getPassName() const { return "Call Graph Construction"; } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // run - Compute the call graph for the specified module. 121b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes virtual bool run(Module *TheModule); 122b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 12355392539fea537abfb6581b474918f9d611fba27Jesse Wilson // getAnalysisUsage - This obviously provides a call graph 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project virtual void getAnalysisUsage(AnalysisUsage &AU) const { 125b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes AU.setPreservesAll(); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AU.addProvided(ID); 127f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes } 128b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 12955392539fea537abfb6581b474918f9d611fba27Jesse Wilson // releaseMemory - Data structures can be large, so free memory agressively. 130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson virtual void releaseMemory() { 131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson destroy(); 132f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 133f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 134f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughesprivate: 135b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes //===--------------------------------------------------------------------- 136f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Implementation of CallGraph construction 137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // 1380efebd8c734d30ed798b80166290b904fa357ee0Jesse Wilson 139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // getNodeFor - Return the node for the specified function or create one if it 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // does not already exist. 141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // 14255392539fea537abfb6581b474918f9d611fba27Jesse Wilson CallGraphNode *getNodeFor(Function *F); 143f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // addToCallGraph - Add a function to the call graph, and link the node to all 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // of the methods that it calls. 14655392539fea537abfb6581b474918f9d611fba27Jesse Wilson // 14755392539fea537abfb6581b474918f9d611fba27Jesse Wilson void addToCallGraph(Function *F); 14855392539fea537abfb6581b474918f9d611fba27Jesse Wilson 14955392539fea537abfb6581b474918f9d611fba27Jesse Wilson // destroy - Release memory for the call graph 150f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes void destroy(); 15155392539fea537abfb6581b474918f9d611fba27Jesse Wilson}; 15255392539fea537abfb6581b474918f9d611fba27Jesse Wilson 15355392539fea537abfb6581b474918f9d611fba27Jesse Wilson 15455392539fea537abfb6581b474918f9d611fba27Jesse Wilson//===----------------------------------------------------------------------===// 15555392539fea537abfb6581b474918f9d611fba27Jesse Wilson// CallGraphNode class definition 15655392539fea537abfb6581b474918f9d611fba27Jesse Wilson// 15755392539fea537abfb6581b474918f9d611fba27Jesse Wilsonclass CallGraphNode { 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Function *Meth; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project std::vector<CallGraphNode*> CalledMethods; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CallGraphNode(const CallGraphNode &); // Do not implement 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic: 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //===--------------------------------------------------------------------- 164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Accessor methods... 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project typedef std::vector<CallGraphNode*>::iterator iterator; 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project typedef std::vector<CallGraphNode*>::const_iterator const_iterator; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // getMethod - Return the method that this call graph node represents... 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Function *getMethod() const { return Meth; } 172b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 173b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes inline iterator begin() { return CalledMethods.begin(); } 174b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes inline iterator end() { return CalledMethods.end(); } 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline const_iterator begin() const { return CalledMethods.begin(); } 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inline const_iterator end() const { return CalledMethods.end(); } 177b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes inline unsigned size() const { return CalledMethods.size(); } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Subscripting operator - Return the i'th called method... 180f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // 181f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson inline CallGraphNode *operator[](unsigned i) const { return CalledMethods[i];} 182f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 184f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson //===--------------------------------------------------------------------- 185f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Methods to keep a call graph up to date with a method that has been 18655392539fea537abfb6581b474918f9d611fba27Jesse Wilson // modified 187f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // 188f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void removeAllCalledMethods() { 190 CalledMethods.clear(); 191 } 192 193private: // Stuff to construct the node, used by CallGraph 194 friend class CallGraph; 195 196 // CallGraphNode ctor - Create a node for the specified method... 197 inline CallGraphNode(Function *F) : Meth(F) {} 198 199 // addCalledMethod add a method to the list of methods called by this one 200 void addCalledMethod(CallGraphNode *M) { 201 CalledMethods.push_back(M); 202 } 203}; 204 205 206 207//===----------------------------------------------------------------------===// 208// GraphTraits specializations for call graphs so that they can be treated as 209// graphs by the generic graph algorithms... 210// 211 212// Provide graph traits for tranversing call graphs using standard graph 213// traversals. 214template <> struct GraphTraits<CallGraphNode*> { 215 typedef CallGraphNode NodeType; 216 typedef NodeType::iterator ChildIteratorType; 217 218 static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; } 219 static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();} 220 static inline ChildIteratorType child_end (NodeType *N) { return N->end(); } 221}; 222 223template <> struct GraphTraits<const CallGraphNode*> { 224 typedef const CallGraphNode NodeType; 225 typedef NodeType::const_iterator ChildIteratorType; 226 227 static NodeType *getEntryNode(const CallGraphNode *CGN) { return CGN; } 228 static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();} 229 static inline ChildIteratorType child_end (NodeType *N) { return N->end(); } 230}; 231 232 233template<> struct GraphTraits<CallGraph*> : 234 public GraphTraits<CallGraphNode*> { 235 static NodeType *getEntryNode(CallGraph *CGN) { 236 return CGN->getRoot(); 237 } 238}; 239template<> struct GraphTraits<const CallGraph*> : 240 public GraphTraits<const CallGraphNode*> { 241 static NodeType *getEntryNode(const CallGraph *CGN) { 242 return CGN->getRoot(); 243 } 244}; 245 246 247//===----------------------------------------------------------------------===// 248// Printing support for Call Graphs 249// 250 251// Stuff for printing out a callgraph... 252 253void WriteToOutput(const CallGraph &, std::ostream &o); 254inline std::ostream &operator <<(std::ostream &o, const CallGraph &CG) { 255 WriteToOutput(CG, o); return o; 256} 257 258void WriteToOutput(const CallGraphNode *, std::ostream &o); 259inline std::ostream &operator <<(std::ostream &o, const CallGraphNode *CGN) { 260 WriteToOutput(CGN, o); return o; 261} 262 263#endif 264