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