diff --git a/llvm/include/llvm/Analysis/CallGraph.h b/llvm/include/llvm/Analysis/CallGraph.h index 5f259d593346..62b1846952ba 100644 --- a/llvm/include/llvm/Analysis/CallGraph.h +++ b/llvm/include/llvm/Analysis/CallGraph.h @@ -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 #include 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 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 { + 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 { + 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 : + public GraphTraits { + static NodeType *getEntryNode(cfg::CallGraph *CGN) { + return CGN->getRoot(); + } +}; +template<> struct GraphTraits : + public GraphTraits { + 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