Implement an entry node for the call graph
authorChris Lattner <sabre@nondot.org>
Mon, 26 Nov 2001 18:47:11 +0000 (18:47 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 26 Nov 2001 18:47:11 +0000 (18:47 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1363 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/CallGraph.h

index 5f259d593346a858a579e5b5a377031e1faa2f03..62b1846952ba0f3ce0ca9c7bd050b04a29573524 100644 (file)
@@ -7,11 +7,16 @@
 // A call graph may only have up to one null method node that represents all of
 // the dynamic method invocations.
 //
+// Additionally, the 'root' node of a call graph represents the "entry point"
+// node of the graph, which has an edge to every external method in the graph.
+// This node has a null method pointer.
+//
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_ANALYSIS_CALLGRAPH_H
 #define LLVM_ANALYSIS_CALLGRAPH_H
 
+#include "llvm/Support/GraphTraits.h"
 #include <map>
 #include <vector>
 class Method;
@@ -40,6 +45,9 @@ public:
 
   inline CallGraphNode *operator[](unsigned i) const { return CalledMethods[i];}
 
+  void removeAllCalledMethods() {
+    CalledMethods.clear();
+  }
 
 private:                    // Stuff to construct the node, used by CallGraph
   friend class CallGraph;
@@ -55,15 +63,23 @@ private:                    // Stuff to construct the node, used by CallGraph
 
 
 class CallGraph {
-  Module *Mod;
+  Module *Mod;              // The module this call graph represents
+
   typedef map<const Method *, CallGraphNode *> MethodMapTy;
-  MethodMapTy MethodMap;
+  MethodMapTy MethodMap;    // Map from a method to its node
+
+  CallGraphNode *Root;
 public:
   CallGraph(Module *TheModule);
+  ~CallGraph();
 
   typedef MethodMapTy::iterator iterator;
   typedef MethodMapTy::const_iterator const_iterator;
 
+  inline       CallGraphNode *getRoot()       { return Root; }
+  inline const CallGraphNode *getRoot() const { return Root; }
+  inline       iterator begin()       { return MethodMap.begin(); }
+  inline       iterator end()         { return MethodMap.end();   }
   inline const_iterator begin() const { return MethodMap.begin(); }
   inline const_iterator end()   const { return MethodMap.end();   }
 
@@ -72,6 +88,28 @@ public:
     assert(I != MethodMap.end() && "Method not in callgraph!");
     return I->second;
   }
+  inline CallGraphNode *operator[](const Method *M) {
+    const_iterator I = MethodMap.find(M);
+    assert(I != MethodMap.end() && "Method not in callgraph!");
+    return I->second;
+  }
+
+  // Methods to keep a call graph up to date with a method that has been
+  // modified
+  //
+  void addMethodToModule(Method *Meth);  // TODO IMPLEMENT
+
+
+  // removeMethodFromModule - Unlink the method from this module, returning it.
+  // Because this removes the method from the module, the call graph node is
+  // destroyed.  This is only valid if the method does not call any other
+  // methods (ie, there are no edges in it's CGN).  The easiest way to do this
+  // is to dropAllReferences before calling this.
+  //
+  Method *removeMethodFromModule(CallGraphNode *CGN);
+  Method *removeMethodFromModule(Method *Meth) {
+    return removeMethodFromModule((*this)[Meth]);
+  }
 
 private:   // Implementation of CallGraph construction
 
@@ -86,21 +124,50 @@ private:   // Implementation of CallGraph construction
   void addToCallGraph(Method *M);
 };
 
-
 }  // end namespace cfg
 
 
-//******************* Externally Visible Functions *************************/
+
+
+// Provide graph traits for tranversing call graphs using standard graph
+// traversals.
+template <> struct GraphTraits<cfg::CallGraphNode*> {
+  typedef cfg::CallGraphNode NodeType;
+  typedef NodeType::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(cfg::CallGraphNode *CGN) { return CGN; }
+  static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
+  static inline ChildIteratorType child_end  (NodeType *N) { return N->end(); }
+};
+
+template <> struct GraphTraits<const cfg::CallGraphNode*> {
+  typedef const cfg::CallGraphNode NodeType;
+  typedef NodeType::const_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(const cfg::CallGraphNode *CGN) { return CGN; }
+  static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
+  static inline ChildIteratorType child_end  (NodeType *N) { return N->end(); }
+};
+
+
+template<> struct GraphTraits<cfg::CallGraph*> :
+  public GraphTraits<cfg::CallGraphNode*> {
+  static NodeType *getEntryNode(cfg::CallGraph *CGN) {
+    return CGN->getRoot();
+  }
+};
+template<> struct GraphTraits<const cfg::CallGraph*> :
+  public GraphTraits<const cfg::CallGraphNode*> {
+  static NodeType *getEntryNode(const cfg::CallGraph *CGN) {
+    return CGN->getRoot();
+  }
+};
 
 
 // Checks if a method contains any call instructions.
 // Note that this uses the call graph only if one is provided.
 // It does not build the call graph.
 // 
-bool   IsLeafMethod       (const Method* method,
-                            const cfg::CallGraph* callGraph = NULL);
-
-
-//**************************************************************************/
+bool isLeafMethod(const Method* method, const cfg::CallGraph *callGraph = 0);
 
 #endif