blob: a323610427bc83892c0f42f5006631f887d745c2 [file] [log] [blame]
Chris Lattner41fbf302001-09-28 00:08:15 +00001//===- CallGraph.cpp - Build a Module's call graph --------------------------=//
2//
3// This file implements call graph construction (from a module), and will
4// eventually implement call graph serialization and deserialization for
5// annotation support.
6//
Chris Lattner9f9e2be2001-10-13 06:33:19 +00007// This call graph represents a dynamic method invocation as a null method node.
8// A call graph may only have up to one null method node that represents all of
9// the dynamic method invocations.
10//
Chris Lattner41fbf302001-09-28 00:08:15 +000011//===----------------------------------------------------------------------===//
12
13#include "llvm/Analysis/CallGraph.h"
14#include "llvm/Analysis/Writer.h"
15#include "llvm/Support/STLExtras.h"
16#include "llvm/Module.h"
17#include "llvm/Method.h"
18#include "llvm/iOther.h"
Chris Lattner9f9e2be2001-10-13 06:33:19 +000019#include "llvm/iTerminators.h"
Chris Lattner41fbf302001-09-28 00:08:15 +000020#include <algorithm>
21
Chris Lattner41fbf302001-09-28 00:08:15 +000022// getNodeFor - Return the node for the specified method or create one if it
23// does not already exist.
24//
Chris Lattner25e9cad2001-11-26 18:51:25 +000025cfg::CallGraphNode *cfg::CallGraph::getNodeFor(Method *M) {
Chris Lattner41fbf302001-09-28 00:08:15 +000026 iterator I = MethodMap.find(M);
27 if (I != MethodMap.end()) return I->second;
28
29 assert(M->getParent() == Mod && "Method not in current module!");
30 CallGraphNode *New = new CallGraphNode(M);
31
32 MethodMap.insert(pair<const Method*, CallGraphNode*>(M, New));
33 return New;
34}
35
36// addToCallGraph - Add a method to the call graph, and link the node to all of
37// the methods that it calls.
38//
Chris Lattner25e9cad2001-11-26 18:51:25 +000039void cfg::CallGraph::addToCallGraph(Method *M) {
Chris Lattner41fbf302001-09-28 00:08:15 +000040 CallGraphNode *Node = getNodeFor(M);
41
Chris Lattner25e9cad2001-11-26 18:51:25 +000042 // If this method has external linkage,
43 if (!M->hasInternalLinkage())
44 Root->addCalledMethod(Node);
45
Chris Lattner9f9e2be2001-10-13 06:33:19 +000046 for (Method::inst_iterator I = M->inst_begin(), E = M->inst_end();
47 I != E; ++I) {
48 // Dynamic calls will cause Null nodes to be created
49 if (CallInst *CI = dyn_cast<CallInst>(*I))
Chris Lattner41fbf302001-09-28 00:08:15 +000050 Node->addCalledMethod(getNodeFor(CI->getCalledMethod()));
Chris Lattner9f9e2be2001-10-13 06:33:19 +000051 else if (InvokeInst *II = dyn_cast<InvokeInst>(*I))
52 Node->addCalledMethod(getNodeFor(II->getCalledMethod()));
Chris Lattner41fbf302001-09-28 00:08:15 +000053 }
54}
55
Chris Lattner25e9cad2001-11-26 18:51:25 +000056cfg::CallGraph::CallGraph(Module *TheModule) {
Chris Lattner41fbf302001-09-28 00:08:15 +000057 Mod = TheModule;
58
Chris Lattner25e9cad2001-11-26 18:51:25 +000059 // Create the root node of the module...
60 Root = new CallGraphNode(0);
61
Chris Lattner41fbf302001-09-28 00:08:15 +000062 // Add every method to the call graph...
63 for_each(Mod->begin(), Mod->end(), bind_obj(this,&CallGraph::addToCallGraph));
64}
65
Chris Lattner25e9cad2001-11-26 18:51:25 +000066cfg::CallGraph::~CallGraph() {
67 for (MethodMapTy::iterator I = MethodMap.begin(), E = MethodMap.end();
68 I != E; ++I) {
69 delete I->second;
70 }
71}
72
Chris Lattner41fbf302001-09-28 00:08:15 +000073
74void cfg::WriteToOutput(const CallGraphNode *CGN, ostream &o) {
Chris Lattner25e9cad2001-11-26 18:51:25 +000075 if (CGN->getMethod())
76 o << "Call graph node for method: '" << CGN->getMethod()->getName() <<"'\n";
77 else
78 o << "Call graph node null method:\n";
79
Chris Lattner41fbf302001-09-28 00:08:15 +000080 for (unsigned i = 0; i < CGN->size(); ++i)
81 o << " Calls method '" << (*CGN)[i]->getMethod()->getName() << "'\n";
82 o << endl;
83}
84
85void cfg::WriteToOutput(const CallGraph &CG, ostream &o) {
Chris Lattner25e9cad2001-11-26 18:51:25 +000086 WriteToOutput(CG.getRoot(), o);
Chris Lattner41fbf302001-09-28 00:08:15 +000087 for (CallGraph::const_iterator I = CG.begin(), E = CG.end(); I != E; ++I)
88 o << I->second;
89}
Vikram S. Advea7edb182001-10-22 13:55:46 +000090
91
Chris Lattner25e9cad2001-11-26 18:51:25 +000092//===----------------------------------------------------------------------===//
93// Implementations of public modification methods
94//
95
96// Methods to keep a call graph up to date with a method that has been
97// modified
98//
99void cfg::CallGraph::addMethodToModule(Method *Meth) {
100 assert(0 && "not implemented");
101 abort();
102}
103
104// removeMethodFromModule - Unlink the method from this module, returning it.
105// Because this removes the method from the module, the call graph node is
106// destroyed. This is only valid if the method does not call any other
107// methods (ie, there are no edges in it's CGN). The easiest way to do this
108// is to dropAllReferences before calling this.
109//
110Method *cfg::CallGraph::removeMethodFromModule(CallGraphNode *CGN) {
111 assert(CGN->CalledMethods.empty() && "Cannot remove method from call graph"
112 " if it references other methods!");
113 Method *M = CGN->getMethod(); // Get the method for the call graph node
114 delete CGN; // Delete the call graph node for this method
115 MethodMap.erase(M); // Remove the call graph node from the map
116
117 Mod->getMethodList().remove(M);
118 return M;
119}
120
Vikram S. Advea7edb182001-10-22 13:55:46 +0000121
122//
123// Checks if a method contains any call instructions.
124// Note that this uses the call graph only if one is provided.
125// It does not build the call graph.
126//
127bool IsLeafMethod(const Method* M, const cfg::CallGraph* CG) {
128 if (CG) {
129 const cfg::CallGraphNode *cgn = (*CG)[M];
130 return (cgn->begin() == cgn->end());
131 }
Chris Lattner25e9cad2001-11-26 18:51:25 +0000132
133 for (Method::inst_const_iterator I = M->inst_begin(), E = M->inst_end();
134 I != E; ++I)
135 if ((*I)->getOpcode() == Instruction::Call)
136 return false;
137 return true;
Vikram S. Advea7edb182001-10-22 13:55:46 +0000138}
139
140