[llvm-commits] [poolalloc] r56857 - in /poolalloc/trunk/lib/DSA: BottomUpClosure.cpp CallTargets.cpp DataStructure.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Tue Sep 30 10:11:51 PDT 2008


Author: alenhar2
Date: Tue Sep 30 12:11:50 2008
New Revision: 56857

URL: http://llvm.org/viewvc/llvm-project?rev=56857&view=rev
Log:
inline graph whenever possible, but don't propagate unresolved call nodes if not inlining complete nodes.  Greatly improves precision.

Modified:
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/CallTargets.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp

Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=56857&r1=56856&r2=56857&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Sep 30 12:11:50 2008
@@ -129,6 +129,25 @@
     CS.getCalleeNode()->addFullFunctionList(Callees);
     
     // If any of the callees are unresolvable, remove the whole batch!
+    for (unsigned i = OldSize; i != Callees.size(); )
+      if (Callees[i]->isDeclaration()) {
+        Callees.erase(Callees.begin()+i);
+      } else 
+        ++i;
+  }
+}
+
+static void GetAnyCallees(const DSCallSite &CS,
+                          std::vector<Function*> &Callees) {
+  if (CS.isDirectCall()) {
+    if (!CS.getCalleeFunc()->isDeclaration())
+      Callees.push_back(CS.getCalleeFunc());
+  } else {
+    // Get all callees.
+    unsigned OldSize = Callees.size();
+    CS.getCalleeNode()->addFullFunctionList(Callees);
+    
+    // If any of the callees are unresolvable, remove the whole batch!
     for (unsigned i = OldSize, e = Callees.size(); i != e; ++i)
       if (Callees[i]->isDeclaration()) {
         Callees.erase(Callees.begin()+OldSize, Callees.end());
@@ -145,6 +164,14 @@
     GetAllCallees(*I, Callees);
 }
 
+/// GetAnyAuxCallees - Return a list containing all of the callees in
+/// the aux list for the specified graph in the Callees vector.
+static void GetAnyAuxCallees(DSGraph &G, std::vector<Function*> &Callees) {
+  Callees.clear();
+  for (DSGraph::afc_iterator I = G.afc_begin(), E = G.afc_end(); I != E; ++I)
+    GetAnyCallees(*I, Callees);
+}
+
 unsigned BUDataStructures::calculateGraphs(Function *F,
                                            std::vector<Function*> &Stack,
                                            unsigned &NextID,
@@ -168,7 +195,7 @@
 
   // Find all callee functions.
   std::vector<Function*> CalleeFunctions;
-  GetAllAuxCallees(Graph, CalleeFunctions);
+  GetAnyAuxCallees(Graph, CalleeFunctions);
 
   // The edges out of the current node are the call site targets...
   for (unsigned i = 0, e = CalleeFunctions.size(); i != e; ++i) {
@@ -202,8 +229,9 @@
 
     // Should we revisit the graph?  Only do it if there are now new resolvable
     // callees.
-    GetAllAuxCallees(Graph, CalleeFunctions);
-    if (!CalleeFunctions.empty()) {
+    std::vector<Function*> CalleeFunctionsNew;
+    GetAnyAuxCallees(Graph, CalleeFunctionsNew);
+    if (CalleeFunctionsNew.size() > CalleeFunctions.size()) {
       DOUT << "Recalculating " << F->getName() << " due to new knowledge\n";
       ValMap.erase(F);
       return calculateGraphs(F, Stack, NextID, ValMap);
@@ -340,107 +368,115 @@
     }
 
     GetAllCallees(CS, CalledFuncs);
+    bool isComplete = true;
 
     if (CalledFuncs.empty()) {
       // Remember that we could not resolve this yet!
       AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
+      isComplete = false;
+      GetAnyCallees(CS, CalledFuncs);
+    }
+    
+    if (CalledFuncs.empty())
       continue;
-    } else {
-      DSGraph *GI;
-      Instruction *TheCall = CS.getCallSite().getInstruction();
-
-      if (CalledFuncs.size() == 1) {
-        Function *Callee = CalledFuncs[0];
-        ActualCallees.insert(std::make_pair(TheCall, Callee));
-
-        // Get the data structure graph for the called function.
-        GI = &getDSGraph(*Callee);  // Graph to inline
-        DOUT << "    Inlining graph for " << Callee->getName()
-             << "[" << GI->getGraphSize() << "+"
-             << GI->getAuxFunctionCalls().size() << "] into '"
-             << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
-             << Graph.getAuxFunctionCalls().size() << "]\n";
-        Graph.mergeInGraph(CS, *Callee, *GI,
-                           DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
-        ++NumBUInlines;
-      } else {
-        if (!Printed)
-          DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
-          DEBUG(std::cerr << "  calls " << CalledFuncs.size()
-                  << " fns from site: " << CS.getCallSite().getInstruction()
-                  << "  " << *CS.getCallSite().getInstruction());
-        DEBUG(std::cerr << "   Fns =");
-        unsigned NumPrinted = 0;
-
-        for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
-               E = CalledFuncs.end(); I != E; ++I) {
-          if (NumPrinted++ < 8) cerr << " " << (*I)->getName();
 
-          // Add the call edges to the call graph.
-          ActualCallees.insert(std::make_pair(TheCall, *I));
-        }
-        cerr << "\n";
-
-        // See if we already computed a graph for this set of callees.
-        std::sort(CalledFuncs.begin(), CalledFuncs.end());
-        std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
-          (*IndCallGraphMap)[CalledFuncs];
-
-        if (IndCallGraph.first == 0) {
-          std::vector<Function*>::iterator I = CalledFuncs.begin(),
-            E = CalledFuncs.end();
-
-          // Start with a copy of the first graph.
-          GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
-          GI->setGlobalsGraph(Graph.getGlobalsGraph());
-          std::vector<DSNodeHandle> &Args = IndCallGraph.second;
-
-          // Get the argument nodes for the first callee.  The return value is
-          // the 0th index in the vector.
-          GI->getFunctionArgumentsForCall(*I, Args);
-
-          // Merge all of the other callees into this graph.
-          for (++I; I != E; ++I) {
-            // If the graph already contains the nodes for the function, don't
-            // bother merging it in again.
-            if (!GI->containsFunction(*I)) {
-              GI->cloneInto(getDSGraph(**I));
-              ++NumBUInlines;
-            }
-
-            std::vector<DSNodeHandle> NextArgs;
-            GI->getFunctionArgumentsForCall(*I, NextArgs);
-            unsigned i = 0, e = Args.size();
-            for (; i != e; ++i) {
-              if (i == NextArgs.size()) break;
-              Args[i].mergeWith(NextArgs[i]);
-            }
-            for (e = NextArgs.size(); i != e; ++i)
-              Args.push_back(NextArgs[i]);
+    DSGraph *GI;
+    Instruction *TheCall = CS.getCallSite().getInstruction();
+    
+    if (CalledFuncs.size() == 1) {
+      Function *Callee = CalledFuncs[0];
+      ActualCallees.insert(std::make_pair(TheCall, Callee));
+      
+      // Get the data structure graph for the called function.
+      GI = &getDSGraph(*Callee);  // Graph to inline
+      DOUT << "    Inlining graph for " << Callee->getName()
+           << "[" << GI->getGraphSize() << "+"
+           << GI->getAuxFunctionCalls().size() << "] into '"
+           << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+           << Graph.getAuxFunctionCalls().size() << "]\n";
+      Graph.mergeInGraph(CS, *Callee, *GI,
+                         DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes|
+                         (isComplete?0:DSGraph::DontCloneAuxCallNodes));
+      ++NumBUInlines;
+    } else {
+      if (!Printed)
+        DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
+      DEBUG(std::cerr << "  calls " << CalledFuncs.size()
+            << " fns from site: " << CS.getCallSite().getInstruction()
+            << "  " << *CS.getCallSite().getInstruction());
+      DEBUG(std::cerr << "   Fns =");
+      unsigned NumPrinted = 0;
+      
+      for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
+             E = CalledFuncs.end(); I != E; ++I) {
+        if (NumPrinted++ < 8) DOUT << " " << (*I)->getName();
+        
+        // Add the call edges to the call graph.
+        ActualCallees.insert(std::make_pair(TheCall, *I));
+      }
+      DOUT << "\n";
+      
+      // See if we already computed a graph for this set of callees.
+      std::sort(CalledFuncs.begin(), CalledFuncs.end());
+      std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
+        (*IndCallGraphMap)[CalledFuncs];
+      
+      if (IndCallGraph.first == 0) {
+        std::vector<Function*>::iterator I = CalledFuncs.begin(),
+          E = CalledFuncs.end();
+        
+        // Start with a copy of the first graph.
+        GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
+        GI->setGlobalsGraph(Graph.getGlobalsGraph());
+        std::vector<DSNodeHandle> &Args = IndCallGraph.second;
+        
+        // Get the argument nodes for the first callee.  The return value is
+        // the 0th index in the vector.
+        GI->getFunctionArgumentsForCall(*I, Args);
+        
+        // Merge all of the other callees into this graph.
+        for (++I; I != E; ++I) {
+          // If the graph already contains the nodes for the function, don't
+          // bother merging it in again.
+          if (!GI->containsFunction(*I)) {
+            GI->cloneInto(getDSGraph(**I));
+            ++NumBUInlines;
           }
-
-          // Clean up the final graph!
-          GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-        } else {
-          cerr << "***\n*** RECYCLED GRAPH ***\n***\n";
+          
+          std::vector<DSNodeHandle> NextArgs;
+          GI->getFunctionArgumentsForCall(*I, NextArgs);
+          unsigned i = 0, e = Args.size();
+          for (; i != e; ++i) {
+            if (i == NextArgs.size()) break;
+            Args[i].mergeWith(NextArgs[i]);
+          }
+          for (e = NextArgs.size(); i != e; ++i)
+            Args.push_back(NextArgs[i]);
         }
-
-        GI = IndCallGraph.first;
-
-        // Merge the unified graph into this graph now.
-        DOUT << "    Inlining multi callee graph "
-             << "[" << GI->getGraphSize() << "+"
-             << GI->getAuxFunctionCalls().size() << "] into '"
-             << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
-             << Graph.getAuxFunctionCalls().size() << "]\n";
-
-        Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
-                           DSGraph::StripAllocaBit |
-                           DSGraph::DontCloneCallNodes);
-        ++NumBUInlines;
+        
+        // Clean up the final graph!
+        GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
+      } else {
+        DOUT << "***\n*** RECYCLED GRAPH ***\n***\n";
       }
+      
+      GI = IndCallGraph.first;
+      
+      // Merge the unified graph into this graph now.
+      DOUT << "    Inlining multi callee graph "
+           << "[" << GI->getGraphSize() << "+"
+           << GI->getAuxFunctionCalls().size() << "] into '"
+           << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+           << Graph.getAuxFunctionCalls().size() << "]\n";
+      
+      Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
+                         DSGraph::StripAllocaBit |
+                         DSGraph::DontCloneCallNodes|
+                         (isComplete?0:DSGraph::DontCloneAuxCallNodes));
+      ++NumBUInlines;
     }
-    TempFCs.erase(TempFCs.begin());
+    if (isComplete)
+      TempFCs.erase(TempFCs.begin());
   }
 
   // Recompute the Incomplete markers

Modified: poolalloc/trunk/lib/DSA/CallTargets.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CallTargets.cpp?rev=56857&r1=56856&r2=56857&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/CallTargets.cpp (original)
+++ poolalloc/trunk/lib/DSA/CallTargets.cpp Tue Sep 30 12:11:50 2008
@@ -77,7 +77,6 @@
 
 void CallTargetFinder::print(std::ostream &O, const Module *M) const
 {
-  return;
   O << "[* = incomplete] CS: func list\n";
   for (std::map<CallSite, std::vector<Function*> >::const_iterator ii =
        IndMap.begin(),

Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=56857&r1=56856&r2=56857&view=diff

==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Sep 30 12:11:50 2008
@@ -1368,7 +1368,6 @@
     DestCS.addPtrArg(getClonedNH(SrcCS.getPtrArg(a)));
 }
 
-
 //===----------------------------------------------------------------------===//
 // DSCallSite Implementation
 //===----------------------------------------------------------------------===//
@@ -1493,14 +1492,14 @@
 void DSGraph::removeFunctionCalls(Function& F) {
   for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
          E = FunctionCalls.end(); I != E; ++I)
-    if (I->isDirectCall() && &I->getCaller() == &F) {
+    if (I->isDirectCall() && I->getCalleeFunc() == &F) {
       FunctionCalls.erase(I);
       break;
     }
 
   for (std::list<DSCallSite>::iterator I = AuxFunctionCalls.begin(),
          E = AuxFunctionCalls.end(); I != E; ++I)
-    if (I->isDirectCall() && &I->getCaller() == &F) {
+    if (I->isDirectCall() && I->getCalleeFunc() == &F) {
       AuxFunctionCalls.erase(I);
       break;
     }
@@ -2747,7 +2746,7 @@
     //Clone or Steal the Source Graph
     DSGraph &BaseGraph = GraphSource->getDSGraph(*F);
     if (Clone) {
-      G = new DSGraph(BaseGraph, GlobalECs);
+      G = new DSGraph(BaseGraph, GlobalECs, DSGraph::DontCloneAuxCallNodes);
     } else {
       G = new DSGraph(GlobalECs, GraphSource->getTargetData());
       G->spliceFrom(BaseGraph);





More information about the llvm-commits mailing list