#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
namespace llvm {
FunctionMapTy FunctionMap; // Map from a function to its node
public:
+ static const int ID; // Class identification, replacement for typeinfo
//===---------------------------------------------------------------------
// Accessors...
//
void initialize(Module &M);
virtual void print(std::ostream &o, const Module *M) const;
+ void print(std::ostream *o, const Module *M) const { if (o) print(*o, M); }
void dump() const;
// stub - dummy function, just ignore it
//
class CallGraphNode {
Function *F;
- std::vector<CallGraphNode*> CalledFunctions;
+ typedef std::pair<CallSite,CallGraphNode*> CallRecord;
+ std::vector<CallRecord> CalledFunctions;
CallGraphNode(const CallGraphNode &); // Do not implement
public:
// Accessor methods...
//
- typedef std::vector<CallGraphNode*>::iterator iterator;
- typedef std::vector<CallGraphNode*>::const_iterator const_iterator;
+ typedef std::vector<CallRecord>::iterator iterator;
+ typedef std::vector<CallRecord>::const_iterator const_iterator;
// getFunction - Return the function that this call graph node represents...
Function *getFunction() const { return F; }
// Subscripting operator - Return the i'th called function...
//
- CallGraphNode *operator[](unsigned i) const { return CalledFunctions[i];}
+ CallGraphNode *operator[](unsigned i) const {
+ return CalledFunctions[i].second;
+ }
/// dump - Print out this call graph node.
///
void dump() const;
void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
//===---------------------------------------------------------------------
// Methods to keep a call graph up to date with a function that has been
/// addCalledFunction add a function to the list of functions called by this
/// one.
- void addCalledFunction(CallGraphNode *M) {
- CalledFunctions.push_back(M);
+ void addCalledFunction(CallSite CS, CallGraphNode *M) {
+ CalledFunctions.push_back(std::make_pair(CS, M));
}
/// removeCallEdgeTo - This method removes a *single* edge to the specified
friend class CallGraph;
- // CallGraphNode ctor - Create a node for the specified function...
+ // CallGraphNode ctor - Create a node for the specified function.
inline CallGraphNode(Function *f) : F(f) {}
};
//===----------------------------------------------------------------------===//
// GraphTraits specializations for call graphs so that they can be treated as
-// graphs by the generic graph algorithms...
+// graphs by the generic graph algorithms.
//
// Provide graph traits for tranversing call graphs using standard graph
// traversals.
template <> struct GraphTraits<CallGraphNode*> {
typedef CallGraphNode NodeType;
- typedef NodeType::iterator ChildIteratorType;
+ typedef std::pair<CallSite, CallGraphNode*> CGNPairTy;
+ typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode*> CGNDerefFun;
+
static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }
- static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
- static inline ChildIteratorType child_end (NodeType *N) { return N->end(); }
+
+ typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+ }
+ static inline ChildIteratorType child_end (NodeType *N) {
+ return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+ }
+
+ static CallGraphNode *CGNDeref(CGNPairTy P) {
+ return P.second;
+ }
+
};
template <> struct GraphTraits<const CallGraphNode*> {
return map_iterator(CG->end(), DerefFun(CGdereference));
}
- static CallGraphNode &CGdereference (std::pair<const Function*,
- CallGraphNode*> P) {
+ static CallGraphNode &CGdereference(PairTy P) {
return *P.second;
}
};