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.cpp120
1 files changed, 47 insertions, 73 deletions
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index 2f6fde8903..a84c4fe032 100644
--- a/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/lib/Analysis/DataStructure/DataStructure.cpp
@@ -1348,95 +1348,69 @@ void DSGraph::mergeInGraph(const DSCallSite &CS,
TIME_REGION(X, "mergeInGraph");
// 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.
- ReachabilityCloner RC(*this, Graph, CloneFlags);
+ if (&Graph == this) {
+ // Merge the return value with the return value of the context.
+ Args[0].mergeWith(CS.getRetVal());
- // Map the return node pointer over.
- if (!CS.getRetVal().isNull())
- RC.merge(CS.getRetVal(), Args[0]);
-
- // Map over all of the arguments.
+ // Resolve all of the function arguments.
for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) {
if (i == Args.size()-1)
break;
// Add the link from the argument scalar to the provided value.
- RC.merge(CS.getPtrArg(i), Args[i+1]);
+ Args[i+1].mergeWith(CS.getPtrArg(i));
}
+ return;
+ }
+
+ // 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.
+ ReachabilityCloner RC(*this, Graph, CloneFlags);
- // If requested, copy all of the calls.
- if (!(CloneFlags & DontCloneCallNodes)) {
- // Copy the function calls list.
- for (fc_iterator I = Graph.fc_begin(), E = Graph.fc_end(); I != E; ++I)
- FunctionCalls.push_back(DSCallSite(*I, RC));
- }
+ // Map the return node pointer over.
+ if (!CS.getRetVal().isNull())
+ RC.merge(CS.getRetVal(), Args[0]);
- // If the user has us copying aux calls (the normal case), set up a data
- // structure to keep track of which ones we've copied over.
- std::set<const DSCallSite*> CopiedAuxCall;
+ // Map over all of the arguments.
+ for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) {
+ if (i == Args.size()-1)
+ break;
+
+ // Add the link from the argument scalar to the provided value.
+ RC.merge(CS.getPtrArg(i), Args[i+1]);
+ }
- // Clone over all globals that appear in the caller and callee graphs.
- hash_set<GlobalVariable*> NonCopiedGlobals;
- for (DSScalarMap::global_iterator GI = Graph.getScalarMap().global_begin(),
- E = Graph.getScalarMap().global_end(); GI != E; ++GI)
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*GI))
- if (ScalarMap.count(GV))
- RC.merge(ScalarMap[GV], Graph.getNodeForValue(GV));
- else
- NonCopiedGlobals.insert(GV);
+ // If requested, copy all of the calls.
+ if (!(CloneFlags & DontCloneCallNodes)) {
+ // Copy the function calls list.
+ for (fc_iterator I = Graph.fc_begin(), E = Graph.fc_end(); I != E; ++I)
+ FunctionCalls.push_back(DSCallSite(*I, RC));
+ }
+
+ // If the user has us copying aux calls (the normal case), set up a data
+ // structure to keep track of which ones we've copied over.
+ std::set<const DSCallSite*> CopiedAuxCall;
- // If the global does not appear in the callers graph we generally don't
- // want to copy the node. However, if there is a path from the node global
- // node to a node that we did copy in the graph, we *must* copy it to
- // maintain the connection information. Every time we decide to include a
- // new global, this might make other globals live, so we must iterate
- // unfortunately.
- bool MadeChange = true;
+ // If the global does not appear in the callers graph we generally don't
+ // want to copy the node. However, if there is a path from the node global
+ // node to a node that we did copy in the graph, we *must* copy it to
+ // maintain the connection information. Every time we decide to include a
+ // new global, this might make other globals live, so we must iterate
+ // unfortunately.
+ bool MadeChange = true;
+ if (!(CloneFlags & DontCloneAuxCallNodes))
while (MadeChange) {
MadeChange = false;
- for (hash_set<GlobalVariable*>::iterator I = NonCopiedGlobals.begin();
- I != NonCopiedGlobals.end();) {
- DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode();
- if (RC.hasClonedNode(GlobalNode)) {
- // Already cloned it, remove from set.
- NonCopiedGlobals.erase(I++);
- MadeChange = true;
- } else if (PathExistsToClonedNode(GlobalNode, RC)) {
- RC.getClonedNH(Graph.getNodeForValue(*I));
- NonCopiedGlobals.erase(I++);
- MadeChange = true;
- } else {
- ++I;
- }
- }
// If requested, copy any aux calls that can reach copied nodes.
- if (!(CloneFlags & DontCloneAuxCallNodes)) {
- for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
- if (CopiedAuxCall.insert(&*I).second &&
- PathExistsToClonedNode(*I, RC)) {
- AuxFunctionCalls.push_back(DSCallSite(*I, RC));
- MadeChange = true;
- }
- }
- }
-
- } else {
- // Merge the return value with the return value of the context.
- Args[0].mergeWith(CS.getRetVal());
-
- // Resolve all of the function arguments.
- for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) {
- if (i == Args.size()-1)
- break;
-
- // Add the link from the argument scalar to the provided value.
- Args[i+1].mergeWith(CS.getPtrArg(i));
+ for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
+ if (CopiedAuxCall.insert(&*I).second &&
+ PathExistsToClonedNode(*I, RC)) {
+ AuxFunctionCalls.push_back(DSCallSite(*I, RC));
+ MadeChange = true;
+ }
}
- }
}