[llvm-commits] [poolalloc] r98921 - in /poolalloc/trunk: include/dsa/DSCallGraph.h lib/DSA/BottomUpClosure.cpp lib/DSA/DSCallGraph.cpp lib/DSA/DSGraph.cpp lib/DSA/Local.cpp

Andrew Lenharth andrewl at lenharth.org
Thu Mar 18 19:58:30 PDT 2010


Author: alenhar2
Date: Thu Mar 18 21:58:30 2010
New Revision: 98921

URL: http://llvm.org/viewvc/llvm-project?rev=98921&view=rev
Log:
remove callnodes condition implemented for partial-knowledge inlining.  Also add some stats to see if the results are believable

Modified:
    poolalloc/trunk/include/dsa/DSCallGraph.h
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/DSCallGraph.cpp
    poolalloc/trunk/lib/DSA/DSGraph.cpp
    poolalloc/trunk/lib/DSA/Local.cpp

Modified: poolalloc/trunk/include/dsa/DSCallGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSCallGraph.h?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSCallGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSCallGraph.h Thu Mar 18 21:58:30 2010
@@ -68,7 +68,9 @@
   typedef llvm::EquivalenceClasses<const llvm::Function*>::member_iterator scc_iterator;
 
   void insert(llvm::CallSite CS, const llvm::Function* F);
-  
+
+  void insureEntry(const llvm::Function* F);
+
   template<class Iterator>
   void insert(llvm::CallSite CS, Iterator _begin, Iterator _end) {
     for (; _begin != _end; ++_begin)
@@ -153,6 +155,10 @@
     return sum;
   }
 
+  unsigned flat_size() const {
+    return SimpleCallees.size();
+  }
+
   void buildSCCs();
 
   void buildRoots();

Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Thu Mar 18 21:58:30 2010
@@ -29,6 +29,9 @@
   STATISTIC (NumInlines, "Number of graphs inlined");
   STATISTIC (NumCallEdges, "Number of 'actual' call edges");
   STATISTIC (NumSCCMerges, "Number of SCC merges");
+  STATISTIC (NumIndResolved, "Number of resolved IndCalls");
+  STATISTIC (NumIndUnresolved, "Number of unresolved IndCalls");
+  STATISTIC (NumEmptyCalls, "Number of calls we know nothing about");
 
   RegisterPass<BUDataStructures>
   X("dsa-bu", "Bottom-up Data Structure Analysis");
@@ -269,6 +272,9 @@
   }
 }
 
+
+//Inline all graphs in the callgraph, remove callsites that are completely dealt
+//with
 void BUDataStructures::calculateGraph(DSGraph* Graph) {
   DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
 
@@ -297,14 +303,11 @@
   std::list<DSCallSite> &AuxCallsList = Graph->getAuxFunctionCalls();
   TempFCs.swap(AuxCallsList);
 
-  std::vector<const Function*> CalledFuncs;
   while (!TempFCs.empty()) {
     DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
     
     DSCallSite &CS = *TempFCs.begin();
 
-    CalledFuncs.clear();
-
     // Fast path for noop calls.  Note that we don't care about merging globals
     // in the callee with nodes in the caller here.
     if (CS.getRetVal().isNull() && CS.getNumPtrArgs() == 0) {
@@ -312,21 +315,51 @@
       continue;
     }
 
-    std::copy(callgraph.callee_begin(CS.getCallSite()),
-              callgraph.callee_end(CS.getCallSite()),
-              std::back_inserter(CalledFuncs));
-
-    std::vector<const Function*>::iterator ErasePoint =
-            std::remove_if(CalledFuncs.begin(), CalledFuncs.end(),
-                           std::mem_fun(&Function::isDeclaration));
-    CalledFuncs.erase(ErasePoint, CalledFuncs.end());
+    std::vector<const Function*> CalledFuncs;
+    //Get the callees from the callgraph
+    {
+      std::copy(callgraph.callee_begin(CS.getCallSite()),
+                callgraph.callee_end(CS.getCallSite()),
+                std::back_inserter(CalledFuncs));
+
+      std::vector<const Function*>::iterator ErasePoint =
+              std::remove_if(CalledFuncs.begin(), CalledFuncs.end(),
+                             std::mem_fun(&Function::isDeclaration));
+      CalledFuncs.erase(ErasePoint, CalledFuncs.end());
+    }
 
     if (CalledFuncs.empty()) {
+      ++NumEmptyCalls;
       // Remember that we could not resolve this yet!
       AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
       continue;
     }
 
+    //Direct calls are always inlined and removed from AuxCalls
+    //Indirect calls are removed if the callnode is complete and the callnode's
+    //functions set is a subset of the Calls from the callgraph
+    //We only inline from the callgraph (which is immutable during this phase
+    //of bu) so as to not introduce SCCs and still be able to inline
+    //aggressively
+    bool eraseCS = true;
+    if (CS.isIndirectCall()) {
+      eraseCS = false;
+      if (CS.getCalleeNode()->isCompleteNode()) {
+        std::vector<const Function*> NodeCallees;
+        CS.getCalleeNode()->addFullFunctionList(NodeCallees);
+        std::vector<const Function*>::iterator ErasePoint =
+                std::remove_if(NodeCallees.begin(), NodeCallees.end(),
+                               std::mem_fun(&Function::isDeclaration));
+        NodeCallees.erase(ErasePoint, NodeCallees.end());
+        std::sort(CalledFuncs.begin(), CalledFuncs.end());
+        std::sort(NodeCallees.begin(), NodeCallees.end());
+        eraseCS = std::includes(CalledFuncs.begin(), CalledFuncs.end(),
+                                NodeCallees.begin(), NodeCallees.end());
+      }
+      if (eraseCS) ++NumIndResolved;
+      else ++NumIndUnresolved;
+    }
+
     DSGraph *GI;
 
     for (unsigned x = 0; x < CalledFuncs.size(); ++x) {
@@ -345,7 +378,10 @@
       ++NumInlines;
       DEBUG(Graph->AssertGraphOK(););
     }
-    TempFCs.erase(TempFCs.begin());
+    if (eraseCS)
+      TempFCs.erase(TempFCs.begin());
+    else
+      AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
   }
 
   // Recompute the Incomplete markers

Modified: poolalloc/trunk/lib/DSA/DSCallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSCallGraph.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSCallGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSCallGraph.cpp Thu Mar 18 21:58:30 2010
@@ -54,16 +54,14 @@
   // The edges out of the current node are the call site targets...
   for (flat_iterator ii = flat_callee_begin(F),
        ee = flat_callee_end(F); ii != ee; ++ii) {
-    if (!(*ii)->isDeclaration()) {
-      unsigned M = Min;
-      // Have we visited the destination function yet?
-      TFMap::iterator It = ValMap.find(*ii);
-      if (It == ValMap.end()) // No, visit it now.
-        M = tarjan_rec(*ii, Stack, NextID, ValMap);
-      else if (std::find(Stack.begin(), Stack.end(), *ii) != Stack.end())
-        M = It->second;
-      if (M < Min) Min = M;
-    }
+    unsigned M = Min;
+    // Have we visited the destination function yet?
+    TFMap::iterator It = ValMap.find(*ii);
+    if (It == ValMap.end()) // No, visit it now.
+      M = tarjan_rec(*ii, Stack, NextID, ValMap);
+    else if (std::find(Stack.begin(), Stack.end(), *ii) != Stack.end())
+      M = It->second;
+    if (M < Min) Min = M;
   }
 
   assert(ValMap[F] == MyID && "SCC construction assumption wrong!");
@@ -209,11 +207,15 @@
 
 //Filter all call edges.  We only want pointer edges.
 void DSCallGraph::insert(llvm::CallSite CS, const llvm::Function* F) {
+  //Create an empty set for the callee, hence all called functions get to be
+  // in the call graph also.  This simplifies SCC formation
+  SimpleCallees[CS.getInstruction()->getParent()->getParent()];
   if (F) {
     ActualCallees[CS].insert(F);
     SimpleCallees[CS.getInstruction()->getParent()->getParent()].insert(F);
-    //Create an empty set for the callee, hence all called functions get to be
-    // in the call graph also.  This simplifies SCC formation
-    SimpleCallees[F];
   }
 }
+
+void DSCallGraph::insureEntry(const llvm::Function* F) {
+  SimpleCallees[F];
+}

Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSGraph.cpp Thu Mar 18 21:58:30 2010
@@ -1267,6 +1267,8 @@
       CallSite CS = ii->getCallSite();
       std::vector<const Function*> MaybeTargets;
       ii->getCalleeNode()->addFullFunctionList(MaybeTargets);
+      //Assure have a record for this callsite
+      DCG.insert(CS, 0);
       for (std::vector<const Function*>::iterator Fi = MaybeTargets.begin(),
            Fe = MaybeTargets.end(); Fi != Fe; ++Fi)
         if (functionIsCallable(CS, *Fi))

Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Thu Mar 18 21:58:30 2010
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "dsa-local"
 #include "dsa/DataStructure.h"
 #include "dsa/DSGraph.h"
 #include "llvm/Constants.h"
@@ -38,11 +39,19 @@
 
 using namespace llvm;
 
-static RegisterPass<LocalDataStructures>
+namespace {
+STATISTIC(NumDirectCall,    "Number of direct calls added");
+STATISTIC(NumIndirectCall,  "Number of indirect calls added");
+STATISTIC(NumAsmCall,       "Number of asm calls collapsed/seen");
+STATISTIC(NumBoringCall,    "Number of pointer-free direct calls ignored");
+STATISTIC(NumIntrinsicCall, "Number of intrinsics called");
+
+RegisterPass<LocalDataStructures>
 X("dsa-local", "Local Data Structure Analysis");
 
-static cl::opt<std::string> hasMagicSections("dsa-magic-sections",
-       cl::desc("File with section to global mapping")); //, cl::ReallyHidden);
+cl::opt<std::string> hasMagicSections("dsa-magic-sections",
+        cl::desc("File with section to global mapping")); //, cl::ReallyHidden);
+}
 
 namespace {
   //===--------------------------------------------------------------------===//
@@ -597,6 +606,7 @@
 
 /// returns true if the intrinsic is handled
 bool GraphBuilder::visitIntrinsic(CallSite CS, Function *F) {
+  ++NumIntrinsicCall;
   switch (F->getIntrinsicID()) {
   case Intrinsic::vastart: {
     // Mark the memory written by the vastart intrinsic as incomplete
@@ -751,6 +761,7 @@
 
   //Can't do much about inline asm (yet!)
   if (isa<InlineAsm>(CS.getCalledValue())) {
+    ++NumAsmCall;
     DSNodeHandle RetVal;
     Instruction *I = CS.getInstruction();
     if (isa<PointerType > (I->getType()))
@@ -766,15 +777,10 @@
   }
 
   //uninteresting direct call
-  if (CS.getCalledFunction() && !DSCallGraph::hasPointers(CS))
+  if (CS.getCalledFunction() && !DSCallGraph::hasPointers(CS)) {
+    ++NumBoringCall;
     return;
-
-
-//  if (InlineAsm* IASM = dyn_cast<InlineAsm>(CS.getCalledValue())) {
-//    if (IASM->hasSideEffects())
-//      errs() << ASM w/ Side Effects\n";
-//    return;
-//  }
+  }
 
   // Set up the return value...
   DSNodeHandle RetVal;
@@ -806,11 +812,13 @@
 
   // Add a new function call entry...
   if (CalleeNode) {
+    ++NumIndirectCall;
     G.getFunctionCalls().push_back(DSCallSite(CS, RetVal, CalleeNode, Args));
-//    DS->callee_site(CS.getInstruction());
-  }else
+  } else {
+    ++NumDirectCall;
     G.getFunctionCalls().push_back(DSCallSite(CS, RetVal, cast<Function>(Callee),
                                               Args));
+  }
 }
 
 // visitInstruction - For all other instruction types, if we have any arguments
@@ -970,11 +978,10 @@
       G->getAuxFunctionCalls() = G->getFunctionCalls();
       setDSGraph(*I, G);
       propagateUnknownFlag(G);
+      callgraph.insureEntry(I);
       G->buildCallGraph(callgraph);
     }
 
-
-
   GlobalsGraph->removeTriviallyDeadNodes();
   GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
 





More information about the llvm-commits mailing list