aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure/DataStructure.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/DataStructure/DataStructure.cpp')
-rw-r--r--lib/Analysis/DataStructure/DataStructure.cpp52
1 files changed, 52 insertions, 0 deletions
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).