[llvm-commits] [poolalloc] r98700 - in /poolalloc/trunk: include/dsa/DSCallGraph.h include/dsa/DSGraph.h include/dsa/DSNode.h include/dsa/DataStructure.h lib/DSA/BottomUpClosure.cpp lib/DSA/CompleteBottomUp.cpp lib/DSA/DSGraph.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/Printer.cpp lib/DSA/TopDownClosure.cpp lib/PoolAllocate/RunTimeAssociate.cpp lib/PoolAllocate/TransformFunctionBody.cpp

Andrew Lenharth andrewl at lenharth.org
Tue Mar 16 18:00:46 PDT 2010


Author: alenhar2
Date: Tue Mar 16 20:00:46 2010
New Revision: 98700

URL: http://llvm.org/viewvc/llvm-project?rev=98700&view=rev
Log:
Precompute SCCs and callgraphs
inline everything in the precomputed SCC
todo: don't remove unresolved callsites


Modified:
    poolalloc/trunk/include/dsa/DSCallGraph.h
    poolalloc/trunk/include/dsa/DSGraph.h
    poolalloc/trunk/include/dsa/DSNode.h
    poolalloc/trunk/include/dsa/DataStructure.h
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
    poolalloc/trunk/lib/DSA/DSGraph.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp
    poolalloc/trunk/lib/DSA/Local.cpp
    poolalloc/trunk/lib/DSA/Printer.cpp
    poolalloc/trunk/lib/DSA/TopDownClosure.cpp
    poolalloc/trunk/lib/PoolAllocate/RunTimeAssociate.cpp
    poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp

Modified: poolalloc/trunk/include/dsa/DSCallGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSCallGraph.h?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSCallGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSCallGraph.h Tue Mar 16 20:00:46 2010
@@ -17,15 +17,15 @@
 #include "dsa/sv/set.h"
 #include <map>
 
+#include "llvm/Function.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Support/CallSite.h"
-
-namespace llvm {
-class Function;
-}
+#include "llvm/Support/FormattedStream.h"
 
 template<class Iter>
 class KeyIterator {
   Iter I;
+
 public:
   typedef typename Iter::difference_type difference_type;
   typedef typename Iter::value_type::first_type value_type;
@@ -33,58 +33,151 @@
   typedef typename Iter::value_type::first_type& reference;
   typedef typename Iter::iterator_category iterator_category;
 
-  KeyIterator(Iter i) :I(i) {}
-  Iter base() const { return I; }
-  reference    operator*() const { return I->first; }
-  KeyIterator  operator+(difference_type n) const { return KeyIterator(I + n); }
-  KeyIterator& operator++() { ++I; return *this; }
-  KeyIterator  operator++(int) { Iter OI = I; ++I; return KeyIterator(OI); }
-  KeyIterator& operator+= (difference_type n) { I += n; return *this; }
-  KeyIterator  operator- (difference_type n) const { return KeyIterator(I - n); }
-  KeyIterator& operator--() { --I; return *this; }
-  KeyIterator  operator--(int) { Iter OI = I; --I; return KeyIterator(OI); }
-  KeyIterator& operator-=(difference_type n) { I -= n; return *this; }
-  pointer operator->() const { return &I->first; }
-  bool operator==(const KeyIterator& RHS) const { return I == RHS.I; }
-  bool operator!=(const KeyIterator& RHS) const { return I != RHS.I; }
+  KeyIterator(Iter i) : I(i) { }
+
+  Iter base() const {
+    return I;
+  }
+
+  reference operator*() const {
+    return I->first;
+  }
+
+  KeyIterator operator+(difference_type n) const {
+    return KeyIterator(I + n);
+  }
+
+  KeyIterator & operator++() {
+    ++I;
+    return *this;
+  }
+
+  KeyIterator operator++(int) {
+    Iter OI = I;
+    ++I;
+    return KeyIterator(OI);
+  }
+
+  KeyIterator & operator+=(difference_type n) {
+    I += n;
+    return *this;
+  }
+
+  KeyIterator operator-(difference_type n) const {
+    return KeyIterator(I - n);
+  }
+
+  KeyIterator & operator--() {
+    --I;
+    return *this;
+  }
+
+  KeyIterator operator--(int) {
+    Iter OI = I;
+    --I;
+    return KeyIterator(OI);
+  }
+
+  KeyIterator & operator-=(difference_type n) {
+    I -= n;
+    return *this;
+  }
+
+  pointer operator->() const {
+    return &I->first;
+  }
+
+  bool operator==(const KeyIterator& RHS) const {
+    return I == RHS.I;
+  }
+
+  bool operator!=(const KeyIterator& RHS) const {
+    return I != RHS.I;
+  }
 };
 
 class DSCallGraph {
-
+public:
   typedef sv::set<const llvm::Function*> FuncSet;
   typedef std::map<llvm::CallSite, FuncSet> ActualCalleesTy;
+  typedef std::map<const llvm::Function*, FuncSet> SimpleCalleesTy;
 
+private:
   ActualCalleesTy ActualCallees;
+  SimpleCalleesTy SimpleCallees;
+
+  FuncSet EmptyActual;
+  FuncSet EmptySimple;
 
 public:
 
-  typedef ActualCalleesTy::mapped_type::const_iterator iterator;
+  DSCallGraph() {}
+
+  typedef ActualCalleesTy::mapped_type::const_iterator callee_iterator;
   typedef KeyIterator<ActualCalleesTy::const_iterator> key_iterator;
+  typedef SimpleCalleesTy::mapped_type::const_iterator flat_iterator;
+  typedef KeyIterator<SimpleCalleesTy::const_iterator> flat_key_iterator;
 
   void insert(llvm::CallSite CS, const llvm::Function* F) {
-    if (F) ActualCallees[CS].insert(F);
+    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];
+    }
   }
 
   template<class Iterator>
   void insert(llvm::CallSite CS, Iterator _begin, Iterator _end) {
-    for(; _begin != _end; ++_begin)
+    for (; _begin != _end; ++_begin)
       insert(CS, *_begin);
   }
 
-  iterator callee_begin(llvm::CallSite CS) const {
+  callee_iterator callee_begin(llvm::CallSite CS) const {
     ActualCalleesTy::const_iterator ii = ActualCallees.find(CS);
     if (ii == ActualCallees.end())
-      ii = ActualCallees.find(llvm::CallSite());
+      return EmptyActual.end();
     return ii->second.begin();
   }
 
-  iterator callee_end(llvm::CallSite CS) const {
+  callee_iterator callee_end(llvm::CallSite CS) const {
     ActualCalleesTy::const_iterator ii = ActualCallees.find(CS);
     if (ii == ActualCallees.end())
-      ii = ActualCallees.find(llvm::CallSite());
+      return EmptyActual.end();
     return ii->second.end();
   }
 
+  key_iterator key_begin() const {
+    return key_iterator(ActualCallees.begin());
+  }
+
+  key_iterator key_end() const {
+    return key_iterator(ActualCallees.end());
+  }
+
+  flat_iterator flat_callee_begin(const llvm::Function* F) const {
+    SimpleCalleesTy::const_iterator ii = SimpleCallees.find(F);
+    if (ii == SimpleCallees.end())
+      return EmptySimple.end();
+    return ii->second.begin();
+  }
+
+  flat_iterator flat_callee_end(const llvm::Function* F) const {
+    SimpleCalleesTy::const_iterator ii = SimpleCallees.find(F);
+    if (ii == SimpleCallees.end())
+      return EmptySimple.end();
+    return ii->second.end();
+  }
+
+  flat_key_iterator flat_key_begin() const {
+    return flat_key_iterator(SimpleCallees.begin());
+  }
+
+  flat_key_iterator flat_key_end() const {
+    return flat_key_iterator(SimpleCallees.end());
+  }
+
 
   unsigned callee_size(llvm::CallSite CS) const {
     ActualCalleesTy::const_iterator ii = ActualCallees.find(CS);
@@ -105,12 +198,191 @@
     ActualCallees.clear();
   }
 
-  key_iterator key_begin() const {
-    return key_iterator(ActualCallees.begin());
+};
+
+class DSSCCGraph {
+public:
+  //SCCs, each element is an SCC
+  std::map<unsigned, DSCallGraph::FuncSet> SCCs;
+  //mapping of functions in SCCs to SCCs index
+  std::map<const llvm::Function*, unsigned> invmap;
+
+  unsigned nextSCC;
+
+  //Functions we know about that aren't called
+  sv::set<unsigned> knownRoots;
+
+  std::map<unsigned, sv::set<unsigned> > SCCCallees;
+  std::map<unsigned, sv::set<unsigned> > ExtCallees;
+
+  DSCallGraph oldGraph;
+
+private:
+  typedef std::map<const llvm::Function*, unsigned> TFMap;
+  typedef std::vector<const llvm::Function*> TFStack;
+
+  bool hasPointers(const llvm::Function* F) {
+    if (F->isVarArg()) return true;
+    if (F->getReturnType()->isPointerTy()) return true;
+    for (llvm::Function::const_arg_iterator ii = F->arg_begin(), ee = F->arg_end();
+            ii != ee; ++ii)
+      if (ii->getType()->isPointerTy()) return true;
+    return false;
   }
 
-  key_iterator key_end() const {
-    return key_iterator(ActualCallees.end());
+  unsigned tarjan_rec(const llvm::Function* F, TFStack& Stack, unsigned &NextID,
+                      TFMap& ValMap, DSCallGraph& cg) {
+    assert(!ValMap.count(F) && "Shouldn't revisit functions!");
+    unsigned Min = NextID++, MyID = Min;
+    ValMap[F] = Min;
+    Stack.push_back(F);
+
+    // The edges out of the current node are the call site targets...
+    for (DSCallGraph::flat_iterator ii = cg.flat_callee_begin(F),
+            ee = cg.flat_callee_end(F); ii != ee; ++ii) {
+      if (hasPointers(*ii) && !(*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, cg);
+        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!");
+    if (Min != MyID)
+      return Min; // This is part of a larger SCC!
+
+    // If this is a new SCC, process it now.
+    ++nextSCC;
+
+    const llvm::Function* NF = 0;
+    do {
+      NF = Stack.back();
+      Stack.pop_back();
+      assert(NF && "Null Function");
+      assert(invmap.find(NF) == invmap.end() && "Function already in invmap");
+      invmap[NF] = nextSCC;
+      assert(SCCs[nextSCC].find(NF) == SCCs[nextSCC].end() &&
+             "Function already in SCC");
+      SCCs[nextSCC].insert(NF);
+    } while (NF != F);
+
+    return MyID;
+  }
+
+  void buildSCC(DSCallGraph& DSG) {
+    TFStack Stack;
+    TFMap ValMap;
+    unsigned NextID = 1;
+
+    for (DSCallGraph::flat_key_iterator ii = DSG.flat_key_begin(),
+            ee = DSG.flat_key_end(); ii != ee; ++ii)
+      if (!ValMap.count(*ii))
+        tarjan_rec(*ii, Stack, NextID, ValMap, DSG);
+  }
+
+  void buildCallGraph(DSCallGraph& DSG) {
+    for(DSCallGraph::flat_key_iterator ii = DSG.flat_key_begin(),
+            ee = DSG.flat_key_end(); ii != ee; ++ii) {
+      assert (*ii && "Null Function");
+      assert(invmap.find(*ii) != invmap.end() && "Unknown Function");
+      for (DSCallGraph::flat_iterator fi = DSG.flat_callee_begin(*ii),
+              fe = DSG.flat_callee_end(*ii); fi != fe; ++fi) {
+        assert(*fi && "Null Function");
+        assert(invmap.find(*fi) != invmap.end() && "Unknown Function");
+        if (invmap[*ii] != invmap[*fi]) // No self calls
+          if (hasPointers(*fi)) {
+            if ((*fi)->isDeclaration())
+              ExtCallees[invmap[*ii]].insert(invmap[*fi]);
+            else
+              SCCCallees[invmap[*ii]].insert(invmap[*fi]);
+          }
+      }
+    }
+  }
+
+  void buildRoots() {
+    sv::set<unsigned> knownCallees;
+    sv::set<unsigned> knownCallers;
+    for (std::map<unsigned, sv::set<unsigned> >::iterator
+      ii = SCCCallees.begin(), ee = SCCCallees.end(); ii != ee; ++ii) {
+      knownCallees.insert(ii->second.begin(), ii->second.end());
+      knownCallers.insert(ii->first);
+    }
+    for (sv::set<unsigned>::iterator ii = knownCallers.begin(),
+            ee = knownCallers.end(); ii != ee; ++ii)
+      if (!knownCallees.count(*ii))
+        knownRoots.insert(*ii);
+  }
+
+  void assertMapValid() {
+    for (std::map<unsigned, DSCallGraph::FuncSet>::iterator ii = SCCs.begin(),
+            ee = SCCs.end(); ii != ee; ++ii) {
+      for (DSCallGraph::FuncSet::iterator i = ii->second.begin(),
+              e = ii->second.end(); i != e; ++i) {
+        assert(*i && "Null Function in map");
+        assert(invmap.find(*i) != invmap.end() && "Function not in invmap");
+        assert(invmap[*i] == ii->first && "invmap doesn't match map");
+      }
+    }
+
+    for (std::map<const llvm::Function*, unsigned>::iterator ii = invmap.begin(),
+            ee = invmap.end(); ii != ee; ++ii) {
+      assert(ii->first && "Null Function in invmap");
+      assert(SCCs.find(ii->second) != SCCs.end() && "Function in invmap but not in map");
+      assert(SCCs[ii->second].count(ii->first) && "SCC doesn't contain function");
+    }
+  }
+
+public:
+
+  DSSCCGraph(DSCallGraph& DSG) :nextSCC(0) {
+    oldGraph = DSG;
+
+    buildSCC(DSG);
+    assertMapValid();
+
+    buildCallGraph(DSG);
+
+    buildRoots();
+    
+  }
+
+  void dump() {
+    //function map
+    for (std::map<unsigned, DSCallGraph::FuncSet>::iterator ii = SCCs.begin(),
+            ee = SCCs.end(); ii != ee; ++ii) {
+      llvm::errs() << "Functions in " << ii->first << ":";
+      for (DSCallGraph::FuncSet::iterator i = ii->second.begin(),
+              e = ii->second.end(); i != e; ++i)
+        llvm::errs() << " " << *i << "(" << invmap[*i] << ")";
+      llvm::errs() << "\n";
+    }
+
+//    for (std::map<const llvm::Function*, unsigned>::iterator ii = invmap.begin(),
+//            ee = invmap.end(); ii != ee; ++ii)
+//      llvm::errs() << ii->first << " -> " << ii->second << "\n";
+
+    //SCC map
+    for (std::map<unsigned, sv::set<unsigned> >::iterator ii = SCCCallees.begin(),
+            ee = SCCCallees.end(); ii != ee; ++ii) {
+      llvm::errs() << "CallGraph[" << ii->first << "]";
+      for (sv::set<unsigned>::iterator i = ii->second.begin(),
+              e = ii->second.end(); i != e; ++i)
+        llvm::errs() << " " << *i;
+      llvm::errs() << "\n";
+    }
+
+    //Functions we know about that aren't called
+    llvm::errs() << "Roots:";
+    for (sv::set<unsigned>::iterator ii = knownRoots.begin(),
+            ee = knownRoots.end(); ii != ee; ++ii)
+      llvm::errs() << " " << *ii;
+    llvm::errs() << "\n";
   }
 
 };

Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Tue Mar 16 20:00:46 2010
@@ -16,6 +16,7 @@
 #define LLVM_ANALYSIS_DSGRAPH_H
 
 #include "dsa/DSNode.h"
+#include "dsa/DSCallGraph.h"
 #include "llvm/ADT/EquivalenceClasses.h"
 
 #include <list>
@@ -42,7 +43,7 @@
   typedef std::map<const Value*, DSNodeHandle> ValueMapTy;
   ValueMapTy ValueMap;
 
-  typedef sv::set<const GlobalValue*> GlobalSetTy;
+  typedef std::set<const GlobalValue*> GlobalSetTy;
   GlobalSetTy GlobalSet;
 
   EquivalenceClasses<const GlobalValue*> &GlobalECs;
@@ -68,6 +69,7 @@
 
 
   iterator find(const Value *V) {
+    assert(V);
     iterator I = ValueMap.find(V);
     if (I != ValueMap.end()) return I;
 
@@ -81,6 +83,7 @@
     return I;
   }
   const_iterator find(const Value *V) const {
+    assert(V);
     const_iterator I = ValueMap.find(V);
     if (I != ValueMap.end()) return I;
 
@@ -135,6 +138,7 @@
   /// operator[] - Return the DSNodeHandle for the specified value, creating a
   /// new null handle if there is no entry yet.
   DSNodeHandle &operator[](const Value *V) {
+    assert(V);
     iterator I = ValueMap.find(V);
     if (I != ValueMap.end())
       return I->second;   // Return value if already exists.
@@ -327,6 +331,7 @@
   // addAuxFunctionCall - Add a call site to the AuxFunctionCallList
   void addAuxFunctionCall(DSCallSite D) { AuxFunctionCalls.push_front(D); }
 
+  void buildCallGraph(DSCallGraph& DCG) const;
 
   /// removeFunction - Specify that all call sites to the function have been
   /// fully specified by a pass such as StdLibPass.

Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Tue Mar 16 20:00:46 2010
@@ -130,15 +130,7 @@
   /// links are just going to be clobbered anyway.
   ///
   DSNode(const DSNode &, DSGraph *G, bool NullLinks = false);
-
-#if 0
-  ~DSNode() {
-    dropAllReferences();
-    assert(hasNoReferrers() && "Referrers to dead node exist!");
-  }
-#else
   ~DSNode();
-#endif
 
   // Iterator for graph interface... Defined in DSGraphTraits.h
   typedef DSNodeIterator<DSNode> iterator;

Modified: poolalloc/trunk/include/dsa/DataStructure.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DataStructure.h (original)
+++ poolalloc/trunk/include/dsa/DataStructure.h Tue Mar 16 20:00:46 2010
@@ -235,13 +235,11 @@
   bool runOnModuleInternal(Module &M);
 
 private:
-  void calculateGraph(DSGraph* G);
-
-  unsigned calculateGraphs(const Function *F, 
-                           std::vector<const Function*> &Stack,
-                           unsigned &NextID,
-                           std::map<const Function*, unsigned> &ValMap);
-
+  void mergeSCCs(DSSCCGraph& DSG);
+  
+  DSGraph* postOrder(DSSCCGraph& DSG, unsigned scc, sv::set<unsigned>& marked);
+  
+  void calculateGraph(DSGraph* G, DSSCCGraph& DSG);
 
   void CloneAuxIntoGlobal(DSGraph* G);
   void cloneGlobalsInto(DSGraph* G);

Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Mar 16 20:00:46 2010
@@ -28,6 +28,7 @@
   STATISTIC (MaxSCC, "Maximum SCC Size in Call Graph");
   STATISTIC (NumInlines, "Number of graphs inlined");
   STATISTIC (NumCallEdges, "Number of 'actual' call edges");
+  STATISTIC (NumSCCMerges, "Number of SCC merges");
 
   RegisterPass<BUDataStructures>
   X("dsa-bu", "Bottom-up Data Structure Analysis");
@@ -51,8 +52,41 @@
 // inline bottum up
 //
 // We must split these out (they were merged in PLDI07) to handle multiple
-// entry-points correctly.
+// entry-points correctly.  As a bonus, we can be more aggressive at propagating
+// information upwards, as long as we don't remove unresolved call sites.
 bool BUDataStructures::runOnModuleInternal(Module& M) {
+  //Find SCCs and make SCC call graph
+  DSSCCGraph DSG(callgraph);
+
+  errs() << "DSNode: " << sizeof(DSNode) << "\nDSCallSite: "
+          << sizeof(DSCallSite) << "\n";
+
+//  DSG.dump();
+
+  //merge SCCs
+  mergeSCCs(DSG);
+
+  //Post order traversal:
+  {
+    //errs() << *DSG.knownRoots.begin() << " -> " << *DSG.knownRoots.rbegin() << "\n";
+    sv::set<unsigned> marked;
+    for (sv::set<unsigned>::const_iterator ii = DSG.knownRoots.begin(),
+         ee = DSG.knownRoots.end(); ii != ee; ++ii) {
+      //errs() << *ii << " ";
+      DSGraph* G = postOrder(DSG, *ii, marked);
+      CloneAuxIntoGlobal(G);
+    }
+  }
+
+
+  return false;
+
+  std::vector<const Function*> EntryPoints;
+  EP = &getAnalysis<EntryPointAnalysis>();
+  EP->findEntryPoints(M, EntryPoints);
+
+  #if 0
+
   std::vector<const Function*> Stack;
   std::map<const Function*, unsigned> ValMap;
   unsigned NextID = 1;
@@ -84,6 +118,7 @@
     }
 
   errs() << "done unreachable Funcs\n";
+  #endif
 
   // If we computed any temporary indcallgraphs, free them now.
   for (std::map<std::vector<const Function*>,
@@ -129,6 +164,51 @@
   return false;
 }
 
+void BUDataStructures::mergeSCCs(DSSCCGraph& DSG) {
+
+  for (std::map<unsigned, DSCallGraph::FuncSet>::iterator ii = DSG.SCCs.begin(),
+       ee = DSG.SCCs.end(); ii != ee; ++ii) {
+
+    DSGraph* SCCGraph = 0;
+    unsigned SCCSize = 0;
+    for (DSCallGraph::FuncSet::iterator Fi = ii->second.begin(),
+         Fe = ii->second.end(); Fi != Fe; ++Fi) {
+      const Function* F = *Fi;
+      if (F->isDeclaration()) continue;
+      ++SCCSize;
+      DSGraph* NFG = getOrCreateGraph(F);
+      if (!SCCGraph) {
+        SCCGraph = NFG;
+      }
+      if (NFG != SCCGraph) {
+        ++NumSCCMerges;
+        // Update the Function -> DSG map.
+        for (DSGraph::retnodes_iterator I = NFG->retnodes_begin(),
+             E = NFG->retnodes_end(); I != E; ++I)
+          setDSGraph(*I->first, SCCGraph);
+
+        SCCGraph->spliceFrom(NFG);
+        delete NFG;
+      }
+    }
+    if (MaxSCC < SCCSize) MaxSCC = SCCSize;
+  }
+}
+
+DSGraph* BUDataStructures::postOrder(DSSCCGraph& DSG, unsigned scc,
+                                     sv::set<unsigned>& marked) {
+  DSGraph* G = getDSGraph(**DSG.SCCs[scc].begin());
+  if (marked.count(scc)) return G;
+
+  for(sv::set<unsigned>::iterator ii = DSG.SCCCallees[scc].begin(),
+          ee = DSG.SCCCallees[scc].end(); ii != ee; ++ii)
+    postOrder(DSG, *ii, marked);
+
+  marked.insert(scc);
+  calculateGraph(G, DSG);
+  return G;
+}
+
 void BUDataStructures::finalizeGlobals(void) {
   // Any unresolved call can be removed (resolved) if it does not contain
   // external functions and it is not reachable from any call that does
@@ -157,169 +237,6 @@
   GlobalsGraph->getScalarMap().clear_scalars();
 }
 
-static void GetAllCallees(const DSCallSite &CS,
-                          std::vector<const Function*> &Callees) {
-  if (CS.isDirectCall()) {
-    if (!CS.getCalleeFunc()->isDeclaration())
-      Callees.push_back(CS.getCalleeFunc());
-  } else if (!CS.getCalleeNode()->isIncompleteNode()) {
-    // Get all callees.
-    if (!CS.getCalleeNode()->isExternFuncNode())
-      CS.getCalleeNode()->addFullFunctionList(Callees);
-  }
-}
-
-static void GetAnyCallees(const DSCallSite &CS,
-                          std::vector<const Function*> &Callees) {
-  if (CS.isDirectCall()) {
-    if (!CS.getCalleeFunc()->isDeclaration())
-      Callees.push_back(CS.getCalleeFunc());
-  } else {
-    // Get any callees.
-    unsigned OldSize = Callees.size();
-    CS.getCalleeNode()->addFullFunctionList(Callees);
-
-    // If any of the callees are unresolvable, remove them
-    for (unsigned i = OldSize; i != Callees.size();)
-      if (Callees[i]->isDeclaration()) {
-        Callees.erase(Callees.begin() + i);
-      } else
-        ++i;
-  }
-}
-
-/// GetAllAuxCallees - Return a list containing all of the resolvable callees in
-/// the aux list for the specified graph in the Callees vector.
-static void GetAllAuxCallees(DSGraph* G, std::vector<const Function*> &Callees) {
-  Callees.clear();
-  for (DSGraph::afc_iterator I = G->afc_begin(), E = G->afc_end(); I != E; ++I)
-    GetAllCallees(*I, Callees);
-}
-
-unsigned BUDataStructures::calculateGraphs(const Function *F,
-                                           std::vector<const Function*> &Stack,
-                                           unsigned &NextID,
-                                           std::map<const Function*, unsigned> &ValMap) {
-  assert(!ValMap.count(F) && "Shouldn't revisit functions!");
-  unsigned Min = NextID++, MyID = Min;
-  ValMap[F] = Min;
-  Stack.push_back(F);
-
-  // FIXME!  This test should be generalized to be any function that we have
-  // already processed, in the case when there isn't a main or there are
-  // unreachable functions!
-  if (F->isDeclaration()) {   // sprintf, fprintf, sscanf, etc...
-    // No callees!
-    Stack.pop_back();
-    ValMap[F] = ~0;
-    return Min;
-  }
-
-  DSGraph* Graph = getOrCreateGraph(F);
-
-  // Find all callee functions.
-  std::vector<const Function*> CalleeFunctions;
-  GetAllAuxCallees(Graph, CalleeFunctions);
-
-  // The edges out of the current node are the call site targets...
-  for (unsigned i = 0, e = CalleeFunctions.size(); i != e; ++i) {
-    const Function *Callee = CalleeFunctions[i];
-    unsigned M;
-    // Have we visited the destination function yet?
-    std::map<const Function*, unsigned>::iterator It = ValMap.find(Callee);
-    if (It == ValMap.end())  // No, visit it now.
-      M = calculateGraphs(Callee, Stack, NextID, ValMap);
-    else                    // Yes, get it's number.
-      M = It->second;
-    if (M < Min) Min = M;
-  }
-
-  assert(ValMap[F] == MyID && "SCC construction assumption wrong!");
-  if (Min != MyID)
-    return Min;         // This is part of a larger SCC!
-
-  // If this is a new SCC, process it now.
-  if (Stack.back() == F) {           // Special case the single "SCC" case here.
-    DEBUG(errs() << "Visiting single node SCC #: " << MyID << " fn: "
-	  << F->getName() << "\n");
-    Stack.pop_back();
-    DEBUG(errs() << "  [BU] Calculating graph for: " << F->getName()<< "\n");
-    calculateGraph(Graph);
-    DEBUG(errs() << "  [BU] Done inlining: " << F->getName() << " ["
-	  << Graph->getGraphSize() << "+" << Graph->getAuxFunctionCalls().size()
-	  << "]\n");
-
-    if (MaxSCC < 1) MaxSCC = 1;
-
-    // Should we revisit the graph?  Only do it if there are now new resolvable
-    // callees
-    GetAllAuxCallees(Graph, CalleeFunctions);
-    if (!CalleeFunctions.empty()) {
-      DEBUG(errs() << "Recalculating " << F->getName() << " due to new knowledge\n");
-      ValMap.erase(F);
-      return calculateGraphs(F, Stack, NextID, ValMap);
-    } else {
-      ValMap[F] = ~0U;
-    }
-    return MyID;
-
-  } else {
-    // SCCFunctions - Keep track of the functions in the current SCC
-    //
-    std::vector<DSGraph*> SCCGraphs;
-
-    unsigned SCCSize = 1;
-    const Function *NF = Stack.back();
-    ValMap[NF] = ~0U;
-    DSGraph* SCCGraph = getDSGraph(*NF);
-
-    // First thing first, collapse all of the DSGraphs into a single graph for
-    // the entire SCC.  Splice all of the graphs into one and discard all of the
-    // old graphs.
-    //
-    while (NF != F) {
-      Stack.pop_back();
-      NF = Stack.back();
-      ValMap[NF] = ~0U;
-
-      DSGraph* NFG = getDSGraph(*NF);
-
-      if (NFG != SCCGraph) {
-        // Update the Function -> DSG map.
-        for (DSGraph::retnodes_iterator I = NFG->retnodes_begin(),
-               E = NFG->retnodes_end(); I != E; ++I)
-          setDSGraph(*I->first, SCCGraph);
-        
-        SCCGraph->spliceFrom(NFG);
-        delete NFG;
-        ++SCCSize;
-      }
-    }
-    Stack.pop_back();
-
-    DEBUG(errs() << "Calculating graph for SCC #: " << MyID << " of size: "
-	  << SCCSize << "\n");
-
-    // Compute the Max SCC Size.
-    if (MaxSCC < SCCSize)
-      MaxSCC = SCCSize;
-
-    // Clean up the graph before we start inlining a bunch again...
-    SCCGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-    // Now that we have one big happy family, resolve all of the call sites in
-    // the graph...
-    calculateGraph(SCCGraph);
-    DEBUG(errs() << "  [BU] Done inlining SCC  [" << SCCGraph->getGraphSize()
-	  << "+" << SCCGraph->getAuxFunctionCalls().size() << "]\n"
-	  << "DONE with SCC #: " << MyID << "\n");
-
-    // We never have to revisit "SCC" processed functions...
-    return MyID;
-  }
-
-  return MyID;  // == Min
-}
 
 void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) {
   DSGraph* GG = G->getGlobalsGraph();
@@ -345,7 +262,7 @@
   }
 }
 
-void BUDataStructures::calculateGraph(DSGraph* Graph) {
+void BUDataStructures::calculateGraph(DSGraph* Graph, DSSCCGraph& DSG) {
   DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
 
   // If this graph contains the main function, clone the globals graph into this
@@ -384,33 +301,29 @@
     // 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) {
-      if (!CS.isDirectCall()) {
-        GetAnyCallees(CS, CalledFuncs);
-        callgraph.insert(CS.getCallSite(), CalledFuncs.begin(), CalledFuncs.end());
-      }
       TempFCs.erase(TempFCs.begin());
       continue;
     }
 
-    GetAllCallees(CS, CalledFuncs);
+    std::copy(DSG.oldGraph.callee_begin(CS.getCallSite()),
+              DSG.oldGraph.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()) {
-      //Get any callees we do have for the callgraph
-      if (!CS.isDirectCall()) {
-        GetAnyCallees(CS, CalledFuncs);
-        callgraph.insert(CS.getCallSite(), CalledFuncs.begin(), CalledFuncs.end());
-      }
       // Remember that we could not resolve this yet!
       AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
       continue;
     }
 
     DSGraph *GI;
-    
-    callgraph.insert(CS.getCallSite(), CalledFuncs.begin(), CalledFuncs.end());
 
-    if (CalledFuncs.size() == 1) {
-      const Function *Callee = CalledFuncs[0];
+    for (unsigned x = 0; x < CalledFuncs.size(); ++x) {
+      const Function *Callee = CalledFuncs[x];
 
       // Get the data structure graph for the called function.
       GI = getDSGraph(*Callee);  // Graph to inline
@@ -424,85 +337,7 @@
                           DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
       ++NumInlines;
       DEBUG(Graph->AssertGraphOK(););
-    } else {
-      bool doDebug = false;
-      DEBUG(doDebug = true);
-      if (doDebug) {
-        errs() << "In Fns: " << Graph->getFunctionNames() << "\n";
-        errs() << "  calls " << CalledFuncs.size()
-                << " fns from site: " << CS.getCallSite().getInstruction()
-                << "  " << *CS.getCallSite().getInstruction();
-        errs() << "   Fns =";
-        unsigned NumPrinted = 0;
-
-        for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
-                E = CalledFuncs.end(); I != E; ++I)
-          if (NumPrinted++ < 8) {
-            errs() << " " << (*I)->getName();
-          }
-        errs() << "\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<const Function*>::iterator I = CalledFuncs.begin(),
-                E = CalledFuncs.end();
-
-        // Start with a copy of the first graph.
-        GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs, *TypeSS);
-        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));
-            ++NumInlines;
-          }
-
-          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]);
-        }
-
-        // Clean up the final graph!
-        GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-      } else {
-        DEBUG(errs() << "***\n*** RECYCLED GRAPH ***\n***\n");
-      }
-
-      GI = IndCallGraph.first;
-
-      // Merge the unified graph into this graph now.
-      DEBUG(errs() << "    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);
-      ++NumInlines;
     }
-    DEBUG(Graph->AssertGraphOK(););
-    DEBUG(Graph->getGlobalsGraph()->AssertGraphOK());
     TempFCs.erase(TempFCs.begin());
   }
 

Modified: poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original)
+++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Tue Mar 16 20:00:46 2010
@@ -51,7 +51,7 @@
   //mege nodes in the global graph for these functions
   for (DSCallGraph::key_iterator ii = callgraph.key_begin(),
        ee = callgraph.key_end(); ii != ee; ++ii) {
-    DSCallGraph::iterator csi = callgraph.callee_begin(*ii),
+    DSCallGraph::callee_iterator csi = callgraph.callee_begin(*ii),
             cse = callgraph.callee_end(*ii);
     if (csi != cse && SM.find(*csi) != SM.end()) {
       DSNodeHandle& SrcNH = SM.find(*csi)->second;

Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSGraph.cpp Tue Mar 16 20:00:46 2010
@@ -38,10 +38,20 @@
 
 #define COLLAPSE_ARRAYS_AGGRESSIVELY 0
 namespace {
-  STATISTIC (NumCallNodesMerged, "Number of call nodes merged");
-  STATISTIC (NumDNE            , "Number of nodes removed by reachability");
-  STATISTIC (NumTrivialDNE     , "Number of nodes trivially removed");
+  STATISTIC (NumCallNodesMerged , "Number of call nodes merged");
+  STATISTIC (NumDNE             , "Number of nodes removed by reachability");
+  STATISTIC (NumTrivialDNE      , "Number of nodes trivially removed");
   STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed");
+  STATISTIC (NumFiltered        , "Number of calls filtered");
+  static cl::opt<bool> noDSACallConv("dsa-no-filter-callcc",
+         cl::desc("Don't filter call sites based on calling convention."),
+         cl::Hidden);
+  static cl::opt<bool> noDSACallVA("dsa-no-filter-vararg",
+         cl::desc("Don't filter call sites based on vararg presense"),
+         cl::Hidden);
+  static cl::opt<bool> noDSACallFP("dsa-no-filter-intfp",
+         cl::desc("Don't filter call sites based on implicit integer to fp conversion"),
+         cl::Hidden);
 }
 
 /// getFunctionNames - Return a space separated list of the name of the
@@ -1215,4 +1225,53 @@
   }
 }
 
+// Filter potential call targets
+static bool functionIsCallable(CallSite CS, const Function* F) {
+  //Which targets do we choose?
+  //Conservative: all of them
+  //Pretty Safe: same calling convention, otherwise undefined behavior
+  //Safe on some archs:
+  //Safe?: vararg call only calling vararg functions
+  //Safe?: non-vararg call only calling non-vararg functions
+  //Safe?: iany/ptr can't be interchanged in args w/ float/double
+  //Not so safe: number of args matching
+  const PointerType*  PT = cast<PointerType>(CS.getCalledValue()->getType());
+  const FunctionType* FT = cast<FunctionType>(PT->getElementType());
+
+  if (!noDSACallConv && CS.getCallingConv() != F->getCallingConv()) return false;
+  if (!noDSACallVA && FT->isVarArg() != F->isVarArg()) return false;
+  if (!noDSACallFP) {
+    FunctionType::param_iterator Pi = FT->param_begin(), Pe = FT->param_end(),
+            Ai = F->getFunctionType()->param_begin(),
+            Ae = F->getFunctionType()->param_end();
+    while (Ai != Ae && Pi != Pe) {
+      if ((Ai->get()->isFPOrFPVectorTy() && !Pi->get()->isFPOrFPVectorTy())
+          ||
+          (!Ai->get()->isFPOrFPVectorTy() && Pi->get()->isFPOrFPVectorTy()))
+        return false;
+      ++Ai;
+      ++Pi;
+    }
+  }
+  //F can be called from CS;
+  return true;
+}
 
+void DSGraph::buildCallGraph(DSCallGraph& DCG) const {
+  const std::list<DSCallSite>& Calls = getAuxFunctionCalls();
+  for (std::list<DSCallSite>::const_iterator ii = Calls.begin(), ee = Calls.end();
+       ii != ee; ++ii)
+    if (ii->isDirectCall()) {
+      DCG.insert(ii->getCallSite(), ii->getCalleeFunc());
+    } else {
+      CallSite CS = ii->getCallSite();
+      std::vector<const Function*> MaybeTargets;
+      ii->getCalleeNode()->addFullFunctionList(MaybeTargets);
+      for (std::vector<const Function*>::iterator Fi = MaybeTargets.begin(),
+           Fe = MaybeTargets.end(); Fi != Fe; ++Fi)
+        if (functionIsCallable(CS, *Fi))
+          DCG.insert(CS, *Fi);
+        else
+          ++NumFiltered;
+    }
+}

Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Mar 16 20:00:46 2010
@@ -85,6 +85,7 @@
 //===----------------------------------------------------------------------===//
 
 DSNodeHandle &DSScalarMap::AddGlobal(const GlobalValue *GV) {
+  assert(GV);
   assert(ValueMap.count(GV) == 0 && "GV already exists!");
 
   // If the node doesn't exist, check to see if it's a global that is
@@ -179,8 +180,9 @@
   DSNodeHandle ToNH(To,Offset);
 
   //Move the Links
-  for (unsigned x = 0, xe = Links.size(); x != xe; ++x)
-    if (!Links[x].isNull()) {
+  for (LinkMapTy::iterator ii = Links.begin(), ee = Links.end();
+       ii != ee; ++ii) {
+    if (!ii->second.isNull()) {
       // Compute the offset into the current node at which to
       // merge this link.  In the common case, this is a linear
       // relation to the offset in the original node (with
@@ -189,9 +191,10 @@
       // links at offset zero.
       unsigned MergeOffset = 0;
       if (ToNH.getNode()->getSize() != 1)
-        MergeOffset = (x + Offset) % ToNH.getNode()->getSize();
-      ToNH.getNode()->addEdgeTo(MergeOffset, Links[x]);
+        MergeOffset = (ii->first + Offset) % ToNH.getNode()->getSize();
+      ToNH.getNode()->addEdgeTo(MergeOffset, ii->second);
     }
+  }
   Links.clear();
 
   // Remove this node from the parent graph's Nodes list.
@@ -452,6 +455,8 @@
     CurNodeH.getNode()->growSize(NH.getNode()->getSize() + NOffset);
   assert(!CurNodeH.getNode()->isDeadNode());
 
+
+
   // Merge the NodeType information.
   CurNodeH.getNode()->NodeType |= N->NodeType;
 
@@ -459,6 +464,27 @@
   N->forwardNode(CurNodeH.getNode(), NOffset);
   assert(!CurNodeH.getNode()->isDeadNode());
 
+  // Make all of the outgoing links of N now be outgoing links of CurNodeH.
+  //
+  for (LinkMapTy::iterator ii = N->Links.begin(), ee = N->Links.end();
+       ii != ee; ++ii)
+    if (ii->second.getNode()) {
+      // Compute the offset into the current node at which to
+      // merge this link.  In the common case, this is a linear
+      // relation to the offset in the original node (with
+      // wrapping), but if the current node gets collapsed due to
+      // recursive merging, we must make sure to merge in all remaining
+      // links at offset zero.
+      unsigned MergeOffset = 0;
+       DSNode *CN = CurNodeH.getNode();
+      if (CN->Size != 1)
+        MergeOffset = (ii->first + NOffset) % CN->getSize();
+      CN->addEdgeTo(MergeOffset, ii->second);
+    }
+
+  // Now that there are no outgoing edges, all of the Links are dead.
+  N->Links.clear();
+
   // Merge the globals list...
   CurNodeH.getNode()->mergeGlobals(*N);
 

Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Tue Mar 16 20:00:46 2010
@@ -522,8 +522,13 @@
       Offset += (unsigned)TD.getStructLayout(STy)->getElementOffset(FieldNo);
     } else if (isa<PointerType>(*I)) {
       if (!isa<Constant>(I.getOperand()) ||
-          !cast<Constant>(I.getOperand())->isNullValue())
+          !cast<Constant>(I.getOperand())->isNullValue()) {
         Value.getNode()->setArrayMarker();
+        Value.getNode()->foldNodeCompletely();
+        Value.getNode();
+        Offset = 0;
+        break;
+      }
     }
 
 
@@ -945,6 +950,7 @@
       G->getAuxFunctionCalls() = G->getFunctionCalls();
       setDSGraph(*I, G);
       propagateUnknownFlag(G);
+      G->buildCallGraph(callgraph);
     }
 
 

Modified: poolalloc/trunk/lib/DSA/Printer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Printer.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Tue Mar 16 20:00:46 2010
@@ -365,15 +365,14 @@
 
 
 void DataStructures::dumpCallGraph() const {
-  for (DSCallGraph::key_iterator ki = callgraph.key_begin(),
-          ke = callgraph.key_end(); ki != ke; ++ki)
-    if (*ki != CallSite()) {
-      errs() << ki->getInstruction()->getParent()->getParent()->getName() << ": [";
-      for (DSCallGraph::iterator cbi = callgraph.callee_begin(*ki),
-           cbe = callgraph.callee_end(*ki); cbi != cbe; ++cbi)
-        errs() << (*cbi)->getName() << " ";
-      errs() << "]\n";
-    }
+  for (DSCallGraph::flat_key_iterator ki = callgraph.flat_key_begin(),
+       ke = callgraph.flat_key_end(); ki != ke; ++ki) {
+    errs() << (*ki)->getName() << ": [";
+    for (DSCallGraph::flat_iterator cbi = callgraph.flat_callee_begin(*ki),
+         cbe = callgraph.flat_callee_end(*ki); cbi != cbe; ++cbi)
+      errs() << (*cbi)->getName() << " ";
+    errs() << "]\n";
+  }
 }
 
 // print - Print out the analysis results...

Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Tue Mar 16 20:00:46 2010
@@ -165,7 +165,7 @@
 
   // Recursively traverse all of the callee graphs.
   for (DSGraph::fc_iterator CI = G->fc_begin(), CE = G->fc_end(); CI != CE; ++CI)
-    for (DSCallGraph::iterator I = callgraph.callee_begin(CI->getCallSite()),
+    for (DSCallGraph::callee_iterator I = callgraph.callee_begin(CI->getCallSite()),
            E = callgraph.callee_end(CI->getCallSite()); I != E; ++I)
       ComputePostOrder(**I, Visited, PostOrder);
 
@@ -300,7 +300,7 @@
     }
 
     // For each function in the invoked function list at this call site...
-    DSCallGraph::iterator IPI = callgraph.callee_begin(CI->getCallSite()),
+    DSCallGraph::callee_iterator IPI = callgraph.callee_begin(CI->getCallSite()),
             IPE = callgraph.callee_end(CI->getCallSite());
 
     // Skip over all calls to this graph (SCC calls).
@@ -332,7 +332,7 @@
     // so we build up a new, private, graph that represents the calls of all
     // calls to this set of functions.
     std::vector<const Function*> Callees;
-    for (DSCallGraph::iterator I = callgraph.callee_begin(CI->getCallSite()),
+    for (DSCallGraph::callee_iterator I = callgraph.callee_begin(CI->getCallSite()),
          E = callgraph.callee_end(CI->getCallSite()); I != E; ++I)
       if (!(*I)->isDeclaration())
         Callees.push_back(*I);

Modified: poolalloc/trunk/lib/PoolAllocate/RunTimeAssociate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/RunTimeAssociate.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/RunTimeAssociate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/RunTimeAssociate.cpp Tue Mar 16 20:00:46 2010
@@ -461,7 +461,7 @@
     Instruction *OrigInst =
       cast<Instruction>(FI.getOldValueIfAvailable(CS.getInstruction()));
 
-    DSCallGraph::iterator I = DS->getCallGraph().callee_begin(CS);
+    DSCallGraph::callee_iterator I = DS->getCallGraph().callee_begin(CS);
     if (I != DS->getCallGraph().callee_end(CS))
       CF = *I;
 
@@ -508,7 +508,7 @@
 
 #ifndef NDEBUG
     // Verify that all potential callees at call site have the same DS graph.
-    DSCallGraph::iterator E = DS->getCallGraph().callee_end(CS);
+    DSCallGraph::callee_iterator E = DS->getCallGraph().callee_end(CS);
     for (; I != E; ++I)
       if (!(*I)->isDeclaration())
         assert(CalleeGraph == DS->getDSGraph(**I) &&

Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=98700&r1=98699&r2=98700&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Tue Mar 16 20:00:46 2010
@@ -645,7 +645,7 @@
     Instruction *OrigInst =
       cast<Instruction>(getOldValueIfAvailable(CS.getInstruction()));
 
-    DSCallGraph::iterator I = Graphs.getCallGraph().callee_begin(CS);
+    DSCallGraph::callee_iterator I = Graphs.getCallGraph().callee_begin(CS);
     if (I != Graphs.getCallGraph().callee_end(CS))
       CF = *I;
     
@@ -685,7 +685,7 @@
     
 #ifndef NDEBUG
     // Verify that all potential callees at call site have the same DS graph.
-    DSCallGraph::iterator E = Graphs.getCallGraph().callee_end(OrigInst);
+    DSCallGraph::callee_iterator E = Graphs.getCallGraph().callee_end(OrigInst);
     for (; I != E; ++I)
       if (!(*I)->isDeclaration())
         assert(CalleeGraph == Graphs.getDSGraph(**I) &&





More information about the llvm-commits mailing list