* Remove the concept of a critical shadow node
* Make the function pointer argument explicit for a call nodes
* Eliminate unreachable global values
* Merge call nodes that are identical


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2266 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/DataStructure/ComputeClosure.cpp b/lib/Analysis/DataStructure/ComputeClosure.cpp
index 30c21a3..67309e8 100644
--- a/lib/Analysis/DataStructure/ComputeClosure.cpp
+++ b/lib/Analysis/DataStructure/ComputeClosure.cpp
@@ -100,6 +100,8 @@
   NI = std::find_if(CallNodes.begin(), CallNodes.end(), isResolvableCallNode);
   while (NI != CallNodes.end()) {
     CallDSNode *CN = *NI;
+    // FIXME: This should work based on the pointer val set of the first arg
+    // link (which is the function to call)
     Function *F = CN->getCall()->getCalledFunction();
 
     if (NumInlines++ == 100) {      // CUTE hack huh?
@@ -181,14 +183,14 @@
                                   RetVals));
 
       // If the call node has arguments, process them now!
-      assert(Args.size() == CN->getNumArgs() &&
+      assert(Args.size() == CN->getNumArgs()-1 &&
              "Call node doesn't match function?");
 
       for (unsigned i = 0, e = Args.size(); i != e; ++i) {
         // Now we make all of the nodes inside of the incorporated method
         // point to the real arguments values, not to the shadow nodes for the
         // argument.
-        ResolveNodesTo(Args[i], CN->getArgValues(i));
+        ResolveNodesTo(Args[i], CN->getArgValues(i+1));
       }
 
       // Loop through the nodes, deleting alloca nodes in the inlined function.
@@ -231,4 +233,18 @@
     // Move on to the next call node...
     NI = std::find_if(CallNodes.begin(), CallNodes.end(), isResolvableCallNode);
   }
+
+  // Drop references to globals...
+  CallMap.clear();
+
+  bool Changed = true;
+  while (Changed) {
+    // Eliminate shadow nodes that are not distinguishable from some other
+    // node in the graph...
+    //
+    Changed = UnlinkUndistinguishableNodes();
+
+    // Eliminate shadow nodes that are now extraneous due to linking...
+    Changed |= RemoveUnreachableNodes();
+  }
 }