#ifndef LLVM_ANALYSIS_CALLGRAPH_H
#define LLVM_ANALYSIS_CALLGRAPH_H
+#include "llvm/Function.h"
+#include "llvm/Pass.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/System/IncludeFile.h"
#include <map>
/// Returns the CallGraphNode which is used to represent undetermined calls
/// into the callgraph. Override this if you want behavioral inheritance.
virtual CallGraphNode* getExternalCallingNode() const { return 0; }
+ virtual CallGraphNode* getCallsExternalNode() const { return 0; }
/// Return the root/main method in the module, or some other root node, such
/// as the externalcallingnode. Overload these if you behavioral
};
//===----------------------------------------------------------------------===//
-// CallGraphNode class definition
+// CallGraphNode class definition.
//
class CallGraphNode {
- Function *F;
- typedef std::pair<CallSite,CallGraphNode*> CallRecord;
+ AssertingVH<Function> F;
+
+ // CallRecord - This is a pair of the calling instruction (a call or invoke)
+ // and the callgraph node being called.
+public:
+ typedef std::pair<WeakVH, CallGraphNode*> CallRecord;
+private:
std::vector<CallRecord> CalledFunctions;
/// NumReferences - This is the number of times that this CallGraphNode occurs
// CallGraphNode ctor - Create a node for the specified function.
inline CallGraphNode(Function *f) : F(f), NumReferences(0) {}
+ ~CallGraphNode() {
+ assert(NumReferences == 0 && "Node deleted while references remain");
+ }
//===---------------------------------------------------------------------
// Accessor methods.
/// addCalledFunction - Add a function to the list of functions called by this
/// one.
void addCalledFunction(CallSite CS, CallGraphNode *M) {
- CalledFunctions.push_back(std::make_pair(CS, M));
+ CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
M->AddRef();
}
+ void removeCallEdge(iterator I) {
+ I->second->DropRef();
+ *I = CalledFunctions.back();
+ CalledFunctions.pop_back();
+ }
+
+
/// removeCallEdgeFor - This method removes the edge in the node for the
/// specified call site. Note that this method takes linear time, so it
/// should be used sparingly.
/// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite
/// from this node to the specified callee function.
void removeOneAbstractEdgeTo(CallGraphNode *Callee);
-
- /// replaceCallSite - Make the edge in the node for Old CallSite be for
- /// New CallSite instead. Note that this method takes linear time, so it
- /// should be used sparingly.
- void replaceCallSite(CallSite Old, CallSite New, CallGraphNode *NewCallee);
+
+ /// replaceCallEdge - This method replaces the edge in the node for the
+ /// specified call site with a new one. Note that this method takes linear
+ /// time, so it should be used sparingly.
+ void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
+
+ /// allReferencesDropped - This is a special function that should only be
+ /// used by the CallGraph class.
+ void allReferencesDropped() {
+ NumReferences = 0;
+ }
};
//===----------------------------------------------------------------------===//
template <> struct GraphTraits<CallGraphNode*> {
typedef CallGraphNode NodeType;
- typedef std::pair<CallSite, CallGraphNode*> CGNPairTy;
+ typedef CallGraphNode::CallRecord CGNPairTy;
typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode*> CGNDerefFun;
static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }