aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-06-30 03:15:25 +0000
committerChris Lattner <sabre@nondot.org>2003-06-30 03:15:25 +0000
commit5a540633036ccd7482bd8e83913304a4ed3fc11c (patch)
treeb33e418ba8a67500feedda5e0e8dec2bcf7d299c /lib/Analysis
parenta321b04d60e41d76d4d53a0e7afd4c2ea5c159ad (diff)
downloadexternal_llvm-5a540633036ccd7482bd8e83913304a4ed3fc11c.zip
external_llvm-5a540633036ccd7482bd8e83913304a4ed3fc11c.tar.gz
external_llvm-5a540633036ccd7482bd8e83913304a4ed3fc11c.tar.bz2
Revamp DSGraphs so that they can support multiple functions in the same
DSGraph at one time git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6994 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/DataStructure/BottomUpClosure.cpp22
-rw-r--r--lib/Analysis/DataStructure/DataStructure.cpp90
-rw-r--r--lib/Analysis/DataStructure/Local.cpp19
-rw-r--r--lib/Analysis/DataStructure/Printer.cpp56
-rw-r--r--lib/Analysis/DataStructure/Steensgaard.cpp16
-rw-r--r--lib/Analysis/DataStructure/TopDownClosure.cpp12
6 files changed, 121 insertions, 94 deletions
diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp
index 4592867..591cefb 100644
--- a/lib/Analysis/DataStructure/BottomUpClosure.cpp
+++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp
@@ -342,7 +342,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
DEBUG(std::cerr << " Self Inlining: " << F.getName() << "\n");
// Handle self recursion by resolving the arguments and return value
- Graph.mergeInGraph(CS, Graph, 0);
+ Graph.mergeInGraph(CS, F, Graph, 0);
} else {
// Get the data structure graph for the called function.
@@ -360,7 +360,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
#endif
// Handle self recursion by resolving the arguments and return value
- Graph.mergeInGraph(CS, GI,
+ Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits |
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes);
@@ -423,28 +423,28 @@ DSGraph &BUDataStructures::inlineNonSCCGraphs(Function &F,
LastCallSiteIdx = I.getCallSiteIdx();
// Resolve the current call...
- Function *Callee = *I;
+ Function &Callee = **I;
DSCallSite &CS = I.getCallSite();
- if (Callee->isExternal()) {
+ if (Callee.isExternal()) {
// Ignore this case, simple varargs functions we cannot stub out!
- } else if (SCCFunctions.count(Callee)) {
+ } else if (SCCFunctions.count(&Callee)) {
// Calling a function in the SCC, ignore it for now!
- DEBUG(std::cerr << " SCC CallSite for: " << Callee->getName() << "\n");
+ DEBUG(std::cerr << " SCC CallSite for: " << Callee.getName() << "\n");
AuxCallsList.push_back(CS);
} else {
// Get the data structure graph for the called function.
//
- DSGraph &GI = getDSGraph(*Callee); // Graph to inline
+ DSGraph &GI = getDSGraph(Callee); // Graph to inline
- DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
+ DEBUG(std::cerr << " Inlining graph for " << Callee.getName()
<< "[" << GI.getGraphSize() << "+"
<< GI.getAuxFunctionCalls().size() << "] into: " << F.getName()
<< "[" << Graph.getGraphSize() << "+"
<< Graph.getAuxFunctionCalls().size() << "]\n");
// Handle self recursion by resolving the arguments and return value
- Graph.mergeInGraph(CS, GI,
+ Graph.mergeInGraph(CS, Callee, GI,
DSGraph::KeepModRefBits | DSGraph::StripAllocaBit |
DSGraph::DontCloneCallNodes);
}
@@ -514,7 +514,7 @@ DSGraph &BUDataStructures::calculateSCCGraph(Function &F,
DEBUG(std::cerr << " Self Inlining: " << F.getName() << "\n");
// Handle self recursion by resolving the arguments and return value
- Graph.mergeInGraph(CS, Graph, 0);
+ Graph.mergeInGraph(CS, *Callee, Graph, 0);
} else if (SCCCallSiteMap.count(Callee)) {
// We have already seen a call site in the SCC for this function, just
// merge the two call sites together and we are done.
@@ -530,7 +530,7 @@ DSGraph &BUDataStructures::calculateSCCGraph(Function &F,
<< Graph.getAuxFunctionCalls().size() << "]\n");
// Handle self recursion by resolving the arguments and return value
- Graph.mergeInGraph(CS, GI,
+ Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits | DSGraph::StripAllocaBit |
DSGraph::DontCloneCallNodes);
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index ea593de..e485683 100644
--- a/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/lib/Analysis/DataStructure/DataStructure.cpp
@@ -703,24 +703,23 @@ Function &DSCallSite::getCaller() const {
// DSGraph Implementation
//===----------------------------------------------------------------------===//
-DSGraph::DSGraph(const DSGraph &G) : Func(G.Func), GlobalsGraph(0) {
+DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0) {
PrintAuxCalls = false;
- hash_map<const DSNode*, DSNodeHandle> NodeMap;
- RetNode = cloneInto(G, ScalarMap, NodeMap);
+ NodeMapTy NodeMap;
+ cloneInto(G, ScalarMap, ReturnNodes, NodeMap);
}
-DSGraph::DSGraph(const DSGraph &G,
- hash_map<const DSNode*, DSNodeHandle> &NodeMap)
- : Func(G.Func), GlobalsGraph(0) {
+DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap)
+ : GlobalsGraph(0) {
PrintAuxCalls = false;
- RetNode = cloneInto(G, ScalarMap, NodeMap);
+ cloneInto(G, ScalarMap, ReturnNodes, NodeMap);
}
DSGraph::~DSGraph() {
FunctionCalls.clear();
AuxFunctionCalls.clear();
ScalarMap.clear();
- RetNode.setNode(0);
+ ReturnNodes.clear();
// Drop all intra-node references, so that assertions don't fail...
std::for_each(Nodes.begin(), Nodes.end(),
@@ -746,16 +745,15 @@ void DSNode::remapLinks(hash_map<const DSNode*, DSNodeHandle> &OldNodeMap) {
}
-// cloneInto - Clone the specified DSGraph into the current graph, returning the
-// Return node of the graph. The translated ScalarMap for the old function is
-// filled into the OldValMap member. If StripAllocas is set to true, Alloca
-// markers are removed from the graph, as the graph is being cloned into a
-// calling function's graph.
-//
-DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
- hash_map<Value*, DSNodeHandle> &OldValMap,
- hash_map<const DSNode*, DSNodeHandle> &OldNodeMap,
- unsigned CloneFlags) {
+/// cloneInto - Clone the specified DSGraph into the current graph. The
+/// translated ScalarMap for the old function is filled into the OldValMap
+/// member, and the translated ReturnNodes map is returned into ReturnNodes.
+///
+/// The CloneFlags member controls various aspects of the cloning process.
+///
+void DSGraph::cloneInto(const DSGraph &G, ScalarMapTy &OldValMap,
+ ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap,
+ unsigned CloneFlags) {
assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
assert(&G != this && "Cannot clone graph into itself!");
@@ -816,10 +814,15 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
AuxFunctionCalls.push_back(DSCallSite(G.AuxFunctionCalls[i], OldNodeMap));
}
- // Return the returned node pointer...
- DSNodeHandle &MappedRet = OldNodeMap[G.RetNode.getNode()];
- return DSNodeHandle(MappedRet.getNode(),
- MappedRet.getOffset()+G.RetNode.getOffset());
+ // Map the return node pointers over...
+ for (ReturnNodesTy::const_iterator I = G.getReturnNodes().begin(),
+ E = G.getReturnNodes().end(); I != E; ++I) {
+ const DSNodeHandle &Ret = I->second;
+ DSNodeHandle &MappedRet = OldNodeMap[Ret.getNode()];
+ OldReturnNodes.insert(std::make_pair(I->first,
+ DSNodeHandle(MappedRet.getNode(),
+ MappedRet.getOffset()+Ret.getOffset())));
+ }
}
/// mergeInGraph - The method is used for merging graphs together. If the
@@ -827,25 +830,27 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
/// merges the nodes specified in the call site with the formal arguments in the
/// graph.
///
-void DSGraph::mergeInGraph(DSCallSite &CS, const DSGraph &Graph,
+void DSGraph::mergeInGraph(DSCallSite &CS, Function &F, const DSGraph &Graph,
unsigned CloneFlags) {
- hash_map<Value*, DSNodeHandle> OldValMap;
+ ScalarMapTy OldValMap;
+ ScalarMapTy *ScalarMap = &OldValMap;
DSNodeHandle RetVal;
- hash_map<Value*, DSNodeHandle> *ScalarMap = &OldValMap;
// If this is not a recursive call, clone the graph into this graph...
if (&Graph != this) {
// Clone the callee's graph into the current graph, keeping
// track of where scalars in the old graph _used_ to point,
// and of the new nodes matching nodes of the old graph.
- hash_map<const DSNode*, DSNodeHandle> OldNodeMap;
+ NodeMapTy OldNodeMap;
// The clone call may invalidate any of the vectors in the data
// structure graph. Strip locals and don't copy the list of callers
- RetVal = cloneInto(Graph, OldValMap, OldNodeMap, CloneFlags);
+ ReturnNodesTy OldRetNodes;
+ cloneInto(Graph, OldValMap, OldRetNodes, OldNodeMap, CloneFlags);
+ RetVal = OldRetNodes[&F];
ScalarMap = &OldValMap;
} else {
- RetVal = getRetNode();
+ RetVal = getReturnNodeFor(F);
ScalarMap = &getScalarMap();
}
@@ -853,7 +858,6 @@ void DSGraph::mergeInGraph(DSCallSite &CS, const DSGraph &Graph,
RetVal.mergeWith(CS.getRetVal());
// Resolve all of the function arguments...
- Function &F = Graph.getFunction();
Function::aiterator AI = F.abegin();
for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i, ++AI) {
@@ -916,10 +920,16 @@ static void markIncomplete(DSCallSite &Call) {
//
void DSGraph::markIncompleteNodes(unsigned Flags) {
// Mark any incoming arguments as incomplete...
- if ((Flags & DSGraph::MarkFormalArgs) && Func && Func->getName() != "main")
- for (Function::aiterator I = Func->abegin(), E = Func->aend(); I != E; ++I)
- if (isPointerType(I->getType()) && ScalarMap.find(I) != ScalarMap.end())
- markIncompleteNode(ScalarMap[I].getNode());
+ if (Flags & DSGraph::MarkFormalArgs)
+ for (ReturnNodesTy::iterator FI = ReturnNodes.begin(), E =ReturnNodes.end();
+ FI != E; ++FI) {
+ Function &F = *FI->first;
+ if (F.getName() != "main")
+ for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
+ if (isPointerType(I->getType()) &&
+ ScalarMap.find(I) != ScalarMap.end())
+ markIncompleteNode(ScalarMap[I].getNode());
+ }
// Mark stuff passed into functions calls as being incomplete...
if (!shouldPrintAuxCalls())
@@ -954,8 +964,7 @@ static inline bool nodeContainsExternalFunction(const DSNode *N) {
return false;
}
-static void removeIdenticalCalls(std::vector<DSCallSite> &Calls,
- const std::string &where) {
+static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
// Remove trivially identical function calls
unsigned NumFns = Calls.size();
std::sort(Calls.begin(), Calls.end()); // Sort by callee as primary key!
@@ -1034,8 +1043,7 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls,
NumCallNodesMerged += NumFns-Calls.size();
DEBUG(if (NumFns != Calls.size())
- std::cerr << "Merged " << (NumFns-Calls.size())
- << " call nodes in " << where << "\n";);
+ std::cerr << "Merged " << (NumFns-Calls.size()) << " call nodes.\n";);
}
@@ -1045,8 +1053,8 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls,
// we don't have to perform any non-trivial analysis here.
//
void DSGraph::removeTriviallyDeadNodes() {
- removeIdenticalCalls(FunctionCalls, Func ? Func->getName() : "");
- removeIdenticalCalls(AuxFunctionCalls, Func ? Func->getName() : "");
+ removeIdenticalCalls(FunctionCalls);
+ removeIdenticalCalls(AuxFunctionCalls);
for (unsigned i = 0; i != Nodes.size(); ++i) {
DSNode *Node = Nodes[i];
@@ -1195,7 +1203,9 @@ void DSGraph::removeDeadNodes(unsigned Flags) {
}
// The return value is alive as well...
- RetNode.getNode()->markReachableNodes(Alive);
+ for (ReturnNodesTy::iterator I = ReturnNodes.begin(), E = ReturnNodes.end();
+ I != E; ++I)
+ I->second.getNode()->markReachableNodes(Alive);
// Mark any nodes reachable by primary calls as alive...
for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i)
diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp
index a7751f2..2b81d14 100644
--- a/lib/Analysis/DataStructure/Local.cpp
+++ b/lib/Analysis/DataStructure/Local.cpp
@@ -62,25 +62,26 @@ namespace {
/// graph by performing a single pass over the function in question.
///
class GraphBuilder : InstVisitor<GraphBuilder> {
+ Function &F;
DSGraph &G;
std::vector<DSNode*> &Nodes;
DSNodeHandle &RetNode; // Node that gets returned...
- hash_map<Value*, DSNodeHandle> &ScalarMap;
+ DSGraph::ScalarMapTy &ScalarMap;
std::vector<DSCallSite> &FunctionCalls;
public:
- GraphBuilder(DSGraph &g, std::vector<DSNode*> &nodes, DSNodeHandle &retNode,
- hash_map<Value*, DSNodeHandle> &SM,
+ GraphBuilder(Function &f, DSGraph &g, std::vector<DSNode*> &nodes,
+ DSNodeHandle &retNode, DSGraph::ScalarMapTy &SM,
std::vector<DSCallSite> &fc)
- : G(g), Nodes(nodes), RetNode(retNode), ScalarMap(SM), FunctionCalls(fc) {
+ : F(f), G(g), Nodes(nodes), RetNode(retNode), ScalarMap(SM),
+ FunctionCalls(fc) {
// Create scalar nodes for all pointer arguments...
- for (Function::aiterator I = G.getFunction().abegin(),
- E = G.getFunction().aend(); I != E; ++I)
+ for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
if (isPointerType(I->getType()))
getValueDest(*I);
- visit(G.getFunction()); // Single pass over the function
+ visit(F); // Single pass over the function
}
private:
@@ -139,10 +140,10 @@ namespace {
//===----------------------------------------------------------------------===//
// DSGraph constructor - Simply use the GraphBuilder to construct the local
// graph.
-DSGraph::DSGraph(Function &F, DSGraph *GG) : Func(&F), GlobalsGraph(GG) {
+DSGraph::DSGraph(Function &F, DSGraph *GG) : GlobalsGraph(GG) {
PrintAuxCalls = false;
// Use the graph builder to construct the local version of the graph
- GraphBuilder B(*this, Nodes, RetNode, ScalarMap, FunctionCalls);
+ GraphBuilder B(F, *this, Nodes, ReturnNodes[&F], ScalarMap, FunctionCalls);
#ifndef NDEBUG
Timer::addPeakMemoryMeasurement();
#endif
diff --git a/lib/Analysis/DataStructure/Printer.cpp b/lib/Analysis/DataStructure/Printer.cpp
index 50d8933..f568c8d 100644
--- a/lib/Analysis/DataStructure/Printer.cpp
+++ b/lib/Analysis/DataStructure/Printer.cpp
@@ -29,7 +29,10 @@ void DSNode::dump() const { print(std::cerr, 0); }
static std::string getCaption(const DSNode *N, const DSGraph *G) {
std::stringstream OS;
- Module *M = G && G->hasFunction() ? G->getFunction().getParent() : 0;
+ Module *M = 0;
+ // Get the module from ONE of the functions in the graph it is available.
+ if (G && !G->getReturnNodes().empty())
+ M = G->getReturnNodes().begin()->first->getParent();
if (N->isNodeCompletelyFolded())
OS << "FOLDED";
@@ -64,10 +67,16 @@ static std::string getCaption(const DSNode *N, const DSGraph *G) {
template<>
struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
static std::string getGraphName(const DSGraph *G) {
- if (G->hasFunction())
- return "Function " + G->getFunction().getName();
- else
- return "Global graph";
+ switch (G->getReturnNodes().size()) {
+ case 0: return "Global graph";
+ case 1: return "Function " + G->getReturnNodes().begin()->first->getName();
+ default:
+ std::string Return = "Functions: ";
+ for (DSGraph::ReturnNodesTy::const_iterator I=G->getReturnNodes().begin();
+ I != G->getReturnNodes().end(); ++I)
+ Return += I->first->getName() + " ";
+ return Return;
+ }
}
static const char *getGraphProperties(const DSGraph *G) {
@@ -88,12 +97,13 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
///
static void addCustomGraphFeatures(const DSGraph *G,
GraphWriter<const DSGraph*> &GW) {
- Module *CurMod = G->hasFunction() ? G->getFunction().getParent() : 0;
+ Module *CurMod = 0;
+ if (!G->getReturnNodes().empty())
+ CurMod = G->getReturnNodes().begin()->first->getParent();
// Add scalar nodes to the graph...
- const hash_map<Value*, DSNodeHandle> &VM = G->getScalarMap();
- for (hash_map<Value*, DSNodeHandle>::const_iterator I = VM.begin();
- I != VM.end(); ++I)
+ const DSGraph::ScalarMapTy &VM = G->getScalarMap();
+ for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
if (!isa<GlobalValue>(I->first)) {
std::stringstream OS;
WriteAsOperand(OS, I->first, false, true, CurMod);
@@ -108,16 +118,24 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
// Output the returned value pointer...
- if (G->getRetNode().getNode() != 0) {
- // Output the return node...
- GW.emitSimpleNode((void*)1, "plaintext=circle", "returning");
-
- // Add edge from return node to real destination
- int RetEdgeDest = G->getRetNode().getOffset() >> DS::PointerShift;;
- if (RetEdgeDest == 0) RetEdgeDest = -1;
- GW.emitEdge((void*)1, -1, G->getRetNode().getNode(),
- RetEdgeDest, "arrowtail=tee,color=gray63");
- }
+ const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
+ for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
+ E = RetNodes.end(); I != E; ++I)
+ if (I->second.getNode()) {
+ std::string Label;
+ if (RetNodes.size() == 1)
+ Label = "returning";
+ else
+ Label = I->first->getName() + " ret node";
+ // Output the return node...
+ GW.emitSimpleNode((void*)1, "plaintext=circle", Label);
+
+ // Add edge from return node to real destination
+ int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
+ if (RetEdgeDest == 0) RetEdgeDest = -1;
+ GW.emitEdge((void*)1, -1, I->second.getNode(),
+ RetEdgeDest, "arrowtail=tee,color=gray63");
+ }
// Output all of the call nodes...
const std::vector<DSCallSite> &FCs =
diff --git a/lib/Analysis/DataStructure/Steensgaard.cpp b/lib/Analysis/DataStructure/Steensgaard.cpp
index 2f37025..5db619d 100644
--- a/lib/Analysis/DataStructure/Steensgaard.cpp
+++ b/lib/Analysis/DataStructure/Steensgaard.cpp
@@ -111,7 +111,7 @@ bool Steens::run(Module &M) {
// RetValMap - Keep track of the return values for all functions that return
// valid pointers.
//
- hash_map<Function*, DSNodeHandle> RetValMap;
+ DSGraph::ReturnNodesTy RetValMap;
// Loop over the rest of the module, merging graphs for non-external functions
// into this graph.
@@ -119,22 +119,16 @@ bool Steens::run(Module &M) {
unsigned Count = 0;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isExternal()) {
- hash_map<Value*, DSNodeHandle> ValMap;
+ DSGraph::ScalarMapTy ValMap;
{ // Scope to free NodeMap memory ASAP
- hash_map<const DSNode*, DSNodeHandle> NodeMap;
+ DSGraph::NodeMapTy NodeMap;
const DSGraph &FDSG = LDS.getDSGraph(*I);
- DSNodeHandle RetNode = ResultGraph->cloneInto(FDSG, ValMap, NodeMap);
-
- // Keep track of the return node of the function's graph if it returns a
- // value...
- //
- if (RetNode.getNode())
- RetValMap[I] = RetNode;
+ ResultGraph->cloneInto(FDSG, ValMap, RetValMap, NodeMap);
}
// Incorporate the inlined Function's ScalarMap into the global
// ScalarMap...
- hash_map<Value*, DSNodeHandle> &GVM = ResultGraph->getScalarMap();
+ DSGraph::ScalarMapTy &GVM = ResultGraph->getScalarMap();
for (hash_map<Value*, DSNodeHandle>::iterator I = ValMap.begin(),
E = ValMap.end(); I != E; ++I)
GVM[I->first].mergeWith(I->second);
diff --git a/lib/Analysis/DataStructure/TopDownClosure.cpp b/lib/Analysis/DataStructure/TopDownClosure.cpp
index 06de437..85a79d1 100644
--- a/lib/Analysis/DataStructure/TopDownClosure.cpp
+++ b/lib/Analysis/DataStructure/TopDownClosure.cpp
@@ -57,6 +57,7 @@ void TDDataStructures::releaseMyMemory() {
GlobalsGraph = 0;
}
+#if 0
/// ResolveCallSite - This method is used to link the actual arguments together
/// with the formal arguments for a function call in the top-down closure. This
/// method assumes that the call site arguments have been mapped into nodes
@@ -82,6 +83,7 @@ void TDDataStructures::ResolveCallSite(DSGraph &Graph,
if (CallSite.getRetVal().getNode() && Graph.getRetNode().getNode())
Graph.getRetNode().mergeWith(CallSite.getRetVal());
}
+#endif
DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) {
DSGraph *&G = DSInfo[&F];
@@ -169,13 +171,15 @@ void TDDataStructures::calculateGraph(Function &F) {
<< "'\n");
// Clone our current graph into the callee...
- hash_map<Value*, DSNodeHandle> OldValMap;
- hash_map<const DSNode*, DSNodeHandle> OldNodeMap;
- CG.cloneInto(Graph, OldValMap, OldNodeMap,
+ DSGraph::ScalarMapTy OldValMap;
+ DSGraph::NodeMapTy OldNodeMap;
+ DSGraph::ReturnNodesTy ReturnNodes;
+ CG.cloneInto(Graph, OldValMap, ReturnNodes, OldNodeMap,
DSGraph::StripModRefBits |
DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
OldValMap.clear(); // We don't care about the ValMap
+ ReturnNodes.clear(); // We don't care about return values either
// Loop over all of the invocation sites of the callee, resolving
// arguments to our graph. This loop may iterate multiple times if the
@@ -187,7 +191,7 @@ void TDDataStructures::calculateGraph(Function &F) {
DSCallSite NewCS(*I->second, OldNodeMap);
// Resolve the return values...
- NewCS.getRetVal().mergeWith(CG.getRetNode());
+ NewCS.getRetVal().mergeWith(CG.getReturnNodeFor(Callee));
// Resolve all of the arguments...
Function::aiterator AI = Callee.abegin();