[llvm-commits] [poolalloc] r57375 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DataStructure.h include/poolalloc/PoolAllocate.h lib/DSA/BottomUpClosure.cpp lib/DSA/CompleteBottomUp.cpp lib/DSA/DataStructure.cpp lib/DSA/EquivClassGraphs.cpp lib/DSA/Printer.cpp lib/DSA/StdLibPass.cpp lib/DSA/TopDownClosure.cpp lib/PoolAllocate/AccessTrace.cpp lib/PoolAllocate/PASimple.cpp lib/PoolAllocate/PointerCompress.cpp lib/PoolAllocate/PoolAllocate.cpp lib/PoolAllocate/TransformFunctionBody.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Sat Oct 11 09:52:05 PDT 2008


Author: alenhar2
Date: Sat Oct 11 11:52:04 2008
New Revision: 57375

URL: http://llvm.org/viewvc/llvm-project?rev=57375&view=rev
Log:
Getting closer.  Equiv was redundant with CBU when doing unresolved call merging in Globals during BU due to GlobalEQs.

Removed:
    poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
Modified:
    poolalloc/trunk/include/dsa/DSGraph.h
    poolalloc/trunk/include/dsa/DataStructure.h
    poolalloc/trunk/include/poolalloc/PoolAllocate.h
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp
    poolalloc/trunk/lib/DSA/Printer.cpp
    poolalloc/trunk/lib/DSA/StdLibPass.cpp
    poolalloc/trunk/lib/DSA/TopDownClosure.cpp
    poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp
    poolalloc/trunk/lib/PoolAllocate/PASimple.cpp
    poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp
    poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
    poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp

Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Sat Oct 11 11:52:04 2008
@@ -327,9 +327,12 @@
 
 
   // Aux Function Call iteration
-  typedef std::list<DSCallSite>::const_iterator afc_iterator;
-  afc_iterator afc_begin() const { return AuxFunctionCalls.begin(); }
-  afc_iterator afc_end() const { return AuxFunctionCalls.end(); }
+  typedef std::list<DSCallSite>::iterator afc_iterator;
+  afc_iterator afc_begin() { return AuxFunctionCalls.begin(); }
+  afc_iterator afc_end() { return AuxFunctionCalls.end(); }
+  typedef std::list<DSCallSite>::const_iterator afc_const_iterator;
+  afc_const_iterator afc_begin() const { return AuxFunctionCalls.begin(); }
+  afc_const_iterator afc_end() const { return AuxFunctionCalls.end(); }
 
   /// getNodeForValue - Given a value that is used or defined in the body of the
   /// current function, return the DSNode that it points to.

Modified: poolalloc/trunk/include/dsa/DataStructure.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/include/dsa/DataStructure.h (original)
+++ poolalloc/trunk/include/dsa/DataStructure.h Sat Oct 11 11:52:04 2008
@@ -72,7 +72,7 @@
   EquivalenceClasses<const GlobalValue*> GlobalECs;
 
 
-  void init(DataStructures* D, bool clone, bool printAuxCalls);
+  void init(DataStructures* D, bool clone, bool printAuxCalls, bool copyGlobalAuxCalls);
   void init(TargetData* T);
 
   void formGlobalECs();
@@ -83,18 +83,23 @@
   }
 
   DataStructures(intptr_t id) 
-    :ModulePass(id), TD(0), GraphSource(0), GlobalsGraph(0) {}
+    :ModulePass(id), TD(0), GraphSource(0), GlobalsGraph(0) {
+    //a dummy node for empty call sites
+    ActualCallees[0];
+  }
 
 public:
   callee_iterator callee_begin(const Instruction *I) const {
     ActualCalleesTy::const_iterator ii = ActualCallees.find(I);
-    assert(ii != ActualCallees.end() && "No calls for instruction");
+    if (ii == ActualCallees.end())
+      ii = ActualCallees.find(0);
     return ii->second.begin();
   }
 
   callee_iterator callee_end(const Instruction *I) const {
     ActualCalleesTy::const_iterator ii = ActualCallees.find(I);
-    assert(ii != ActualCallees.end() && "No calls for instruction");
+    if (ii == ActualCallees.end())
+      ii = ActualCallees.find(0);
     return ii->second.end();
   }
 
@@ -127,7 +132,6 @@
   }
 
   void setDSGraph(const Function& F, DSGraph* G) {
-    assert(!DSInfo[&F] && "DSGraph already exists");
     DSInfo[&F] = G;
   }
 
@@ -204,10 +208,16 @@
   std::map<std::vector<const Function*>,
            std::pair<DSGraph*, std::vector<DSNodeHandle> > > IndCallGraphMap;
 
-  BUDataStructures(intptr_t id) : DataStructures(id) {}
+  const char* debugname;
+
 public:
   static char ID;
-  BUDataStructures() : DataStructures((intptr_t)&ID) {}
+  //Child constructor
+  BUDataStructures(intptr_t CID, const char* name)
+    : DataStructures(CID), debugname(name) {}
+  //main constructor
+  BUDataStructures() 
+    : DataStructures((intptr_t)&ID), debugname("dsa-bu") {}
   ~BUDataStructures() { releaseMemory(); }
 
   virtual bool runOnModule(Module &M);
@@ -225,6 +235,9 @@
     AU.addRequired<StdLibDataStructures>();
   }
 
+protected:
+  bool runOnModuleInternal(Module &M);
+
 private:
   void calculateGraph(DSGraph &G);
 
@@ -247,7 +260,6 @@
 ///
 class TDDataStructures : public DataStructures {
   hash_set<const Function*> ArgsRemainIncomplete;
-  BUDataStructures *BUInfo;
 
   /// CallerCallEdges - For a particular graph, we keep a list of these records
   /// which indicates which graphs call this function and from where.
@@ -307,10 +319,12 @@
 /// their callers graphs, making the result more useful for things like pool
 /// allocation.
 ///
-class CompleteBUDataStructures : public  DataStructures {
+class CompleteBUDataStructures : public  BUDataStructures {
+  void buildIndirectFunctionSets(Module &M);
 public:
   static char ID;
-  CompleteBUDataStructures() : DataStructures((intptr_t)&ID) {}
+  CompleteBUDataStructures()
+    : BUDataStructures((intptr_t)&ID, "dsa-cbu") {}
   ~CompleteBUDataStructures() { releaseMemory(); }
 
   virtual bool runOnModule(Module &M);
@@ -322,64 +336,6 @@
   /// print - Print out the analysis results...
   ///
   void print(std::ostream &O, const Module *M) const;
-
-  virtual void releaseMemory();
-
-private:
-  unsigned calculateSCCGraphs(DSGraph &FG, std::vector<DSGraph*> &Stack,
-                              unsigned &NextID,
-                              hash_map<DSGraph*, unsigned> &ValMap);
-  void processGraph(DSGraph &G);
-};
-
-
-/// EquivClassGraphs - This is the same as the complete bottom-up graphs, but
-/// with functions partitioned into equivalence classes and a single merged
-/// DS graph for all functions in an equivalence class.  After this merging,
-/// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
-///
-struct EquivClassGraphs : public DataStructures {
-
-  // Equivalence class where functions that can potentially be called via the
-  // same function pointer are in the same class.
-  EquivalenceClasses<const Function*> FuncECs;
-
-  /// OneCalledFunction - For each indirect call, we keep track of one
-  /// target of the call.  This is used to find equivalence class called by
-  /// a call site.
-  std::map<DSNode*, const Function *> OneCalledFunction;
-
-public:
-  static char ID;
-  EquivClassGraphs();
-
-  /// EquivClassGraphs - Computes the equivalence classes and then the
-  /// folded DS graphs for each class.
-  ///
-
-  virtual bool runOnModule(Module &M);
-
-  /// print - Print out the analysis results...
-  ///
-  void print(std::ostream &O, const Module *M) const;
-
-  /// getSomeCalleeForCallSite - Return any one callee function at
-  /// a call site.
-  ///
-  const Function *getSomeCalleeForCallSite(const CallSite &CS) const;
-
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.addRequired<CompleteBUDataStructures>();
-  }
-
-private:
-  void buildIndirectFunctionSets(Module &M);
-
-  unsigned processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack,
-                      unsigned &NextID,
-                      std::map<DSGraph*, unsigned> &ValMap);
-  void processGraph(DSGraph &FG);
-
 };
 
 } // End llvm namespace

Modified: poolalloc/trunk/include/poolalloc/PoolAllocate.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/PoolAllocate.h?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/include/poolalloc/PoolAllocate.h (original)
+++ poolalloc/trunk/include/poolalloc/PoolAllocate.h Sat Oct 11 11:52:04 2008
@@ -34,7 +34,6 @@
 class DSGraph;
 class Type;
 class AllocaInst;
-class EquivClassGraphs;
 class CallTargetFinder;
 
 namespace PA {
@@ -103,8 +102,7 @@
 
 class PoolAllocateGroup {
 protected:
-  EquivClassGraphs *ECGraphs;
-  TDDataStructures *TDGraphs;
+  DataStructures *Graphs;
 
 public:
   static char ID;
@@ -120,23 +118,23 @@
   virtual const Type * getPoolType() {return 0;}
 
   virtual bool hasDSGraph (const Function & F) const {
-    return ECGraphs->hasDSGraph (F);
+    return Graphs->hasDSGraph (F);
   }
 
   virtual DSGraph & getDSGraph (const Function & F) const {
-    return ECGraphs->getDSGraph (F);
+    return Graphs->getDSGraph (F);
   }
 
   virtual DSGraph & getGlobalsGraph () const {
-    return ECGraphs->getGlobalsGraph ();
+    return Graphs->getGlobalsGraph ();
   }
 
   virtual Value * getPool (const DSNode * N, Function & F) {return 0;}
 
   virtual Value * getGlobalPool (const DSNode * Node) {return 0;}
 
-  virtual CompleteBUDataStructures::callee_iterator callee_begin (Instruction *I) { return ECGraphs->callee_begin(I);}
-  virtual CompleteBUDataStructures::callee_iterator callee_end   (Instruction *I) { return ECGraphs->callee_end(I);}
+  virtual DataStructures::callee_iterator callee_begin (Instruction *I) { return Graphs->callee_begin(I);}
+  virtual DataStructures::callee_iterator callee_end   (Instruction *I) { return Graphs->callee_end(I);}
 };
 
 /// PoolAllocate - The main pool allocation pass
@@ -183,7 +181,7 @@
   
   virtual void getAnalysisUsage(AnalysisUsage &AU) const;
   
-  EquivClassGraphs &getECGraphs() const { return *ECGraphs; }
+  DataStructures &getGraphs() const { return *Graphs; }
 
   /// getOrigFunctionFromClone - Given a pointer to a function that was cloned
   /// from another function, return the original function.  If the argument
@@ -240,11 +238,11 @@
   }
 
   virtual DSGraph & getDSGraph (const Function & F) const {
-    return ECGraphs->getDSGraph (F);
+    return Graphs->getDSGraph (F);
   }
 
   virtual DSGraph & getGlobalsGraph () const {
-    return ECGraphs->getGlobalsGraph ();
+    return Graphs->getGlobalsGraph ();
   }
 
   virtual Value * getPool (const DSNode * N, Function & F) {
@@ -265,14 +263,14 @@
       return I->second;
   }
 
-  virtual CompleteBUDataStructures::callee_iterator
+  virtual DataStructures::callee_iterator
   callee_begin (Instruction * I) {
-    return ECGraphs->callee_begin(I);
+    return Graphs->callee_begin(I);
   }
 
-  virtual CompleteBUDataStructures::callee_iterator
+  virtual DataStructures::callee_iterator
   callee_end (Instruction * I) {
-    return ECGraphs->callee_end(I);
+    return Graphs->callee_end(I);
   }
 
 protected:

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

==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Sat Oct 11 11:52:04 2008
@@ -18,16 +18,13 @@
 #include "dsa/DataStructure.h"
 #include "dsa/DSGraph.h"
 #include "llvm/Module.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/Timer.h"
 using namespace llvm;
 
 namespace {
   STATISTIC (MaxSCC, "Maximum SCC Size in Call Graph");
-  STATISTIC (NumBUInlines, "Number of graphs inlined");
+  STATISTIC (NumInlines, "Number of graphs inlined");
   STATISTIC (NumCallEdges, "Number of 'actual' call edges");
 
   RegisterPass<BUDataStructures>
@@ -40,8 +37,12 @@
 // program.
 //
 bool BUDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<StdLibDataStructures>(), false, true);
+  init(&getAnalysis<StdLibDataStructures>(), false, true, false);
 
+  return runOnModuleInternal(M);
+}
+
+bool BUDataStructures::runOnModuleInternal(Module& M) {
   std::vector<const Function*> Stack;
   hash_map<const Function*, unsigned> ValMap;
   unsigned NextID = 1;
@@ -50,13 +51,15 @@
   if (MainFunc) {
     calculateGraphs(MainFunc, Stack, NextID, ValMap);
     CloneAuxIntoGlobal(getDSGraph(*MainFunc));
+  } else {
+    DOUT << debugname << ": No 'main' function found!\n";
   }
 
   // Calculate the graphs for any functions that are unreachable from main...
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
     if (!I->isDeclaration() && !hasDSGraph(*I)) {
       if (MainFunc)
-        DOUT << "*** BU: Function unreachable from main: "
+        DOUT << debugname << ": Function unreachable from main: "
              << I->getName() << "\n";
       calculateGraphs(I, Stack, NextID, ValMap);     // Calculate all graphs.
       CloneAuxIntoGlobal(getDSGraph(*I));
@@ -348,8 +351,20 @@
   ReachabilityCloner RC(GG, G, 0);
 
   for(DSGraph::afc_iterator ii = G.afc_begin(), ee = G.afc_end();
-      ii != ee; ++ii)
-    GG.getAuxFunctionCalls().push_front(RC.cloneCallSite(*ii));
+      ii != ee; ++ii) {
+    //If we can, merge with an existing call site for this instruction
+    if (GG.hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) {
+      DSGraph::afc_iterator GGii;
+      for(GGii = GG.afc_begin(); GGii != GG.afc_end(); ++GGii)
+        if (GGii->getCallSite().getInstruction()->getOperand(0) ==
+            ii->getCallSite().getInstruction()->getOperand(0))
+          break;
+      assert (GGii != GG.afc_end() && "Callsite should exist but doesn't");
+      RC.cloneCallSite(*ii).mergeWith(*GGii);
+    } else {
+      GG.getAuxFunctionCalls().push_front(RC.cloneCallSite(*ii));
+    }
+  }
 }
 
 void BUDataStructures::calculateGraph(DSGraph &Graph) {
@@ -432,7 +447,7 @@
       Graph.mergeInGraph(CS, *Callee, *GI,
                          DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes|
                          (isComplete?0:DSGraph::DontCloneAuxCallNodes));
-      ++NumBUInlines;
+      ++NumInlines;
     } else {
       DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
       DEBUG(std::cerr << "  calls " << CalledFuncs.size()
@@ -484,7 +499,7 @@
           // bother merging it in again.
           if (!GI->containsFunction(*I)) {
             GI->cloneInto(getDSGraph(**I));
-            ++NumBUInlines;
+            ++NumInlines;
           }
           
           std::vector<DSNodeHandle> NextArgs;
@@ -517,7 +532,7 @@
                          DSGraph::StripAllocaBit |
                          DSGraph::DontCloneCallNodes|
                          (isComplete?0:DSGraph::DontCloneAuxCallNodes));
-      ++NumBUInlines;
+      ++NumInlines;
     }
     if (isComplete)
       TempFCs.erase(TempFCs.begin());
@@ -575,7 +590,7 @@
            << Graph.getAuxFunctionCalls().size() << "]\n";
       Graph.mergeInGraph(CS, *Callee, *GI,
                          DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
-      ++NumBUInlines;
+      ++NumInlines;
     } else {
       DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
       DEBUG(std::cerr << "  calls " << CalledFuncs.size()
@@ -627,7 +642,7 @@
           // bother merging it in again.
           if (!GI->containsFunction(*I)) {
             GI->cloneInto(getDSGraph(**I));
-            ++NumBUInlines;
+            ++NumInlines;
           }
           
           std::vector<DSNodeHandle> NextArgs;
@@ -659,7 +674,7 @@
       Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
                          DSGraph::StripAllocaBit |
                          DSGraph::DontCloneCallNodes);
-      ++NumBUInlines;
+      ++NumInlines;
     }
   }
 

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

==============================================================================
--- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original)
+++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Sat Oct 11 11:52:04 2008
@@ -15,18 +15,15 @@
 
 #define DEBUG_TYPE "dsa-cbu"
 #include "dsa/DataStructure.h"
-#include "llvm/Module.h"
 #include "dsa/DSGraph.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/SCCIterator.h"
+#include "llvm/Module.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Debug.h"
 using namespace llvm;
 
 namespace {
   RegisterPass<CompleteBUDataStructures>
   X("dsa-cbu", "'Complete' Bottom-up Data Structure Analysis");
-  STATISTIC (NumCBUInlines, "Number of graphs inlined");
 }
 
 char CompleteBUDataStructures::ID;
@@ -35,177 +32,28 @@
 // program.
 //
 bool CompleteBUDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<BUDataStructures>(), false, true);
-
-  std::vector<DSGraph*> Stack;
-  hash_map<DSGraph*, unsigned> ValMap;
-  unsigned NextID = 1;
-
-  Function *MainFunc = M.getFunction("main");
-  if (MainFunc) {
-    if (!MainFunc->isDeclaration())
-      calculateSCCGraphs(getOrCreateGraph(MainFunc), Stack, NextID, ValMap);
-  } else {
-    DOUT << "CBU-DSA: No 'main' function found!\n";
-  }
+  init(&getAnalysis<BUDataStructures>(), false, true, false);
 
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && !hasDSGraph(*I)) {
-      if (MainFunc) {
-        DOUT << "*** CBU: Function unreachable from main: "
-             << I->getName() << "\n";
-      }
-      calculateSCCGraphs(getOrCreateGraph(I), Stack, NextID, ValMap);
-    }
-
-  GlobalsGraph->removeTriviallyDeadNodes();
-
-
-  // Merge the globals variables (not the calls) from the globals graph back
-  // into the main function's graph so that the main function contains all of
-  // the information about global pools and GV usage in the program.
-  if (MainFunc && !MainFunc->isDeclaration()) {
-    DSGraph &MainGraph = getOrCreateGraph(MainFunc);
-    const DSGraph &GG = *MainGraph.getGlobalsGraph();
-    ReachabilityCloner RC(MainGraph, GG,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-
-    // Clone the global nodes into this graph.
-    for (DSScalarMap::global_iterator I = GG.getScalarMap().global_begin(),
-           E = GG.getScalarMap().global_end(); I != E; ++I)
-      if (isa<GlobalVariable>(*I))
-        RC.getClonedNH(GG.getNodeForValue(*I));
-
-    MainGraph.maskIncompleteMarkers();
-    MainGraph.markIncompleteNodes(DSGraph::MarkFormalArgs |
-                                  DSGraph::IgnoreGlobals);
-  }
+  buildIndirectFunctionSets(M);
 
-  return false;
+  return runOnModuleInternal(M);
 }
 
-unsigned CompleteBUDataStructures::calculateSCCGraphs(DSGraph &FG,
-                                                  std::vector<DSGraph*> &Stack,
-                                                  unsigned &NextID,
-                                         hash_map<DSGraph*, unsigned> &ValMap) {
-  assert(!ValMap.count(&FG) && "Shouldn't revisit functions!");
-  unsigned Min = NextID++, MyID = Min;
-  ValMap[&FG] = Min;
-  Stack.push_back(&FG);
-
-  // The edges out of the current node are the call site targets...
-  for (DSGraph::fc_iterator CI = FG.fc_begin(), CE = FG.fc_end();
-       CI != CE; ++CI) {
-    Instruction *Call = CI->getCallSite().getInstruction();
-
-    // Loop over all of the actually called functions...
-    for (callee_iterator I = callee_begin(Call), E = callee_end(Call); 
-         I != E ; ++I) {
-      if (!(*I)->isDeclaration()) {
-        DSGraph &Callee = getOrCreateGraph(*I);
-        unsigned M;
-        // Have we visited the destination function yet?
-        hash_map<DSGraph*, unsigned>::iterator It = ValMap.find(&Callee);
-        if (It == ValMap.end())  // No, visit it now.
-          M = calculateSCCGraphs(Callee, Stack, NextID, ValMap);
-        else                    // Yes, get it's number.
-          M = It->second;
-        if (M < Min) Min = M;
-      }
+void CompleteBUDataStructures::buildIndirectFunctionSets(Module &M) {
+  // Loop over all of the indirect calls in the program.  If a call site can
+  // call multiple different functions, we need to unify all of the callees into
+  // the same equivalence class.
+  std::vector<const Instruction*> keys;
+  callee_get_keys(keys);
+
+  //mege nodes in the global graph for these functions
+  for (std::vector<const Instruction*>::iterator ii = keys.begin(), ee = keys.end();
+       ii != ee; ++ii) {
+    callee_iterator base = callee_begin(*ii);
+    for (callee_iterator csi = callee_begin(*ii), cse = callee_end(*ii); 
+         csi != cse; ++csi) {
+      GlobalECs.unionSets(*base, *csi);
+      GlobalsGraph->getNodeForValue(*base).mergeWith(GlobalsGraph->getNodeForValue(*csi));
     }
   }
-
-  assert(ValMap[&FG] == 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.
-  bool IsMultiNodeSCC = false;
-  while (Stack.back() != &FG) {
-    DSGraph *NG = Stack.back();
-    ValMap[NG] = ~0U;
-
-    FG.cloneInto(*NG);
-
-    // Update the DSInfo map and delete the old graph...
-    for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
-         I != NG->retnodes_end(); ++I)
-      setDSGraph(*I->first, &FG);
-
-    // Remove NG from the ValMap since the pointer may get recycled.
-    ValMap.erase(NG);
-    delete NG;
-
-    Stack.pop_back();
-    IsMultiNodeSCC = true;
-  }
-
-  // Clean up the graph before we start inlining a bunch again...
-  if (IsMultiNodeSCC)
-    FG.removeTriviallyDeadNodes();
-
-  Stack.pop_back();
-  processGraph(FG);
-  ValMap[&FG] = ~0U;
-  return MyID;
-}
-
-
-/// processGraph - Process the BU graphs for the program in bottom-up order on
-/// the SCC of the __ACTUAL__ call graph.  This builds "complete" BU graphs.
-void CompleteBUDataStructures::processGraph(DSGraph &G) {
-  hash_set<Instruction*> calls;
-
-  // The edges out of the current node are the call site targets...
-  unsigned i = 0;
-  for (DSGraph::fc_iterator CI = G.fc_begin(), CE = G.fc_end(); CI != CE;
-       ++CI, ++i) {
-    const DSCallSite &CS = *CI;
-    Instruction *TheCall = CS.getCallSite().getInstruction();
-
-    assert(calls.insert(TheCall).second &&
-           "Call instruction occurs multiple times in graph??");
-
-    // 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)
-      continue;
-
-    // Loop over all of the potentially called functions...
-    // Inline direct calls as well as indirect calls because the direct
-    // callee may have indirect callees and so may have changed.
-    //
-    unsigned TNum = 0, Num = 0;
-    DEBUG(Num = std::distance(callee_begin(TheCall), callee_end(TheCall)));
-    for (callee_iterator I = callee_begin(TheCall), E = callee_end(TheCall);
-         I != E; ++I, ++TNum) {
-      const Function *CalleeFunc = *I;
-      if (!CalleeFunc->isDeclaration()) {
-        // Merge the callee's graph into this graph.  This works for normal
-        // calls or for self recursion within an SCC.
-        DSGraph &GI = getOrCreateGraph(CalleeFunc);
-        ++NumCBUInlines;
-        G.mergeInGraph(CS, *CalleeFunc, GI,
-                       DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes |
-                       DSGraph::DontCloneAuxCallNodes);
-        DOUT << "    Inlining graph [" << i << "/"
-             << G.getFunctionCalls().size()-1
-             << ":" << TNum << "/" << Num-1 << "] for "
-             << CalleeFunc->getName() << "["
-             << GI.getGraphSize() << "+" << GI.getAuxFunctionCalls().size()
-             << "] into '" /*<< G.getFunctionNames()*/ << "' ["
-             << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
-             << "]\n";
-      }
-    }
-  }
-
-  // Recompute the Incomplete markers
-  G.maskIncompleteMarkers();
-  G.markIncompleteNodes(DSGraph::MarkFormalArgs);
-
-  // Delete dead nodes.  Treat globals that are unreachable but that can
-  // reach live nodes as live.
-  G.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
 }

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

==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Sat Oct 11 11:52:04 2008
@@ -1607,7 +1607,7 @@
     RHS.ReturnNodes.clear();
   }
 
-  // Merge the scalar map in.
+ // Merge the scalar map in.
   ScalarMap.spliceFrom(RHS.ScalarMap);
 }
 
@@ -1810,7 +1810,7 @@
   HackedGraphSCCFinder SCCFinder(RC);
 
   if (!(CloneFlags & DontCloneAuxCallNodes))
-    for (afc_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
+    for (afc_const_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
       if (SCCFinder.PathExistsToClonedNode(*I))
         AuxCallToCopy.push_back(&*I);
 //       else if (I->isIndirectCall()){
@@ -2493,7 +2493,7 @@
     AssertCallSiteInGraph(*I);
 }
 void DSGraph::AssertAuxCallNodesInGraph() const {
-  for (afc_iterator I = afc_begin(), E = afc_end(); I != E; ++I)
+  for (afc_const_iterator I = afc_begin(), E = afc_end(); I != E; ++I)
     AssertCallSiteInGraph(*I);
 }
 
@@ -2840,14 +2840,16 @@
   DEBUG(if(MadeChange) G.AssertGraphOK());
 }
 
-void DataStructures::init(DataStructures* D, bool clone, bool printAuxCalls) {
+void DataStructures::init(DataStructures* D, bool clone, bool printAuxCalls, 
+                          bool copyGlobalAuxCalls) {
   assert (!GraphSource && "Already init");
   GraphSource = D;
   Clone = clone;
   TD = D->TD;
   ActualCallees = D->ActualCallees;
   GlobalECs = D->getGlobalECs();
-  GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs);
+  GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs, 
+                             copyGlobalAuxCalls?0:DSGraph::DontCloneAuxCallNodes);
   if (printAuxCalls) GlobalsGraph->setPrintAuxCalls();
 }
 

Removed: poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp?rev=57374&view=auto

==============================================================================
--- poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (original)
+++ poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (removed)
@@ -1,427 +0,0 @@
-//===- EquivClassGraphs.cpp - Merge equiv-class graphs & inline bottom-up -===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass is the same as the complete bottom-up graphs, but
-// with functions partitioned into equivalence classes and a single merged
-// DS graph for all functions in an equivalence class.  After this merging,
-// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "ECGraphs"
-#include "dsa/DataStructure.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "dsa/DSGraph.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/SCCIterator.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/EquivalenceClasses.h"
-#include "llvm/ADT/STLExtras.h"
-using namespace llvm;
-
-namespace {
-  RegisterPass<EquivClassGraphs> X("dsa-eq",
-                    "Equivalence-class Bottom-up Data Structure Analysis");
-  STATISTIC (NumEquivBUInlines,
-                                "Number of graphs inlined");
-  STATISTIC (NumFoldGraphInlines,
-                                  "Number of graphs inlined");
-}
-
-char EquivClassGraphs::ID = 0;
-
-EquivClassGraphs::EquivClassGraphs() : DataStructures((intptr_t)&ID) {}
-
-#ifndef NDEBUG
-template<typename GT>
-static void CheckAllGraphs(Module *M, GT &ECGraphs) {
-  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
-    if (!I->isDeclaration()) {
-      DSGraph &G = ECGraphs.getDSGraph(*I);
-      if (G.retnodes_begin()->first != I)
-        continue;  // Only check a graph once.
-
-      DSGraph::NodeMapTy GlobalsGraphNodeMapping;
-      G.computeGToGGMapping(GlobalsGraphNodeMapping);
-    }
-}
-#endif
-
-// getSomeCalleeForCallSite - Return any one callee function at a call site.
-//
-const Function *EquivClassGraphs::getSomeCalleeForCallSite(const CallSite &CS) const{
-  Function *thisFunc = CS.getCaller();
-  assert(thisFunc && "getSomeCalleeForCallSite(): Not a valid call site?");
-  DSGraph &DSG = getDSGraph(*thisFunc);
-  DSNode *calleeNode = DSG.getNodeForValue(CS.getCalledValue()).getNode();
-  std::map<DSNode*, const Function *>::const_iterator I =
-    OneCalledFunction.find(calleeNode);
-  return (I == OneCalledFunction.end())? NULL : I->second;
-}
-
-// runOnModule - Calculate the bottom up data structure graphs for each function
-// in the program.
-//
-bool EquivClassGraphs::runOnModule(Module &M) {
-  init(&getAnalysis<CompleteBUDataStructures>(), false, true);
-
-  // Find equivalence classes of functions called from common call sites.
-  // Fold the CBU graphs for all functions in an equivalence class.
-  buildIndirectFunctionSets(M);
-
-  // Stack of functions used for Tarjan's SCC-finding algorithm.
-  std::vector<DSGraph*> Stack;
-  std::map<DSGraph*, unsigned> ValMap;
-  unsigned NextID = 1;
-
-  const Function *MainFunc = M.getFunction("main");
-  if (MainFunc && !MainFunc->isDeclaration()) {
-    processSCC(getOrCreateGraph(MainFunc), Stack, NextID, ValMap);
-  } else {
-    cerr << "Fold Graphs: No 'main' function found!\n";
-  }
-
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration())
-      processSCC(getOrCreateGraph(I), Stack, NextID, ValMap);
-
-  DEBUG(CheckAllGraphs(&M, *this));
-
-  getGlobalsGraph().removeTriviallyDeadNodes();
-  getGlobalsGraph().markIncompleteNodes(DSGraph::IgnoreGlobals);
-
-  // Merge the globals variables (not the calls) from the globals graph back
-  // into the main function's graph so that the main function contains all of
-  // the information about global pools and GV usage in the program.
-  if (MainFunc && !MainFunc->isDeclaration()) {
-    DSGraph &MainGraph = getOrCreateGraph(MainFunc);
-    const DSGraph &GG = *MainGraph.getGlobalsGraph();
-    ReachabilityCloner RC(MainGraph, GG,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-
-    // Clone the global nodes into this graph.
-    for (DSScalarMap::global_iterator I = GG.getScalarMap().global_begin(),
-           E = GG.getScalarMap().global_end(); I != E; ++I)
-      if (isa<GlobalVariable>(*I))
-        RC.getClonedNH(GG.getNodeForValue(*I));
-
-    MainGraph.maskIncompleteMarkers();
-    MainGraph.markIncompleteNodes(DSGraph::MarkFormalArgs |
-                                  DSGraph::IgnoreGlobals);
-  }
-
-  // Final processing.  Note that dead node elimination may actually remove
-  // globals from a function graph that are immediately used.  If there are no
-  // scalars pointing to the node (e.g. because the only use is a direct store
-  // to a scalar global) we have to make sure to rematerialize the globals back
-  // into the graphs here, or clients will break!
-  for (Module::global_iterator GI = M.global_begin(), E = M.global_end();
-       GI != E; ++GI)
-    // This only happens to first class typed globals.
-    if (GI->getType()->getElementType()->isFirstClassType())
-      for (Value::use_iterator UI = GI->use_begin(), E = GI->use_end();
-           UI != E; ++UI)
-        // This only happens to direct uses by instructions.
-        if (Instruction *User = dyn_cast<Instruction>(*UI)) {
-          DSGraph &DSG = getOrCreateGraph(User->getParent()->getParent());
-          if (!DSG.getScalarMap().count(GI)) {
-            // If this global does not exist in the graph, but it is immediately
-            // used by an instruction in the graph, clone it over from the
-            // globals graph.
-            ReachabilityCloner RC(DSG, *GlobalsGraph, 0);
-            RC.getClonedNH(GlobalsGraph->getNodeForValue(GI));
-          }
-        }
-
-  return false;
-}
-
-
-// buildIndirectFunctionSets - Iterate over the module looking for indirect
-// calls to functions.  If a call site can invoke any functions [F1, F2... FN],
-// unify the N functions together in the FuncECs set.
-//
-void EquivClassGraphs::buildIndirectFunctionSets(Module &M) {
-  // Loop over all of the indirect calls in the program.  If a call site can
-  // call multiple different functions, we need to unify all of the callees into
-  // the same equivalence class.
-  std::vector<const Instruction*> keys;
-  callee_get_keys(keys);
-
-  for (std::vector<const Instruction*>::iterator ii = keys.begin(), ee = keys.end();
-       ii != ee; ++ii) {
-    const Function* F = 0;
-    for (callee_iterator csi = callee_begin(*ii), cse = callee_end(*ii); 
-         csi != cse; ++csi) {
-      if (F != *csi) {
-        F = *csi;
-        FuncECs.insert(*csi);
-        const Function *thisFunc = (*ii)->getParent()->getParent();
-        DSGraph &TFG = getOrCreateGraph(thisFunc);
-        DSNode *calleeNode = TFG.getNodeForValue((*ii)->getOperand(0)).getNode();
-        OneCalledFunction[calleeNode] = *csi;
-      } else {
-        FuncECs.unionSets(*csi, F);
-      }
-    }
-
-    // Now include all functions that share a graph with any function in the
-    // equivalence class.  More precisely, if F is in the class, and G(F) is
-    // its graph, then we include all other functions that are also in G(F).
-    // Currently, that is just the functions in the same call-graph-SCC as F.
-    //
-    DSGraph& funcDSGraph = getOrCreateGraph(F);
-    for (DSGraph::retnodes_iterator RI = funcDSGraph.retnodes_begin(),
-           RE = funcDSGraph.retnodes_end(); RI != RE; ++RI)
-      FuncECs.unionSets(F, RI->first);
-  }
-
-  // Now that all of the equivalences have been built, merge the graphs for
-  // each equivalence class.
-  //
-  DOUT << "\nIndirect Function Equivalence Sets:\n";
-  for (EquivalenceClasses<const Function*>::iterator EQSI = FuncECs.begin(), E =
-         FuncECs.end(); EQSI != E; ++EQSI) {
-    if (!EQSI->isLeader()) continue;
-
-    EquivalenceClasses<const Function*>::member_iterator SI =
-      FuncECs.member_begin(EQSI);
-    assert(SI != FuncECs.member_end() && "Empty equiv set??");
-    EquivalenceClasses<const Function*>::member_iterator SN = SI;
-    ++SN;
-    if (SN == FuncECs.member_end())
-      continue;   // Single function equivalence set, no merging to do.
-
-    const Function* LF = *SI;
-
-#ifndef NDEBUG
-    DOUT <<"  Equivalence set for leader " << LF->getName() <<" = ";
-    for (SN = SI; SN != FuncECs.member_end(); ++SN)
-      DOUT << " " << (*SN)->getName() << "," ;
-    DOUT << "\n";
-#endif
-
-    // This equiv class has multiple functions: merge their graphs.  First,
-    // clone the CBU graph for the leader and make it the common graph for the
-    // equivalence graph.
-    DSGraph &MergedG = getOrCreateGraph(LF);
-
-    // Record the argument nodes for use in merging later below.
-    std::vector<DSNodeHandle> ArgNodes;
-
-    for (Function::const_arg_iterator AI = LF->arg_begin(), E = LF->arg_end();
-         AI != E; ++AI)
-      if (DS::isPointerType(AI->getType()))
-        ArgNodes.push_back(MergedG.getNodeForValue(AI));
-
-    // Merge in the graphs of all other functions in this equiv. class.  Note
-    // that two or more functions may have the same graph, and it only needs
-    // to be merged in once.
-    std::set<DSGraph*> GraphsMerged;
-    GraphsMerged.insert(&getOrCreateGraph(LF));
-
-    for (++SI; SI != FuncECs.member_end(); ++SI) {
-      const Function *F = *SI;
-      DSGraph &CBUGraph = getOrCreateGraph(F);
-      if (GraphsMerged.insert(&CBUGraph).second) {
-        // Record the "folded" graph for the function.
-        for (DSGraph::retnodes_iterator I = CBUGraph.retnodes_begin(),
-               E = CBUGraph.retnodes_end(); I != E; ++I)
-          setDSGraph(*I->first, &MergedG);
-
-        // Clone this member of the equivalence class into MergedG.
-        MergedG.cloneInto(CBUGraph);
-      }
-
-      // Merge the return nodes of all functions together.
-      MergedG.getReturnNodes()[LF].mergeWith(MergedG.getReturnNodes()[F]);
-
-      // Merge the function arguments with all argument nodes found so far.
-      // If there are extra function args, add them to the vector of argNodes
-      Function::const_arg_iterator AI2 = F->arg_begin(), AI2end = F->arg_end();
-      for (unsigned arg = 0, numArgs = ArgNodes.size();
-           arg != numArgs && AI2 != AI2end; ++AI2, ++arg)
-        if (DS::isPointerType(AI2->getType()))
-          ArgNodes[arg].mergeWith(MergedG.getNodeForValue(AI2));
-
-      for ( ; AI2 != AI2end; ++AI2)
-        if (DS::isPointerType(AI2->getType()))
-          ArgNodes.push_back(MergedG.getNodeForValue(AI2));
-      DEBUG(MergedG.AssertGraphOK());
-    }
-  }
-  DOUT << "\n";
-}
-
-
-unsigned EquivClassGraphs::
-processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack, unsigned &NextID,
-           std::map<DSGraph*, unsigned> &ValMap) {
-  std::map<DSGraph*, unsigned>::iterator It = ValMap.lower_bound(&FG);
-  if (It != ValMap.end() && It->first == &FG)
-    return It->second;
-
-  DOUT << "    ProcessSCC for function " << FG.getFunctionNames() << "\n";
-
-  unsigned Min = NextID++, MyID = Min;
-  ValMap[&FG] = Min;
-  Stack.push_back(&FG);
-
-  // The edges out of the current node are the call site targets...
-  for (DSGraph::fc_iterator CI = FG.fc_begin(), CE = FG.fc_end();
-       CI != CE; ++CI) {
-    Instruction *Call = CI->getCallSite().getInstruction();
-
-    // Loop over all of the actually called functions...
-    for (callee_iterator I = callee_begin(Call), E = callee_end(Call);
-         I != E; ++I)
-      if (!(*I)->isDeclaration()) {
-        // Process the callee as necessary.
-        unsigned M = processSCC(getOrCreateGraph(*I),
-                                Stack, NextID, ValMap);
-        if (M < Min) Min = M;
-      }
-  }
-
-  assert(ValMap[&FG] == 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.
-  bool MergedGraphs = false;
-  while (Stack.back() != &FG) {
-    DSGraph *NG = Stack.back();
-    ValMap[NG] = ~0U;
-
-    // If the SCC found is not the same as those found in CBU, make sure to
-    // merge the graphs as appropriate.
-    FG.cloneInto(*NG);
-
-    // Update the DSInfo map and delete the old graph...
-    for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
-         I != NG->retnodes_end(); ++I)
-      setDSGraph(*I->first, &FG);
-
-    // Remove NG from the ValMap since the pointer may get recycled.
-    ValMap.erase(NG);
-    delete NG;
-    MergedGraphs = true;
-    Stack.pop_back();
-  }
-
-  // Clean up the graph before we start inlining a bunch again.
-  if (MergedGraphs)
-    FG.removeTriviallyDeadNodes();
-
-  Stack.pop_back();
-
-  processGraph(FG);
-  ValMap[&FG] = ~0U;
-  return MyID;
-}
-
-
-/// processGraph - Process the CBU graphs for the program in bottom-up order on
-/// the SCC of the __ACTUAL__ call graph.  This builds final folded CBU graphs.
-void EquivClassGraphs::processGraph(DSGraph &G) {
-  DOUT << "    ProcessGraph for function " << G.getFunctionNames() << "\n";
-
-  hash_set<Instruction*> calls;
-
-  // Else we need to inline some callee graph.  Visit all call sites.
-  // The edges out of the current node are the call site targets...
-  unsigned i = 0;
-  for (DSGraph::fc_iterator CI = G.fc_begin(), CE = G.fc_end(); CI != CE;
-       ++CI, ++i) {
-    const DSCallSite &CS = *CI;
-    Instruction *TheCall = CS.getCallSite().getInstruction();
-
-    assert(calls.insert(TheCall).second &&
-           "Call instruction occurs multiple times in graph??");
-
-    if (CS.getRetVal().isNull() && CS.getNumPtrArgs() == 0)
-      continue;
-
-    // Inline the common callee graph into the current graph, if the callee
-    // graph has not changed.  Note that all callees should have the same
-    // graph so we only need to do this once.
-    //
-    DSGraph* CalleeGraph = NULL;
-    callee_iterator I = callee_begin(TheCall), E = callee_end(TheCall);
-    unsigned TNum, Num;
-
-    // Loop over all potential callees to find the first non-external callee.
-    for (TNum = 0, Num = std::distance(I, E); I != E; ++I, ++TNum)
-      if (!(*I)->isDeclaration())
-        break;
-
-    // Now check if the graph has changed and if so, clone and inline it.
-    if (I != E) {
-      const Function *CalleeFunc = *I;
-
-      // Merge the callee's graph into this graph, if not already the same.
-      // Callees in the same equivalence class (which subsumes those
-      // in the same SCCs) have the same graph.  Note that all recursion
-      // including self-recursion have been folded in the equiv classes.
-      //
-      CalleeGraph = &getOrCreateGraph(CalleeFunc);
-      if (CalleeGraph != &G) {
-        ++NumFoldGraphInlines;
-        G.mergeInGraph(CS, *CalleeFunc, *CalleeGraph,
-                       DSGraph::StripAllocaBit |
-                       DSGraph::DontCloneCallNodes |
-                       DSGraph::DontCloneAuxCallNodes);
-        DOUT << "    Inlining graph [" << i << "/"
-             << G.getFunctionCalls().size()-1
-             << ":" << TNum << "/" << Num-1 << "] for "
-             << CalleeFunc->getName() << "["
-             << CalleeGraph->getGraphSize() << "+"
-             << CalleeGraph->getAuxFunctionCalls().size()
-             << "] into '" /*<< G.getFunctionNames()*/ << "' ["
-             << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
-             << "]\n";
-      }
-    }
-
-#ifndef NDEBUG
-    // Now loop over the rest of the callees and make sure they have the
-    // same graph as the one inlined above.
-    if (CalleeGraph)
-      for (++I, ++TNum; I != E; ++I, ++TNum)
-        if (!(*I)->isDeclaration())
-          assert(CalleeGraph == &getOrCreateGraph(*I) &&
-                 "Callees at a call site have different graphs?");
-#endif
-  }
-
-  // Recompute the Incomplete markers.
-  G.maskIncompleteMarkers();
-  G.markIncompleteNodes(DSGraph::MarkFormalArgs);
-
-  // Delete dead nodes.  Treat globals that are unreachable but that can
-  // reach live nodes as live.
-  G.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-  // When this graph is finalized, clone the globals in the graph into the
-  // globals graph to make sure it has everything, from all graphs.
-  ReachabilityCloner RC(*G.getGlobalsGraph(), G, DSGraph::StripAllocaBit);
-
-  // Clone everything reachable from globals in the function graph into the
-  // globals graph.
-  DSScalarMap &MainSM = G.getScalarMap();
-  for (DSScalarMap::global_iterator I = MainSM.global_begin(),
-         E = MainSM.global_end(); I != E; ++I)
-    RC.getClonedNH(MainSM[*I]);
-
-  DOUT << "  -- DONE ProcessGraph for function " << G.getFunctionNames() <<"\n";
-}

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

==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Sat Oct 11 11:52:04 2008
@@ -358,10 +358,3 @@
   if (DontPrintAnything) return;
   printCollection(*this, O, M, "cbu.");
 }
-
-
-void EquivClassGraphs::print(std::ostream &O, const Module *M) const {
-  if (DontPrintAnything) return;
-  printCollection(*this, O, M, "eq.");
-}
-

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

==============================================================================
--- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original)
+++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Sat Oct 11 11:52:04 2008
@@ -164,7 +164,7 @@
 }
 
 bool StdLibDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<LocalDataStructures>(), false, true);
+  init(&getAnalysis<LocalDataStructures>(), false, true, false);
 
   //Clone Module
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 

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

==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Sat Oct 11 11:52:04 2008
@@ -61,7 +61,7 @@
 // program.
 //
 bool TDDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<BUDataStructures>(), true, true);
+  init(&getAnalysis<BUDataStructures>(), true, true, true);
 
   // Figure out which functions must not mark their arguments complete because
   // they are accessible outside this compilation unit.  Currently, these

Modified: poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp Sat Oct 11 11:52:04 2008
@@ -27,7 +27,7 @@
   /// descriptor loaded from.
   class PoolAccessTrace : public ModulePass {
     PoolAllocate *PoolAlloc;
-    EquivClassGraphs *ECG;
+    DataStructures *G;
     Constant *AccessTraceInitFn, *PoolAccessTraceFn;
     const Type *VoidPtrTy;
   public:
@@ -39,7 +39,7 @@
     void getAnalysisUsage(AnalysisUsage &AU) const;
 
     const DSGraph &getGraphForFunc(PA::FuncInfo *FI) const {
-      return ECG->getDSGraph(FI->F);
+      return G->getDSGraph(FI->F);
     }
     static char ID;
 
@@ -59,7 +59,7 @@
   AU.addRequired<PoolAllocatePassAllPools>();
 
   // Need information from DSA.
-  AU.addRequired<EquivClassGraphs>();
+  AU.addRequired<CompleteBUDataStructures>();
 }
 
 void PoolAccessTrace::InitializeLibraryFunctions(Module &M) {
@@ -100,7 +100,7 @@
 
 bool PoolAccessTrace::runOnModule(Module &M) {
   PoolAlloc = &getAnalysis<PoolAllocatePassAllPools>();
-  ECG = &getAnalysis<EquivClassGraphs>();
+  G = &getAnalysis<CompleteBUDataStructures>();
 
   // Create the function prototypes for runtime library.
   InitializeLibraryFunctions(M);
@@ -124,7 +124,7 @@
       continue;
 
     // Get the DSGraph for this function.
-    DSGraph &DSG = ECG->getDSGraph(FI->F);
+    DSGraph &DSG = G->getDSGraph(FI->F);
 
     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
       for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)

Modified: poolalloc/trunk/lib/PoolAllocate/PASimple.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PASimple.cpp?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PASimple.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PASimple.cpp Sat Oct 11 11:52:04 2008
@@ -73,9 +73,9 @@
 
 void PoolAllocateSimple::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetData>();
-  AU.addRequiredTransitive<EquivClassGraphs>();
+  AU.addRequiredTransitive<CompleteBUDataStructures>();
 
-  AU.addPreserved<EquivClassGraphs>();
+  AU.addPreserved<CompleteBUDataStructures>();
 
   AU.setPreservesAll();
 }
@@ -100,9 +100,9 @@
 bool PoolAllocateSimple::runOnModule(Module &M) {
   if (M.begin() == M.end()) return false;
 
-  // Get the Target Data information and the ECGraphs
-  ECGraphs = &getAnalysis<EquivClassGraphs>();   // folded inlined CBU graphs
-  assert (ECGraphs && "No ECGraphs pass available!\n");
+  // Get the Target Data information and the Graphs
+  Graphs = &getAnalysis<CompleteBUDataStructures>();   // folded inlined CBU graphs
+  assert (Graphs && "No ECGraphs pass available!\n");
   TargetData & TD = getAnalysis<TargetData>();
 
   // Add the pool* prototypes to the module
@@ -120,14 +120,14 @@
   //
   // Merge all of the DSNodes in the DSGraphs.
   //
-  GlobalECs = ECGraphs->getGlobalECs();
-  CombinedDSGraph = new DSGraph (GlobalECs, TD, &(ECGraphs->getGlobalsGraph()));
+  GlobalECs = Graphs->getGlobalECs();
+  CombinedDSGraph = new DSGraph (GlobalECs, TD, &(Graphs->getGlobalsGraph()));
   //CombinedDSGraph.cloneInto (getGlobalsGraph());
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
-    if (ECGraphs->hasDSGraph (*I))
-      CombinedDSGraph->cloneInto (ECGraphs->getDSGraph(*I));
+    if (Graphs->hasDSGraph (*I))
+      CombinedDSGraph->cloneInto (Graphs->getDSGraph(*I));
   }
-  CombinedDSGraph->cloneInto (ECGraphs->getGlobalsGraph());
+  CombinedDSGraph->cloneInto (Graphs->getGlobalsGraph());
   MergeNodesInDSGraph (*CombinedDSGraph);
 
   //
@@ -161,7 +161,7 @@
   //
   // Get the DSGraph for this function.
   //
-  DSGraph &ECG = ECGraphs->getDSGraph(F);
+  DSGraph &ECG = Graphs->getDSGraph(F);
 
   for (Function::iterator i = F.begin(), e = F.end(); i != e; ++i)
     for (BasicBlock::iterator ii = i->begin(), ee = i->end(); ii != ee; ++ii) {

Modified: poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp Sat Oct 11 11:52:04 2008
@@ -95,7 +95,7 @@
   /// data structures to reduce the size of pointers in the program.
   class PointerCompress : public ModulePass {
     PoolAllocate *PoolAlloc;
-    EquivClassGraphs *ECG;
+    CompleteBUDataStructures *ECG;
 
     /// ClonedFunctionMap - Every time we clone a function to compress its
     /// arguments, keep track of the clone and which arguments are compressed.
@@ -918,7 +918,7 @@
 
 
 void InstructionRewriter::visitCallInst(CallInst &CI) {
-  if (Function *F = CI.getCalledFunction())
+  if (Function *F = CI.getCalledFunction()) {
     // These functions are handled specially.
     if (F->getName() == "poolinit") {
       visitPoolInit(CI);
@@ -930,7 +930,8 @@
       visitPoolAlloc(CI);
       return;
     }
-  
+  }
+
   // Normal function call: check to see if this call produces or uses a pointer
   // into a compressed pool.  If so, we will need to transform the callee or use
   // a previously transformed version.
@@ -1136,7 +1137,7 @@
   AU.addRequired<PoolAllocatePassAllPools>();
 
   // Need information from DSA.
-  AU.addRequired<EquivClassGraphs>();
+  AU.addRequired<CompleteBUDataStructures>();
 }
 
 /// PoolIsCompressible - Return true if we can pointer compress this node.
@@ -1190,7 +1191,7 @@
 
     // Ignore potential pools that the pool allocation heuristic decided not to
     // pool allocated.
-    if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N]))
+    if (!isa<ConstantPointerNull>(FI->PoolDescriptors[N])) {
       if (PoolIsCompressible(N)) {
         Pools.insert(N);
         ++NumCompressed;
@@ -1198,6 +1199,7 @@
         DEBUG(std::cerr << "PCF: "; N->dump());
         ++NumNotCompressed;
       }
+    }
   }
 
   // If there are no compressed global pools, don't bother to look for them.
@@ -1482,7 +1484,7 @@
 
     // Ignore potential pools that the pool allocation heuristic decided not to
     // pool allocated.
-    if (!isa<ConstantPointerNull>(I->second))
+    if (!isa<ConstantPointerNull>(I->second)) {
       if (PoolIsCompressible(N)) {
         CompressedGlobalPools.insert(std::make_pair(N, 
                                              cast<GlobalValue>(I->second)));
@@ -1491,6 +1493,7 @@
         DEBUG(std::cerr << "PCF: "; N->dump());
         ++NumNotCompressed;
       }
+    }
   }
 }
 
@@ -1512,7 +1515,7 @@
 
 bool PointerCompress::runOnModule(Module &M) {
   PoolAlloc = &getAnalysis<PoolAllocatePassAllPools>();
-  ECG = &getAnalysis<EquivClassGraphs>();
+  ECG = &getAnalysis<CompleteBUDataStructures>();
   
   if (SmallIntCompress)
     MEMUINTTYPE = Type::Int16Ty;

Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Sat Oct 11 11:52:04 2008
@@ -85,35 +85,26 @@
   DisablePoolFreeOpt("poolalloc-force-all-poolfrees",
                      cl::desc("Do not try to elide poolfree's where possible"));
 
-  cl::opt<bool>
-  UseTDResolve("poolalloc-usetd-resolve",
-	       cl::desc("Use Top-Down Graph as a resolve source"));
 }
 
 void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.addRequiredTransitive<EquivClassGraphs>();
-  AU.addPreserved<EquivClassGraphs>();
+  AU.addRequiredTransitive<CompleteBUDataStructures>();
+  AU.addPreserved<CompleteBUDataStructures>();
 
   // Preserve the pool information across passes
   if (SAFECodeEnabled)
     AU.setPreservesAll();
 
   AU.addRequired<TargetData>();
-  if (UseTDResolve)
-    AU.addRequired<CallTargetFinder>();
 }
 
 bool PoolAllocate::runOnModule(Module &M) {
   if (M.begin() == M.end()) return false;
   CurModule = &M;
-  ECGraphs = &getAnalysis<EquivClassGraphs>();   // folded inlined CBU graphs
-  if (UseTDResolve)
-    CTF = &getAnalysis<CallTargetFinder>();
-  else
-    CTF = 0;
+  Graphs = &getAnalysis<CompleteBUDataStructures>();   // folded inlined CBU graphs
 
   CurHeuristic = Heuristic::create();
-  CurHeuristic->Initialize(M, ECGraphs->getGlobalsGraph(), *this);
+  CurHeuristic->Initialize(M, Graphs->getGlobalsGraph(), *this);
 
   // Add the pool* prototypes to the module
   AddPoolPrototypes(&M);
@@ -125,7 +116,7 @@
   // Loop over the functions in the original program finding the pool desc.
   // arguments necessary for each function that is indirectly callable.
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && ECGraphs->hasDSGraph(*I))
+    if (!I->isDeclaration() && Graphs->hasDSGraph(*I))
       FindFunctionPoolArgs(*I);
 
   std::map<Function*, Function*> FuncMap;
@@ -138,7 +129,7 @@
 {TIME_REGION(X, "MakeFunctionClone");
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
     if (!I->isDeclaration() && !ClonedFunctions.count(I) &&
-        ECGraphs->hasDSGraph(*I))
+        Graphs->hasDSGraph(*I))
       if (Function *Clone = MakeFunctionClone(*I)) {
         FuncMap[I] = Clone;
         ClonedFunctions.insert(Clone);
@@ -150,7 +141,7 @@
 {TIME_REGION(X, "ProcessFunctionBody");
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
     if (!I->isDeclaration() && !ClonedFunctions.count(I) &&
-        ECGraphs->hasDSGraph(*I)) {
+        Graphs->hasDSGraph(*I)) {
       std::map<Function*, Function*>::iterator FI = FuncMap.find(I);
       ProcessFunctionBody(*I, FI != FuncMap.end() ? *FI->second : *I);
     }
@@ -344,7 +335,7 @@
 /// arguments will have to be added for each function, build the FunctionInfo
 /// map and recording this info in the ArgNodes set.
 void PoolAllocate::FindFunctionPoolArgs(Function &F) {
-  DSGraph &G = ECGraphs->getDSGraph(F);
+  DSGraph &G = Graphs->getDSGraph(F);
 
   // Create a new entry for F.
   FuncInfo &FI =
@@ -367,7 +358,7 @@
 // necessary, and return it.  If not, just return null.
 //
 Function *PoolAllocate::MakeFunctionClone(Function &F) {
-  DSGraph &G = ECGraphs->getDSGraph(F);
+  DSGraph &G = Graphs->getDSGraph(F);
   if (G.node_begin() == G.node_end()) return 0;
     
   FuncInfo &FI = *getFuncInfo(F);
@@ -472,7 +463,7 @@
 //
 bool PoolAllocate::SetupGlobalPools(Module &M) {
   // Get the globals graph for the program.
-  DSGraph &GG = ECGraphs->getGlobalsGraph();
+  DSGraph &GG = Graphs->getGlobalsGraph();
 
   // Get all of the nodes reachable from globals.
   hash_set<const DSNode*> GlobalHeapNodes;
@@ -558,7 +549,7 @@
                        CurModule);
 
   // Update the global DSGraph to include this.
-  DSNode *GNode = ECGraphs->getGlobalsGraph().addObjectToGraph(GV);
+  DSNode *GNode = Graphs->getGlobalsGraph().addObjectToGraph(GV);
   GNode->setModifiedMarker()->setReadMarker();
 
   Function *MainFunc = CurModule->getFunction("main");
@@ -648,7 +639,7 @@
 // the specified function.
 //
 void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) {
-  DSGraph &G = ECGraphs->getDSGraph(F);
+  DSGraph &G = Graphs->getDSGraph(F);
 
   if (G.node_begin() == G.node_end()) return;  // Quick exit if nothing to do.
   
@@ -658,7 +649,7 @@
   // Calculate which DSNodes are reachable from globals.  If a node is reachable
   // from a global, we will create a global pool for it, so no argument passage
   // is required.
-  ECGraphs->getGlobalsGraph();
+  Graphs->getGlobalsGraph();
 
   // Map all node reachable from this global to the corresponding nodes in
   // the globals graph.
@@ -670,7 +661,7 @@
   for (DSGraph::node_iterator I = G.node_begin(), E = G.node_end(); I != E;++I){
     // We only need to make a pool if there is a heap object in it...
     DSNode *N = I;
-    if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArray())))
+    if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArray()))) {
       if (GlobalsGraphNodeMapping.count(N)) {
         // If it is a global pool, set up the pool descriptor appropriately.
         DSNode *GGN = GlobalsGraphNodeMapping[N].getNode();
@@ -682,6 +673,7 @@
         assert(!N->isGlobalNode() && "Should be in global mapping!");
         FI.NodesToPA.push_back(N);
       }
+    }
   }
 
   if (!FI.NodesToPA.empty()) {

Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=57375&r1=57374&r2=57375&view=diff

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Sat Oct 11 11:52:04 2008
@@ -556,7 +556,7 @@
 
   // If this function is one of the memory manipulating functions built into
   // libc, emulate it with pool calls as appropriate.
-  if (CF && CF->isDeclaration())
+  if (CF && CF->isDeclaration()) {
     if (CF->getName() == "calloc") {
       visitCallocCall(CS);
       return;
@@ -576,6 +576,7 @@
       std::cerr << "VALLOC USED BUT NOT HANDLED!\n";
       abort();
     }
+  }
 
   // We need to figure out which local pool descriptors correspond to the pool
   // descriptor arguments passed into the function call.  Calculate a mapping
@@ -583,7 +584,7 @@
   // between the graphs to figure out which pool descriptors need to be passed
   // in.  The roots of this mapping is found from arguments and return values.
   //
-  EquivClassGraphs& ECGraphs = PAInfo.getECGraphs();
+  DataStructures& Graphs = PAInfo.getGraphs();
   DSGraph::NodeMapTy NodeMapping;
   Instruction *NewCall;
   Value *NewCallee;
@@ -602,8 +603,8 @@
     NewCallee = CFI->Clone;
     ArgNodes = CFI->ArgNodes;
     
-    assert ((ECGraphs.hasDSGraph (*CF)) && "Function has no ECGraph!\n");
-    CalleeGraph = &ECGraphs.getDSGraph(*CF);
+    assert ((Graphs.hasDSGraph (*CF)) && "Function has no ECGraph!\n");
+    CalleeGraph = &Graphs.getDSGraph(*CF);
   } else {
     DEBUG(std::cerr << "  Handling indirect call: " << *TheCall);
     
@@ -614,28 +615,24 @@
     // in CS back to the original call instruction.)
     Instruction *OrigInst =
       cast<Instruction>(getOldValueIfAvailable(CS.getInstruction()));
-    CF = isa<CallInst>(OrigInst)?
-      ECGraphs.getSomeCalleeForCallSite(cast<CallInst>(OrigInst)) :
-      ECGraphs.getSomeCalleeForCallSite(cast<InvokeInst>(OrigInst));
-
-    if (!CF) 
-      for (EquivClassGraphs::callee_iterator I = ECGraphs.callee_begin(OrigInst), 
-             E = ECGraphs.callee_end(OrigInst); I != E; ++I) {
-        CF = *I;
-        break;
-      }
+
+    for (DataStructures::callee_iterator I = Graphs.callee_begin(OrigInst), 
+           E = Graphs.callee_end(OrigInst); I != E; ++I) {
+      CF = *I;
+      break;
+    }
 
     // If we didn't find the callee in the constructed call graph, try
     // checking in the DSNode itself.
     // This isn't ideal as it means that this call site didn't have inlining
     // happen.
     if (!CF) {
-      DSGraph* dg = &ECGraphs.getDSGraph(*OrigInst->getParent()->getParent());
+      DSGraph* dg = &Graphs.getDSGraph(*OrigInst->getParent()->getParent());
       DSNode* d = dg->getNodeForValue(OrigInst->getOperand(0)).getNode();
       const std::vector<const GlobalValue*> &g = d->getGlobalsList();
       for(std::vector<const GlobalValue*>::const_iterator ii = g.begin(), ee = g.end();
 	  !CF && ii != ee; ++ii) {
-        EquivalenceClasses< const GlobalValue *> & EC = ECGraphs.getGlobalECs();
+        EquivalenceClasses< const GlobalValue *> & EC = Graphs.getGlobalECs();
         for (EquivalenceClasses<const GlobalValue *>::member_iterator MI = EC.findLeader(*ii);
              MI != EC.member_end(); ++MI)   // Loop over members in this set.
           if ((CF = dyn_cast<Function>(*MI))) {
@@ -664,15 +661,15 @@
     }
 
     // Get the common graph for the set of functions this call may invoke.
-    CalleeGraph = &ECGraphs.getDSGraph(*CF);
+    CalleeGraph = &Graphs.getDSGraph(*CF);
     
 #ifndef NDEBUG
     // Verify that all potential callees at call site have the same DS graph.
-    EquivClassGraphs::callee_iterator I =
-      ECGraphs.callee_begin(OrigInst), E = ECGraphs.callee_end(OrigInst);
+    DataStructures::callee_iterator I =
+      Graphs.callee_begin(OrigInst), E = Graphs.callee_end(OrigInst);
     for (; I != E; ++I)
       if (!(*I)->isDeclaration())
-        assert(CalleeGraph == &ECGraphs.getDSGraph(**I) &&
+        assert(CalleeGraph == &Graphs.getDSGraph(**I) &&
                "Callees at call site do not have a common graph!");
 #endif    
 





More information about the llvm-commits mailing list