Implement optimization for direct function call case.  This dramatically
reduces the number of function nodes created and speeds up analysis by
about 10% overall.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5495 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index badc9c0..cf117bb 100644
--- a/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/lib/Analysis/DataStructure/DataStructure.cpp
@@ -799,7 +799,8 @@
   std::sort(Calls.begin(), Calls.end());  // Sort by callee as primary key!
 
   // Scan the call list cleaning it up as necessary...
-  DSNode *LastCalleeNode = 0;
+  DSNode   *LastCalleeNode = 0;
+  Function *LastCalleeFunc = 0;
   unsigned NumDuplicateCalls = 0;
   bool LastCalleeContainsExternalFunction = false;
   for (unsigned i = 0; i != Calls.size(); ++i) {
@@ -807,8 +808,9 @@
 
     // If the Callee is a useless edge, this must be an unreachable call site,
     // eliminate it.
-    killIfUselessEdge(CS.getCallee());
-    if (CS.getCallee().getNode() == 0) {
+    if (CS.isIndirectCall() && CS.getCalleeNode()->getReferrers().size() == 1 &&
+        CS.getCalleeNode()->NodeType == 0) {  // No useful info?
+      std::cerr << "WARNING: Useless call site found??\n";
       CS.swap(Calls.back());
       Calls.pop_back();
       --i;
@@ -826,11 +828,15 @@
       // never be resolved.  Merge the arguments of the call node because no
       // information will be lost.
       //
-      if (CS.getCallee().getNode() == LastCalleeNode) {
+      if ((CS.isDirectCall()   && CS.getCalleeFunc() == LastCalleeFunc) ||
+          (CS.isIndirectCall() && CS.getCalleeNode() == LastCalleeNode)) {
         ++NumDuplicateCalls;
         if (NumDuplicateCalls == 1) {
-          LastCalleeContainsExternalFunction =
-            nodeContainsExternalFunction(LastCalleeNode);
+          if (LastCalleeNode)
+            LastCalleeContainsExternalFunction =
+              nodeContainsExternalFunction(LastCalleeNode);
+          else
+            LastCalleeContainsExternalFunction = LastCalleeFunc->isExternal();
         }
         
         if (LastCalleeContainsExternalFunction ||
@@ -847,7 +853,13 @@
             OCS = CS;
         }
       } else {
-        LastCalleeNode = CS.getCallee().getNode();
+        if (CS.isDirectCall()) {
+          LastCalleeFunc = CS.getCalleeFunc();
+          LastCalleeNode = 0;
+        } else {
+          LastCalleeNode = CS.getCalleeNode();
+          LastCalleeFunc = 0;
+        }
         NumDuplicateCalls = 0;
       }
     }
@@ -877,7 +889,7 @@
   for (unsigned i = 0; i != Nodes.size(); ++i) {
     DSNode *Node = Nodes[i];
     if (!(Node->NodeType & ~(DSNode::Composition | DSNode::Array |
-                                 DSNode::DEAD))) {
+                             DSNode::DEAD))) {
       // This is a useless node if it has no mod/ref info (checked above),
       // outgoing edges (which it cannot, as it is not modified in this
       // context), and it has no incoming edges.  If it is a global node it may
@@ -918,7 +930,7 @@
 
 void DSCallSite::markReachableNodes(hash_set<DSNode*> &Nodes) {
   getRetVal().getNode()->markReachableNodes(Nodes);
-  getCallee().getNode()->markReachableNodes(Nodes);
+  if (isIndirectCall()) getCalleeNode()->markReachableNodes(Nodes);
   
   for (unsigned i = 0, e = getNumPtrArgs(); i != e; ++i)
     getPtrArg(i).getNode()->markReachableNodes(Nodes);
@@ -954,8 +966,10 @@
 //
 static bool CallSiteUsesAliveArgs(DSCallSite &CS, hash_set<DSNode*> &Alive,
                                   hash_set<DSNode*> &Visited) {
-  if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited) ||
-      CanReachAliveNodes(CS.getCallee().getNode(), Alive, Visited))
+  if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited))
+    return true;
+  if (CS.isIndirectCall() &&
+      CanReachAliveNodes(CS.getCalleeNode(), Alive, Visited))
     return true;
   for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i)
     if (CanReachAliveNodes(CS.getPtrArg(i).getNode(), Alive, Visited))