aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/DataStructure')
-rw-r--r--lib/Analysis/DataStructure/BottomUpClosure.cpp48
-rw-r--r--lib/Analysis/DataStructure/DataStructure.cpp52
-rw-r--r--lib/Analysis/DataStructure/TopDownClosure.cpp60
3 files changed, 86 insertions, 74 deletions
diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp
index 02a9e64408..cbe53ce68e 100644
--- a/lib/Analysis/DataStructure/BottomUpClosure.cpp
+++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp
@@ -46,29 +46,6 @@ bool BUDataStructures::run(Module &M) {
return false;
}
-// ResolveArguments - Resolve the formal and actual arguments for a function
-// call.
-//
-static void ResolveArguments(DSCallSite &Call, Function &F,
- map<Value*, DSNodeHandle> &ScalarMap) {
- // Resolve all of the function arguments...
- Function::aiterator AI = F.abegin();
- for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i, ++AI) {
- // Advance the argument iterator to the first pointer argument...
- while (!isPointerType(AI->getType())) {
- ++AI;
-#ifndef NDEBUG
- if (AI == F.aend())
- std::cerr << "Bad call to Function: " << F.getName() << "\n";
-#endif
- assert(AI != F.aend() && "# Args provided is not # Args required!");
- }
-
- // Add the link from the argument scalar to the provided value
- ScalarMap[AI].mergeWith(Call.getPtrArg(i));
- }
-}
-
DSGraph &BUDataStructures::calculateGraph(Function &F) {
// Make sure this graph has not already been calculated, or that we don't get
// into an infinite loop with mutually recursive functions.
@@ -115,11 +92,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
// actual arguments...
DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n");
- // Handle the return value if present...
- Graph->getRetNode().mergeWith(Call.getRetVal());
-
- // Resolve the arguments in the call to the actual values...
- ResolveArguments(Call, F, Graph->getScalarMap());
+ // Handle self recursion by resolving the arguments and return value
+ Graph->mergeInGraph(Call, *Graph, true);
// Erase the entry in the callees vector
Callees.erase(Callees.begin()+c--);
@@ -145,22 +119,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
CallSitesForFunc.back().setResolvingCaller(&F);
CallSitesForFunc.back().setCallee(0);
- // 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.
- map<Value*, DSNodeHandle> OldValMap;
- map<const DSNode*, DSNode*> 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
- DSNodeHandle RetVal = Graph->cloneInto(GI, OldValMap, OldNodeMap,
- /*StripAllocas*/ true);
-
- // Resolve the arguments in the call to the actual values...
- ResolveArguments(Call, FI, OldValMap);
-
- // Handle the return value if present...
- RetVal.mergeWith(Call.getRetVal());
+ // Handle self recursion by resolving the arguments and return value
+ Graph->mergeInGraph(Call, GI, true);
// Erase the entry in the Callees vector
Callees.erase(Callees.begin()+c--);
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index ff2a4b8e0a..41cd7185ec 100644
--- a/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/lib/Analysis/DataStructure/DataStructure.cpp
@@ -90,6 +90,7 @@ void DSNode::foldNodeCompletely() {
Links[0].mergeWith(Links[i]);
Links.resize(1);
}
+
/// isNodeCompletelyFolded - Return true if this node has been completely
/// folded down to something that can never be expanded, effectively losing
/// all of the field sensitivity that may be present in the node.
@@ -573,6 +574,57 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
return DSNodeHandle(OldNodeMap[G.RetNode.getNode()], G.RetNode.getOffset());
}
+/// mergeInGraph - The method is used for merging graphs together. If the
+/// argument graph is not *this, it makes a clone of the specified graph, then
+/// merges the nodes specified in the call site with the formal arguments in the
+/// graph.
+///
+void DSGraph::mergeInGraph(DSCallSite &CS, const DSGraph &Graph,
+ bool StripAllocas) {
+ std::map<Value*, DSNodeHandle> OldValMap;
+ DSNodeHandle RetVal;
+ std::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.
+ std::map<const DSNode*, DSNode*> 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, StripAllocas);
+ ScalarMap = &OldValMap;
+ } else {
+ RetVal = getRetNode();
+ ScalarMap = &getScalarMap();
+ }
+
+ // Merge the return value with the return value of the context...
+ 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) {
+ // Advance the argument iterator to the first pointer argument...
+ while (!isPointerType(AI->getType())) {
+ ++AI;
+#ifndef NDEBUG
+ if (AI == F.aend())
+ std::cerr << "Bad call to Function: " << F.getName() << "\n";
+#endif
+ assert(AI != F.aend() && "# Args provided is not # Args required!");
+ }
+
+ // Add the link from the argument scalar to the provided value
+ DSNodeHandle &NH = (*ScalarMap)[AI];
+ assert(NH.getNode() && "Pointer argument without scalarmap entry?");
+ NH.mergeWith(CS.getPtrArg(i));
+ }
+}
+
#if 0
// cloneGlobalInto - Clone the given global node and all its target links
// (and all their llinks, recursively).
diff --git a/lib/Analysis/DataStructure/TopDownClosure.cpp b/lib/Analysis/DataStructure/TopDownClosure.cpp
index 69422caa8f..817e734a9c 100644
--- a/lib/Analysis/DataStructure/TopDownClosure.cpp
+++ b/lib/Analysis/DataStructure/TopDownClosure.cpp
@@ -149,36 +149,36 @@ DSGraph &TDDataStructures::calculateGraph(Function &F) {
DEBUG(std::cerr << "\t [TD] Inlining caller #" << c << " '"
<< Caller.getName() << "' into callee: " << F.getName() << "\n");
- if (&Caller == &F) {
- // Self-recursive call: this can happen after a cycle of calls is inlined.
- ResolveCallSite(*Graph, CallSite);
- } else {
-
- // Recursively compute the graph for the Caller. It should be fully
- // resolved except if there is mutual recursion...
- //
- DSGraph &CG = calculateGraph(Caller); // Graph to inline
-
- DEBUG(std::cerr << "\t\t[TD] Got graph for " << Caller.getName()
- << " in: " << F.getName() << "\n");
-
- // These two maps keep track of where scalars in the old graph _used_
- // to point to, and of new nodes matching nodes of the old graph.
- std::map<Value*, DSNodeHandle> OldValMap;
- std::map<const DSNode*, DSNode*> OldNodeMap;
-
- // Translate call site from having links into the BU graph
- DSCallSite CallSiteInCG(CallSite, BUMaps[&Caller]);
-
- // Clone the Caller's graph into the current graph, keeping
- // track of where scalars in the old graph _used_ to point...
- // Do this here because it only needs to happens once for each Caller!
- // Strip scalars but not allocas since they are alive in callee.
- //
- DSNodeHandle RetVal = Graph->cloneInto(CG, OldValMap, OldNodeMap,
- /*StripAllocas*/ false);
- ResolveCallSite(*Graph, DSCallSite(CallSiteInCG, OldNodeMap));
- }
+ // Self recursion is not tracked in BU pass...
+ assert(&Caller != &F && "This cannot happen!\n");
+
+ // Recursively compute the graph for the Caller. It should be fully
+ // resolved except if there is mutual recursion...
+ //
+ DSGraph &CG = calculateGraph(Caller); // Graph to inline
+
+ DEBUG(std::cerr << "\t\t[TD] Got graph for " << Caller.getName()
+ << " in: " << F.getName() << "\n");
+
+ // Translate call site from having links into the BU graph
+ DSCallSite CallSiteInCG(CallSite, BUMaps[&Caller]);
+
+ // These two maps keep track of where scalars in the old graph _used_
+ // to point to, and of new nodes matching nodes of the old graph.
+ std::map<Value*, DSNodeHandle> OldValMap;
+ std::map<const DSNode*, DSNode*> OldNodeMap;
+
+ // FIXME: Eventually use DSGraph::mergeInGraph here...
+ // Graph->mergeInGraph(CallSiteInCG, CG, false);
+
+ // Clone the Caller's graph into the current graph, keeping
+ // track of where scalars in the old graph _used_ to point...
+ // Do this here because it only needs to happens once for each Caller!
+ // Strip scalars but not allocas since they are alive in callee.
+ //
+ DSNodeHandle RetVal = Graph->cloneInto(CG, OldValMap, OldNodeMap,
+ /*StripAllocas*/ false);
+ ResolveCallSite(*Graph, DSCallSite(CallSiteInCG, OldNodeMap));
}
// Recompute the Incomplete markers and eliminate unreachable nodes.