[llvm-commits] [poolalloc] r57319 - in /poolalloc/trunk/lib: DSA/BottomUpClosure.cpp DSA/CallTargets.cpp DSA/CompleteBottomUp.cpp DSA/DataStructure.cpp DSA/DataStructureStats.cpp DSA/EquivClassGraphs.cpp DSA/Local.cpp DSA/Printer.cpp DSA/StdLibPass.cpp DSA/Steensgaard.cpp DSA/TopDownClosure.cpp PoolAllocate/PoolAllocate.cpp PoolAllocate/TransformFunctionBody.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Wed Oct 8 23:24:33 PDT 2008


Author: alenhar2
Date: Thu Oct  9 01:24:31 2008
New Revision: 57319

URL: http://llvm.org/viewvc/llvm-project?rev=57319&view=rev
Log:
simplify and unify code.  EQ pass may be broken

Modified:
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/CallTargets.cpp
    poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp
    poolalloc/trunk/lib/DSA/DataStructureStats.cpp
    poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp
    poolalloc/trunk/lib/DSA/Local.cpp
    poolalloc/trunk/lib/DSA/Printer.cpp
    poolalloc/trunk/lib/DSA/StdLibPass.cpp
    poolalloc/trunk/lib/DSA/Steensgaard.cpp
    poolalloc/trunk/lib/DSA/TopDownClosure.cpp
    poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
    poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp

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

==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Thu Oct  9 01:24:31 2008
@@ -14,7 +14,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "bu_dsa"
+#define DEBUG_TYPE "dsa-bu"
 #include "dsa/DataStructure.h"
 #include "dsa/DSGraph.h"
 #include "llvm/Module.h"
@@ -40,17 +40,10 @@
 // program.
 //
 bool BUDataStructures::runOnModule(Module &M) {
-  StdLibDataStructures &LocalDSA = getAnalysis<StdLibDataStructures>();
-  setGraphSource(&LocalDSA);
-  setTargetData(LocalDSA.getTargetData());
-  setGraphClone(false);
-  GlobalECs = LocalDSA.getGlobalECs();
+  init(&getAnalysis<StdLibDataStructures>(), false, true);
 
-  GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
-  GlobalsGraph->setPrintAuxCalls();
-
-  std::vector<Function*> Stack;
-  hash_map<Function*, unsigned> ValMap;
+  std::vector<const Function*> Stack;
+  hash_map<const Function*, unsigned> ValMap;
   unsigned NextID = 1;
 
   Function *MainFunc = M.getFunction("main");
@@ -61,7 +54,7 @@
 
   // 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() && !DSInfo.count(I)) {
+    if (!I->isDeclaration() && !hasDSGraph(*I)) {
       if (MainFunc)
         DOUT << "*** BU: Function unreachable from main: "
              << I->getName() << "\n";
@@ -69,14 +62,8 @@
       CloneAuxIntoGlobal(getDSGraph(*I));
     }
 
-  //Be sure to get the all unresolved call sites
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && InlinedSomewhere.find(I) == InlinedSomewhere.end())
-      CloneAuxIntoGlobal(getDSGraph(*I));
-  InlinedSomewhere.clear();
-
   // If we computed any temporary indcallgraphs, free them now.
-  for (std::map<std::vector<Function*>,
+  for (std::map<std::vector<const Function*>,
          std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I =
          IndCallGraphMap.begin(), E = IndCallGraphMap.end(); I != E; ++I) {
     I->second.second.clear();  // Drop arg refs into the graph.
@@ -122,13 +109,13 @@
                                   DSGraph::IgnoreGlobals);
   }
 
-  NumCallEdges += ActualCallees.size();
+  NumCallEdges += callee_size();
 
   return false;
 }
 
 static inline bool nodeContainsExternalFunction(const DSNode *N) {
-  std::vector<Function*> Funcs;
+  std::vector<const Function*> Funcs;
   N->addFullFunctionList(Funcs);
   for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
     if (Funcs[i]->isDeclaration()) return true;
@@ -165,7 +152,7 @@
 }
 
 static void GetAllCallees(const DSCallSite &CS,
-                          std::vector<Function*> &Callees) {
+                          std::vector<const Function*> &Callees) {
   if (CS.isDirectCall()) {
     if (!CS.getCalleeFunc()->isDeclaration())
       Callees.push_back(CS.getCalleeFunc());
@@ -184,7 +171,7 @@
 }
 
 static void GetAnyCallees(const DSCallSite &CS,
-                          std::vector<Function*> &Callees) {
+                          std::vector<const Function*> &Callees) {
   if (CS.isDirectCall()) {
     if (!CS.getCalleeFunc()->isDeclaration())
       Callees.push_back(CS.getCalleeFunc());
@@ -204,7 +191,7 @@
 
 /// 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<Function*> &Callees) {
+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);
@@ -212,16 +199,16 @@
 
 /// GetAnyAuxCallees - Return a list containing all of the callees in
 /// the aux list for the specified graph in the Callees vector.
-static void GetAnyAuxCallees(DSGraph &G, std::vector<Function*> &Callees) {
+static void GetAnyAuxCallees(DSGraph &G, std::vector<const Function*> &Callees) {
   Callees.clear();
   for (DSGraph::afc_iterator I = G.afc_begin(), E = G.afc_end(); I != E; ++I)
     GetAnyCallees(*I, Callees);
 }
 
-unsigned BUDataStructures::calculateGraphs(Function *F,
-                                           std::vector<Function*> &Stack,
+unsigned BUDataStructures::calculateGraphs(const Function *F,
+                                           std::vector<const Function*> &Stack,
                                            unsigned &NextID,
-                                           hash_map<Function*, unsigned> &ValMap) {
+                                           hash_map<const Function*, unsigned> &ValMap) {
   assert(!ValMap.count(F) && "Shouldn't revisit functions!");
   unsigned Min = NextID++, MyID = Min;
   ValMap[F] = Min;
@@ -240,18 +227,18 @@
   DSGraph &Graph = getOrCreateGraph(F);
 
   // Find all callee functions.
-  std::vector<Function*> CalleeFunctions;
+  std::vector<const Function*> CalleeFunctions;
   GetAnyAuxCallees(Graph, CalleeFunctions);
   std::sort(CalleeFunctions.begin(), CalleeFunctions.end());
-  std::vector<Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
+  std::vector<const Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
   CalleeFunctions.resize(uid - CalleeFunctions.begin());
 
   // The edges out of the current node are the call site targets...
   for (unsigned i = 0, e = CalleeFunctions.size(); i != e; ++i) {
-    Function *Callee = CalleeFunctions[i];
+    const Function *Callee = CalleeFunctions[i];
     unsigned M;
     // Have we visited the destination function yet?
-    hash_map<Function*, unsigned>::iterator It = ValMap.find(Callee);
+    hash_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.
@@ -281,10 +268,10 @@
     unsigned oldsize = CalleeFunctions.size();
     GetAnyAuxCallees(Graph, CalleeFunctions);
     std::sort(CalleeFunctions.begin(), CalleeFunctions.end());
-    std::vector<Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
+    std::vector<const Function*>::iterator uid = std::unique(CalleeFunctions.begin(), CalleeFunctions.end());
     CalleeFunctions.resize(uid - CalleeFunctions.begin());
 
-    std::vector<Function*> ResolvedFuncs;
+    std::vector<const Function*> ResolvedFuncs;
     GetAllAuxCallees(Graph, ResolvedFuncs);
     if (ResolvedFuncs.size() || CalleeFunctions.size() > oldsize) {
       DOUT << "Recalculating " << F->getName() << " due to new knowledge\n";
@@ -293,6 +280,8 @@
     } else {
       ValMap[F] = ~0U;
     }
+    //propagate incomplete call nodes
+    inlineUnresolved(Graph);
     return MyID;
 
   } else {
@@ -301,7 +290,7 @@
     std::vector<DSGraph*> SCCGraphs;
 
     unsigned SCCSize = 1;
-    Function *NF = Stack.back();
+    const Function *NF = Stack.back();
     ValMap[NF] = ~0U;
     DSGraph &SCCGraph = getDSGraph(*NF);
 
@@ -319,7 +308,7 @@
       // Update the Function -> DSG map.
       for (DSGraph::retnodes_iterator I = NFG.retnodes_begin(),
              E = NFG.retnodes_end(); I != E; ++I)
-        DSInfo[I->first] = &SCCGraph;
+        setDSGraph(*I->first, &SCCGraph);
 
       SCCGraph.spliceFrom(NFG);
       delete &NFG;
@@ -346,6 +335,8 @@
          << "DONE with SCC #: " << MyID << "\n";
 
     // We never have to revisit "SCC" processed functions...
+    //propagate incomplete call nodes
+    inlineUnresolved(SCCGraph);
     return MyID;
   }
 
@@ -361,24 +352,6 @@
     GG.getAuxFunctionCalls().push_front(RC.cloneCallSite(*ii));
 }
 
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void BUDataStructures::releaseMyMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
-
 void BUDataStructures::calculateGraph(DSGraph &Graph) {
   // If this graph contains the main function, clone the globals graph into this
   // graph before we inline callees and other fun stuff.
@@ -416,8 +389,7 @@
   std::list<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
   TempFCs.swap(AuxCallsList);
 
-  bool Printed = false;
-  std::vector<Function*> CalledFuncs;
+  std::vector<const Function*> CalledFuncs;
   while (!TempFCs.empty()) {
     DSCallSite &CS = *TempFCs.begin();
 
@@ -447,9 +419,8 @@
     Instruction *TheCall = CS.getCallSite().getInstruction();
     
     if (CalledFuncs.size() == 1 && (isComplete || hasDSGraph(*CalledFuncs[0]))) {
-      Function *Callee = CalledFuncs[0];
-      ActualCallees.insert(std::make_pair(TheCall, Callee));
-      if (isComplete) InlinedSomewhere.insert(Callee);
+      const Function *Callee = CalledFuncs[0];
+      callee_add(TheCall, Callee);
 
       // Get the data structure graph for the called function.
       GI = &getDSGraph(*Callee);  // Graph to inline
@@ -463,20 +434,19 @@
                          (isComplete?0:DSGraph::DontCloneAuxCallNodes));
       ++NumBUInlines;
     } else {
-      if (!Printed)
-        DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
+      DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
       DEBUG(std::cerr << "  calls " << CalledFuncs.size()
             << " fns from site: " << CS.getCallSite().getInstruction()
             << "  " << *CS.getCallSite().getInstruction());
       DEBUG(std::cerr << "   Fns =");
       unsigned NumPrinted = 0;
       
-      for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
+      for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
              E = CalledFuncs.end(); I != E; ++I) {
         if (NumPrinted++ < 8) DOUT << " " << (*I)->getName();
         
         // Add the call edges to the call graph.
-        ActualCallees.insert(std::make_pair(TheCall, *I));
+        callee_add(TheCall, *I);
       }
       DOUT << "\n";
       
@@ -496,7 +466,7 @@
         IndCallGraphMap[CalledFuncs];
       
       if (IndCallGraph.first == 0) {
-        std::vector<Function*>::iterator I = CalledFuncs.begin(),
+        std::vector<const Function*>::iterator I = CalledFuncs.begin(),
           E = CalledFuncs.end();
         
         // Start with a copy of the first graph.
@@ -510,7 +480,6 @@
         
         // Merge all of the other callees into this graph.
         for (++I; I != E; ++I) {
-          if (isComplete) InlinedSomewhere.insert(*I);
           // If the graph already contains the nodes for the function, don't
           // bother merging it in again.
           if (!GI->containsFunction(*I)) {
@@ -576,66 +545,142 @@
   //Graph.writeGraphToFile(cerr, "bu_" + F.getName());
 }
 
-static const Function *getFnForValue(const Value *V) {
-  if (const Instruction *I = dyn_cast<Instruction>(V))
-    return I->getParent()->getParent();
-  else if (const Argument *A = dyn_cast<Argument>(V))
-    return A->getParent();
-  else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
-    return BB->getParent();
-  return 0;
-}
-
-/// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
-/// These correspond to the interfaces defined in the AliasAnalysis class.
-void BUDataStructures::deleteValue(Value *V) {
-  if (const Function *F = getFnForValue(V)) {  // Function local value?
-    // If this is a function local value, just delete it from the scalar map!
-    getDSGraph(*F).getScalarMap().eraseIfExists(V);
-    return;
-  }
-
-  if (Function *F = dyn_cast<Function>(V)) {
-    assert(getDSGraph(*F).getReturnNodes().size() == 1 &&
-           "cannot handle scc's");
-    delete DSInfo[F];
-    DSInfo.erase(F);
-    return;
-  }
-
-  assert(!isa<GlobalVariable>(V) && "Do not know how to delete GV's yet!");
-}
-
-void BUDataStructures::copyValue(Value *From, Value *To) {
-  if (From == To) return;
-  if (const Function *F = getFnForValue(From)) {  // Function local value?
-    // If this is a function local value, just delete it from the scalar map!
-    getDSGraph(*F).getScalarMap().copyScalarIfExists(From, To);
-    return;
-  }
-
-  if (Function *FromF = dyn_cast<Function>(From)) {
-    Function *ToF = cast<Function>(To);
-    assert(!DSInfo.count(ToF) && "New Function already exists!");
-    DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs);
-    DSInfo[ToF] = NG;
-    assert(NG->getReturnNodes().size() == 1 && "Cannot copy SCC's yet!");
-
-    // Change the Function* is the returnnodes map to the ToF.
-    DSNodeHandle Ret = NG->retnodes_begin()->second;
-    NG->getReturnNodes().clear();
-    NG->getReturnNodes()[ToF] = Ret;
-    return;
-  }
-
-  if (const Function *F = getFnForValue(To)) {
-    DSGraph &G = getDSGraph(*F);
-    G.getScalarMap().copyScalarIfExists(From, To);
-    return;
-  }
-
-  cerr << *From;
-  cerr << *To;
-  assert(0 && "Do not know how to copy this yet!");
-  abort();
+void BUDataStructures::inlineUnresolved(DSGraph &Graph) {
+  std::list<DSCallSite> TempFCs;
+  std::list<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
+  TempFCs.insert(TempFCs.begin(), AuxCallsList.begin(), AuxCallsList.end());
+
+  std::vector<const Function*> CalledFuncs;
+  while (!TempFCs.empty()) {
+    DSCallSite CS = *TempFCs.begin();
+    TempFCs.erase(TempFCs.begin());
+    CalledFuncs.clear();
+    GetAnyCallees(CS, CalledFuncs);
+    if (CalledFuncs.empty())
+      continue;
+
+    DSGraph *GI;
+    Instruction *TheCall = CS.getCallSite().getInstruction();  
+    if (CalledFuncs.size() == 1 && hasDSGraph(*CalledFuncs[0])) {
+      const Function *Callee = CalledFuncs[0];
+      callee_add(TheCall, Callee);
+
+      // Get the data structure graph for the called function.
+      GI = &getDSGraph(*Callee);  // Graph to inline
+      if (GI == &Graph) continue;
+      DOUT << "    Inlining graph for " << Callee->getName()
+           << "[" << GI->getGraphSize() << "+"
+           << GI->getAuxFunctionCalls().size() << "] into '"
+           << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+           << Graph.getAuxFunctionCalls().size() << "]\n";
+      Graph.mergeInGraph(CS, *Callee, *GI,
+                         DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
+      ++NumBUInlines;
+    } else {
+      DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
+      DEBUG(std::cerr << "  calls " << CalledFuncs.size()
+            << " fns from site: " << CS.getCallSite().getInstruction()
+            << "  " << *CS.getCallSite().getInstruction());
+      DEBUG(std::cerr << "   Fns =");
+      unsigned NumPrinted = 0;
+      
+      for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
+             E = CalledFuncs.end(); I != E; ++I) {
+        if (NumPrinted++ < 8) DOUT << " " << (*I)->getName();
+        
+        // Add the call edges to the call graph.
+        callee_add(TheCall, *I);
+      }
+      DOUT << "\n";
+      
+      for (unsigned x = 0; x < CalledFuncs.size(); )
+        if (!hasDSGraph(*CalledFuncs[x]))
+          CalledFuncs.erase(CalledFuncs.begin() + x);
+        else
+          ++x;
+      if (!CalledFuncs.size())
+        continue;
+
+      // 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 == &Graph) continue;
+
+      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);
+        GI->setGlobalsGraph(Graph.getGlobalsGraph());
+        std::vector<DSNodeHandle> &Args = IndCallGraph.second;
+        
+        // Get the argument nodes for the first callee.  The return value is
+        // the 0th index in the vector.
+        GI->getFunctionArgumentsForCall(*I, Args);
+        
+        // Merge all of the other callees into this graph.
+        for (++I; I != E; ++I) {
+          // If the graph already contains the nodes for the function, don't
+          // bother merging it in again.
+          if (!GI->containsFunction(*I)) {
+            GI->cloneInto(getDSGraph(**I));
+            ++NumBUInlines;
+          }
+          
+          std::vector<DSNodeHandle> NextArgs;
+          GI->getFunctionArgumentsForCall(*I, NextArgs);
+          unsigned i = 0, e = Args.size();
+          for (; i != e; ++i) {
+            if (i == NextArgs.size()) break;
+            Args[i].mergeWith(NextArgs[i]);
+          }
+          for (e = NextArgs.size(); i != e; ++i)
+            Args.push_back(NextArgs[i]);
+        }
+        
+        // Clean up the final graph!
+        GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
+      } else {
+        DOUT << "***\n*** RECYCLED GRAPH ***\n***\n";
+      }
+      
+      GI = IndCallGraph.first;
+      
+      // Merge the unified graph into this graph now.
+      DOUT << "    Inlining multi callee graph "
+           << "[" << GI->getGraphSize() << "+"
+           << GI->getAuxFunctionCalls().size() << "] into '"
+           << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+           << Graph.getAuxFunctionCalls().size() << "]\n";
+      
+      Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
+                         DSGraph::StripAllocaBit |
+                         DSGraph::DontCloneCallNodes);
+      ++NumBUInlines;
+    }
+  }
+
+  // Recompute the Incomplete markers
+  Graph.maskIncompleteMarkers();
+  Graph.markIncompleteNodes(DSGraph::MarkFormalArgs);
+
+  // Delete dead nodes.  Treat globals that are unreachable but that can
+  // reach live nodes as live.
+  Graph.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.
+  DSScalarMap &MainSM = Graph.getScalarMap();
+  ReachabilityCloner RC(*GlobalsGraph, Graph, DSGraph::StripAllocaBit);
+
+  // Clone everything reachable from globals in the function graph into the
+  // globals graph.
+  for (DSScalarMap::global_iterator I = MainSM.global_begin(),
+         E = MainSM.global_end(); I != E; ++I)
+    RC.getClonedNH(MainSM[*I]);
+
+  //Graph.writeGraphToFile(cerr, "bu_" + F.getName());
 }

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

==============================================================================
--- poolalloc/trunk/lib/DSA/CallTargets.cpp (original)
+++ poolalloc/trunk/lib/DSA/CallTargets.cpp Thu Oct  9 01:24:31 2008
@@ -78,7 +78,7 @@
 void CallTargetFinder::print(std::ostream &O, const Module *M) const
 {
   O << "[* = incomplete] CS: func list\n";
-  for (std::map<CallSite, std::vector<Function*> >::const_iterator ii =
+  for (std::map<CallSite, std::vector<const Function*> >::const_iterator ii =
        IndMap.begin(),
          ee = IndMap.end(); ii != ee; ++ii) {
     if (!ii->first.getCalledFunction()) { //only print indirect
@@ -90,7 +90,7 @@
           << cs.getInstruction()->getName() << " ";
       }
       O << ii->first.getInstruction() << ":";
-      for (std::vector<Function*>::const_iterator i = ii->second.begin(),
+      for (std::vector<const Function*>::const_iterator i = ii->second.begin(),
              e = ii->second.end(); i != e; ++i) {
         O << " " << (*i)->getName();
       }
@@ -109,11 +109,11 @@
   AU.addRequired<TDDataStructures>();
 }
 
-std::vector<Function*>::iterator CallTargetFinder::begin(CallSite cs) {
+std::vector<const Function*>::iterator CallTargetFinder::begin(CallSite cs) {
   return IndMap[cs].begin();
 }
 
-std::vector<Function*>::iterator CallTargetFinder::end(CallSite cs) {
+std::vector<const Function*>::iterator CallTargetFinder::end(CallSite cs) {
   return IndMap[cs].end();
 }
 

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

==============================================================================
--- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original)
+++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Thu Oct  9 01:24:31 2008
@@ -13,7 +13,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "cbudatastructure"
+#define DEBUG_TYPE "dsa-cbu"
 #include "dsa/DataStructure.h"
 #include "llvm/Module.h"
 #include "dsa/DSGraph.h"
@@ -25,7 +25,7 @@
 
 namespace {
   RegisterPass<CompleteBUDataStructures>
-  X("cbudatastructure", "'Complete' Bottom-up Data Structure Analysis");
+  X("dsa-cbu", "'Complete' Bottom-up Data Structure Analysis");
   STATISTIC (NumCBUInlines, "Number of graphs inlined");
 }
 
@@ -35,13 +35,7 @@
 // program.
 //
 bool CompleteBUDataStructures::runOnModule(Module &M) {
-  BUDataStructures &BU = getAnalysis<BUDataStructures>();
-  GlobalECs = BU.getGlobalECs();
-  GlobalsGraph = new DSGraph(BU.getGlobalsGraph(), GlobalECs);
-  GlobalsGraph->setPrintAuxCalls();
-
-  // Our call graph is the same as the BU data structures call graph
-  ActualCallees = BU.getActualCallees();
+  init(&getAnalysis<BUDataStructures>(), false, true);
 
   std::vector<DSGraph*> Stack;
   hash_map<DSGraph*, unsigned> ValMap;
@@ -50,18 +44,18 @@
   Function *MainFunc = M.getFunction("main");
   if (MainFunc) {
     if (!MainFunc->isDeclaration())
-      calculateSCCGraphs(getOrCreateGraph(*MainFunc), Stack, NextID, ValMap);
+      calculateSCCGraphs(getOrCreateGraph(MainFunc), Stack, NextID, ValMap);
   } else {
     DOUT << "CBU-DSA: No 'main' function found!\n";
   }
 
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && !DSInfo.count(I)) {
+    if (!I->isDeclaration() && !hasDSGraph(*I)) {
       if (MainFunc) {
         DOUT << "*** CBU: Function unreachable from main: "
              << I->getName() << "\n";
       }
-      calculateSCCGraphs(getOrCreateGraph(*I), Stack, NextID, ValMap);
+      calculateSCCGraphs(getOrCreateGraph(I), Stack, NextID, ValMap);
     }
 
   GlobalsGraph->removeTriviallyDeadNodes();
@@ -71,7 +65,7 @@
   // 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);
+    DSGraph &MainGraph = getOrCreateGraph(MainFunc);
     const DSGraph &GG = *MainGraph.getGlobalsGraph();
     ReachabilityCloner RC(MainGraph, GG,
                           DSGraph::DontCloneCallNodes |
@@ -91,27 +85,6 @@
   return false;
 }
 
-DSGraph &CompleteBUDataStructures::getOrCreateGraph(Function &F) {
-  // Has the graph already been created?
-  DSGraph *&Graph = DSInfo[&F];
-  if (Graph) return *Graph;
-
-  // Copy the BU graph...
-  Graph = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F), GlobalECs);
-  Graph->setGlobalsGraph(GlobalsGraph);
-  Graph->setPrintAuxCalls();
-
-  // Make sure to update the DSInfo map for all of the functions currently in
-  // this graph!
-  for (DSGraph::retnodes_iterator I = Graph->retnodes_begin();
-       I != Graph->retnodes_end(); ++I)
-    DSInfo[I->first] = Graph;
-
-  return *Graph;
-}
-
-
-
 unsigned CompleteBUDataStructures::calculateSCCGraphs(DSGraph &FG,
                                                   std::vector<DSGraph*> &Stack,
                                                   unsigned &NextID,
@@ -127,11 +100,10 @@
     Instruction *Call = CI->getCallSite().getInstruction();
 
     // Loop over all of the actually called functions...
-    callee_iterator I = callee_begin(Call), E = callee_end(Call);
-    for (; I != E && I->first == Call; ++I) {
-      assert(I->first == Call && "Bad callee construction!");
-      if (!I->second->isDeclaration()) {
-        DSGraph &Callee = getOrCreateGraph(*I->second);
+    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);
@@ -159,7 +131,7 @@
     // Update the DSInfo map and delete the old graph...
     for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
          I != NG->retnodes_end(); ++I)
-      DSInfo[I->first] = &FG;
+      setDSGraph(*I->first, &FG);
 
     // Remove NG from the ValMap since the pointer may get recycled.
     ValMap.erase(NG);
@@ -204,16 +176,15 @@
     // Inline direct calls as well as indirect calls because the direct
     // callee may have indirect callees and so may have changed.
     //
-    callee_iterator I = callee_begin(TheCall),E = callee_end(TheCall);
     unsigned TNum = 0, Num = 0;
-    DEBUG(Num = std::distance(I, E));
-    for (; I != E; ++I, ++TNum) {
-      assert(I->first == TheCall && "Bad callee construction!");
-      Function *CalleeFunc = I->second;
+    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);
+        DSGraph &GI = getOrCreateGraph(CalleeFunc);
         ++NumCBUInlines;
         G.mergeInGraph(CS, *CalleeFunc, GI,
                        DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes |

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

==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Thu Oct  9 01:24:31 2008
@@ -112,14 +112,14 @@
 // DSScalarMap Implementation
 //===----------------------------------------------------------------------===//
 
-DSNodeHandle &DSScalarMap::AddGlobal(GlobalValue *GV) {
+DSNodeHandle &DSScalarMap::AddGlobal(const GlobalValue *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
   // equated to another global in the program.
-  EquivalenceClasses<GlobalValue*>::iterator ECI = GlobalECs.findValue(GV);
+  EquivalenceClasses<const GlobalValue*>::iterator ECI = GlobalECs.findValue(GV);
   if (ECI != GlobalECs.end()) {
-    GlobalValue *Leader = *GlobalECs.findLeader(ECI);
+    const GlobalValue *Leader = *GlobalECs.findLeader(ECI);
     if (Leader != GV) {
       GV = Leader;
       iterator I = ValueMap.find(GV);
@@ -220,13 +220,13 @@
 // addGlobal - Add an entry for a global value to the Globals list.  This also
 // marks the node with the 'G' flag if it does not already have it.
 //
-void DSNode::addGlobal(GlobalValue *GV) {
+void DSNode::addGlobal(const GlobalValue *GV) {
   // First, check to make sure this is the leader if the global is in an
   // equivalence class.
   GV = getParentGraph()->getScalarMap().getLeaderForGlobal(GV);
 
   // Keep the list sorted.
-  std::vector<GlobalValue*>::iterator I =
+  std::vector<const GlobalValue*>::iterator I =
     std::lower_bound(Globals.begin(), Globals.end(), GV);
 
   if (I == Globals.end() || *I != GV) {
@@ -237,8 +237,8 @@
 
 // removeGlobal - Remove the specified global that is explicitly in the globals
 // list.
-void DSNode::removeGlobal(GlobalValue *GV) {
-  std::vector<GlobalValue*>::iterator I =
+void DSNode::removeGlobal(const GlobalValue *GV) {
+  std::vector<const GlobalValue*>::iterator I =
     std::lower_bound(Globals.begin(), Globals.end(), GV);
   assert(I != Globals.end() && *I == GV && "Global not in node!");
   Globals.erase(I);
@@ -316,13 +316,13 @@
 /// addFullGlobalsList - Compute the full set of global values that are
 /// represented by this node.  Unlike getGlobalsList(), this requires fair
 /// amount of work to compute, so don't treat this method call as free.
-void DSNode::addFullGlobalsList(std::vector<GlobalValue*> &List) const {
+void DSNode::addFullGlobalsList(std::vector<const GlobalValue*> &List) const {
   if (globals_begin() == globals_end()) return;
 
-  EquivalenceClasses<GlobalValue*> &EC = getParentGraph()->getGlobalECs();
+  EquivalenceClasses<const GlobalValue*> &EC = getParentGraph()->getGlobalECs();
 
   for (globals_iterator I = globals_begin(), E = globals_end(); I != E; ++I) {
-    EquivalenceClasses<GlobalValue*>::iterator ECI = EC.findValue(*I);
+    EquivalenceClasses<const GlobalValue*>::iterator ECI = EC.findValue(*I);
     if (ECI == EC.end())
       List.push_back(*I);
     else
@@ -332,20 +332,20 @@
 
 /// addFullFunctionList - Identical to addFullGlobalsList, but only return the
 /// functions in the full list.
-void DSNode::addFullFunctionList(std::vector<Function*> &List) const {
+void DSNode::addFullFunctionList(std::vector<const Function*> &List) const {
   if (globals_begin() == globals_end()) return;
 
-  EquivalenceClasses<GlobalValue*> &EC = getParentGraph()->getGlobalECs();
+  EquivalenceClasses<const GlobalValue*> &EC = getParentGraph()->getGlobalECs();
 
   for (globals_iterator I = globals_begin(), E = globals_end(); I != E; ++I) {
-    EquivalenceClasses<GlobalValue*>::iterator ECI = EC.findValue(*I);
+    EquivalenceClasses<const GlobalValue*>::iterator ECI = EC.findValue(*I);
     if (ECI == EC.end()) {
-      if (Function *F = dyn_cast<Function>(*I))
+      if (const Function *F = dyn_cast<Function>(*I))
         List.push_back(F);
     } else {
-      for (EquivalenceClasses<GlobalValue*>::member_iterator MI =
+      for (EquivalenceClasses<const GlobalValue*>::member_iterator MI =
              EC.member_begin(ECI), E = EC.member_end(); MI != E; ++MI)
-        if (Function *F = dyn_cast<Function>(*MI))
+        if (const Function *F = dyn_cast<Function>(*MI))
           List.push_back(F);
     }
   }
@@ -765,7 +765,7 @@
     return false;
   }
 
-  Module *M = 0;
+  const Module *M = 0;
   if (getParentGraph()->retnodes_begin() != getParentGraph()->retnodes_end())
     M = getParentGraph()->retnodes_begin()->first->getParent();
 
@@ -802,51 +802,13 @@
 }
 
 
-/// MergeSortedVectors - Efficiently merge a vector into another vector where
-/// duplicates are not allowed and both are sorted.  This assumes that 'T's are
-/// efficiently copyable and have sane comparison semantics.
-///
-static void MergeSortedVectors(std::vector<GlobalValue*> &Dest,
-                               const std::vector<GlobalValue*> &Src) {
-  // By far, the most common cases will be the simple ones.  In these cases,
-  // avoid having to allocate a temporary vector...
-  //
-  if (Src.empty()) {             // Nothing to merge in...
-    return;
-  } else if (Dest.empty()) {     // Just copy the result in...
-    Dest = Src;
-  } else if (Src.size() == 1) {  // Insert a single element...
-    const GlobalValue *V = Src[0];
-    std::vector<GlobalValue*>::iterator I =
-      std::lower_bound(Dest.begin(), Dest.end(), V);
-    if (I == Dest.end() || *I != Src[0])  // If not already contained...
-      Dest.insert(I, Src[0]);
-  } else if (Dest.size() == 1) {
-    GlobalValue *Tmp = Dest[0];           // Save value in temporary...
-    Dest = Src;                           // Copy over list...
-    std::vector<GlobalValue*>::iterator I =
-      std::lower_bound(Dest.begin(), Dest.end(), Tmp);
-    if (I == Dest.end() || *I != Tmp)     // If not already contained...
-      Dest.insert(I, Tmp);
-
-  } else {
-    // Make a copy to the side of Dest...
-    std::vector<GlobalValue*> Old(Dest);
-
-    // Make space for all of the type entries now...
-    Dest.resize(Dest.size()+Src.size());
-
-    // Merge the two sorted ranges together... into Dest.
-    std::merge(Old.begin(), Old.end(), Src.begin(), Src.end(), Dest.begin());
-
-    // Now erase any duplicate entries that may have accumulated into the
-    // vectors (because they were in both of the input sets)
-    Dest.erase(std::unique(Dest.begin(), Dest.end()), Dest.end());
-  }
-}
-
-void DSNode::mergeGlobals(const std::vector<GlobalValue*> &RHS) {
-  MergeSortedVectors(Globals, RHS);
+void DSNode::mergeGlobals(const std::vector<const GlobalValue*> &RHS) {
+  std::vector<const GlobalValue*> Temp;
+  std::back_insert_iterator< std::vector<const GlobalValue*> > back_it (Temp);
+  std::set_union(Globals.begin(), Globals.end(), 
+                 RHS.begin(), RHS.end(), 
+                 back_it);
+  Globals.swap(Temp);
 }
 
 // MergeNodes - Helper function for DSNode::mergeWith().
@@ -1002,7 +964,7 @@
     CurNodeH.getNode()->mergeGlobals(N->Globals);
 
     // Delete the globals from the old node...
-    std::vector<GlobalValue*>().swap(N->Globals);
+    N->Globals.clear();
   }
 }
 
@@ -1081,7 +1043,7 @@
     DSScalarMap &DestSM = Dest.getScalarMap();
     for (DSNode::globals_iterator I = SN->globals_begin(),E = SN->globals_end();
          I != E; ++I) {
-      GlobalValue *GV = *I;
+      const GlobalValue *GV = *I;
       DSScalarMap::iterator GI = DestSM.find(GV);
       if (GI != DestSM.end() && !GI->second.isNull()) {
         // We found one, use merge instead!
@@ -1137,7 +1099,7 @@
   // map with the correct offset.
   for (DSNode::globals_iterator I = SN->globals_begin(), E = SN->globals_end();
        I != E; ++I) {
-    GlobalValue *GV = *I;
+    const GlobalValue *GV = *I;
     const DSNodeHandle &SrcGNH = Src.getNodeForValue(GV);
     DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
     assert(DestGNH.getNode() == NH.getNode() &&"Global mapping inconsistent");
@@ -1226,7 +1188,7 @@
       // into.
       for (DSNode::globals_iterator I = SN->globals_begin(),
              E = SN->globals_end(); I != E; ++I) {
-        GlobalValue *GV = *I;
+        const GlobalValue *GV = *I;
         const DSNodeHandle &SrcGNH = Src.getNodeForValue(GV);
         DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
         assert(DestGNH.getNode()==NH.getNode() &&"Global mapping inconsistent");
@@ -1257,7 +1219,7 @@
     // in the scalar map for them!
     for (DSNode::globals_iterator I = SN->globals_begin(),
            E = SN->globals_end(); I != E; ++I) {
-      GlobalValue *GV = *I;
+      const GlobalValue *GV = *I;
       const DSNodeHandle &SrcGNH = Src.getNodeForValue(GV);
       DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
       assert(DestGNH.getNode()==NH.getNode() &&"Global mapping inconsistent");
@@ -1389,7 +1351,7 @@
 //===----------------------------------------------------------------------===//
 
 // Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
-Function &DSCallSite::getCaller() const {
+const Function &DSCallSite::getCaller() const {
   return *Site.getInstruction()->getParent()->getParent();
 }
 
@@ -1466,7 +1428,7 @@
 }
 
 
-DSGraph::DSGraph(DSGraph &G, EquivalenceClasses<GlobalValue*> &ECs,
+DSGraph::DSGraph(DSGraph &G, EquivalenceClasses<const GlobalValue*> &ECs,
                  unsigned CloneFlags)
   : GlobalsGraph(0), ScalarMap(ECs), TD(G.TD) {
   PrintAuxCalls = false;
@@ -1671,10 +1633,10 @@
 /// function arguments.  The vector is filled in with the return value (or
 /// null if it is not pointer compatible), followed by all of the
 /// pointer-compatible arguments.
-void DSGraph::getFunctionArgumentsForCall(Function *F,
+void DSGraph::getFunctionArgumentsForCall(const Function *F,
                                        std::vector<DSNodeHandle> &Args) const {
   Args.push_back(getReturnNodeFor(*F));
-  for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
+  for (Function::const_arg_iterator AI = F->arg_begin(), E = F->arg_end();
        AI != E; ++AI)
     if (isa<PointerType>(AI->getType())) {
       Args.push_back(getNodeForValue(AI));
@@ -1840,7 +1802,7 @@
   // through another global.  Compute the set of node that can reach globals and
   // aux call nodes to copy over, then do it.
   std::vector<const DSCallSite*> AuxCallToCopy;
-  std::vector<GlobalValue*> GlobalsToCopy;
+  std::vector<const GlobalValue*> GlobalsToCopy;
 
   // NodesReachCopiedNodes - Memoize results for efficiency.  Contains a
   // true/false value for every visited node that reaches a copied node without
@@ -1887,7 +1849,7 @@
 /// merges the nodes specified in the call site with the formal arguments in the
 /// graph.
 ///
-void DSGraph::mergeInGraph(const DSCallSite &CS, Function &F,
+void DSGraph::mergeInGraph(const DSCallSite &CS, const Function &F,
                            const DSGraph &Graph, unsigned CloneFlags) {
   // Set up argument bindings.
   std::vector<DSNodeHandle> Args;
@@ -1899,10 +1861,10 @@
 /// getCallSiteForArguments - Get the arguments and return value bindings for
 /// the specified function in the current graph.
 ///
-DSCallSite DSGraph::getCallSiteForArguments(Function &F) const {
+DSCallSite DSGraph::getCallSiteForArguments(const Function &F) const {
   std::vector<DSNodeHandle> Args;
 
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
+  for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
     if (isa<PointerType>(I->getType()))
       Args.push_back(getNodeForValue(I));
 
@@ -1982,8 +1944,8 @@
   if (Flags & DSGraph::MarkFormalArgs)
     for (ReturnNodesTy::iterator FI = ReturnNodes.begin(), E =ReturnNodes.end();
          FI != E; ++FI) {
-      Function &F = *FI->first;
-      for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
+      const Function &F = *FI->first;
+      for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
            I != E; ++I)
         if (isa<PointerType>(I->getType()))
           markIncompleteNode(getNodeForValue(I).getNode());
@@ -2013,7 +1975,7 @@
   // Mark all global nodes as incomplete.
   for (DSScalarMap::global_iterator I = ScalarMap.global_begin(),
          E = ScalarMap.global_end(); I != E; ++I)
-    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
       if (!GV->hasInitializer() ||    // Always mark external globals incomp.
           (!GV->isConstant() && (Flags & DSGraph::IgnoreGlobals) == 0))
         markIncompleteNode(ScalarMap[GV].getNode());
@@ -2029,7 +1991,7 @@
 }
 
 static inline bool nodeContainsExternalFunction(const DSNode *N) {
-  std::vector<Function*> Funcs;
+  std::vector<const Function*> Funcs;
   N->addFullFunctionList(Funcs);
   for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
     if (Funcs[i]->isDeclaration()) return true;
@@ -2246,7 +2208,7 @@
       // scalar map, so we check those now.
       //
       if (Node.getNumReferrers() == Node.getGlobalsList().size()) {
-        const std::vector<GlobalValue*> &Globals = Node.getGlobalsList();
+        const std::vector<const GlobalValue*> &Globals = Node.getGlobalsList();
 
         // Loop through and make sure all of the globals are referring directly
         // to the node...
@@ -2371,7 +2333,7 @@
 
   // Alive - a set that holds all nodes found to be reachable/alive.
   hash_set<const DSNode*> Alive;
-  std::vector<std::pair<Value*, DSNode*> > GlobalNodes;
+  std::vector<std::pair<const Value*, DSNode*> > GlobalNodes;
 
   // Copy and merge all information about globals to the GlobalsGraph if this is
   // not a final pass (where unreachable globals are removed).
@@ -2507,7 +2469,7 @@
   DEBUG(AssertGraphOK(); GlobalsGraph->AssertGraphOK());
 }
 
-void DSGraph::AssertNodeContainsGlobal(const DSNode *N, GlobalValue *GV) const {
+void DSGraph::AssertNodeContainsGlobal(const DSNode *N, const GlobalValue *GV) const {
   assert(std::find(N->globals_begin(),N->globals_end(), GV) !=
          N->globals_end() && "Global value not in node!");
 }
@@ -2543,7 +2505,7 @@
          E = ScalarMap.end(); I != E; ++I) {
     assert(!I->second.isNull() && "Null node in scalarmap!");
     AssertNodeInGraph(I->second.getNode());
-    if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
+    if (const GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
       assert(I->second.getNode()->isGlobalNode() &&
              "Global points to node, but node isn't global?");
       AssertNodeContainsGlobal(I->second.getNode(), GV);
@@ -2557,8 +2519,8 @@
   for (ReturnNodesTy::const_iterator RI = ReturnNodes.begin(),
          E = ReturnNodes.end();
        RI != E; ++RI) {
-    Function &F = *RI->first;
-    for (Function::arg_iterator AI = F.arg_begin(); AI != F.arg_end(); ++AI)
+    const Function &F = *RI->first;
+    for (Function::const_arg_iterator AI = F.arg_begin(); AI != F.arg_end(); ++AI)
       if (isa<PointerType>(AI->getType()))
         assert(!getNodeForValue(AI).isNull() &&
                "Pointer argument must be in the scalar map!");
@@ -2759,7 +2721,7 @@
   abort();
 }
 
-DSGraph& DataStructures::getOrCreateGraph(Function* F) {
+DSGraph& DataStructures::getOrCreateGraph(const Function* F) {
   assert(F && "No function");
   DSGraph *&G = DSInfo[F];
   if (!G) {
@@ -2789,11 +2751,11 @@
 void DataStructures::formGlobalECs() {
   // Grow the equivalence classes for the globals to include anything that we
   // now know to be aliased.
-  std::set<GlobalValue*> ECGlobals;
+  std::set<const GlobalValue*> ECGlobals;
   buildGlobalECs(ECGlobals);
   if (!ECGlobals.empty()) {
     DOUT << "Eliminating " << ECGlobals.size() << " EC Globals!\n";
-    for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
+    for (DSInfoTy::iterator I = DSInfo.begin(),
            E = DSInfo.end(); I != E; ++I)
       eliminateUsesOfECGlobals(*I->second, ECGlobals);
   }
@@ -2804,9 +2766,9 @@
 /// apart.  Instead of maintaining this information in all of the graphs
 /// throughout the entire program, store only a single global (the "leader") in
 /// the graphs, and build equivalence classes for the rest of the globals.
-void DataStructures::buildGlobalECs(std::set<GlobalValue*> &ECGlobals) {
+void DataStructures::buildGlobalECs(std::set<const GlobalValue*> &ECGlobals) {
   DSScalarMap &SM = GlobalsGraph->getScalarMap();
-  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+  EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
   for (DSGraph::node_iterator I = GlobalsGraph->node_begin(), 
          E = GlobalsGraph->node_end();
        I != E; ++I) {
@@ -2814,7 +2776,7 @@
 
     // First, build up the equivalence set for this block of globals.
     DSNode::globals_iterator i = I->globals_begin();
-    GlobalValue *First = *i++;
+    const GlobalValue *First = *i++;
     for( ; i != I->globals_end(); ++i) {
       GlobalECs.unionSets(First, *i);
       ECGlobals.insert(*i);
@@ -2837,14 +2799,14 @@
 /// really just equivalent to some other globals, remove the globals from the
 /// specified DSGraph (if present), and merge any nodes with their leader nodes.
 void DataStructures::eliminateUsesOfECGlobals(DSGraph &G,
-                                              const std::set<GlobalValue*> &ECGlobals) {
+                                              const std::set<const GlobalValue*> &ECGlobals) {
   DSScalarMap &SM = G.getScalarMap();
-  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+  EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
 
   bool MadeChange = false;
   for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
        GI != E; ) {
-    GlobalValue *GV = *GI++;
+    const GlobalValue *GV = *GI++;
     if (!ECGlobals.count(GV)) continue;
 
     const DSNodeHandle &GVNH = SM[GV];
@@ -2852,7 +2814,7 @@
 
     // Okay, this global is in some equivalence class.  Start by finding the
     // leader of the class.
-    GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
+    const GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
 
     // If the leader isn't already in the graph, insert it into the node
     // corresponding to GV.
@@ -2877,3 +2839,37 @@
 
   DEBUG(if(MadeChange) G.AssertGraphOK());
 }
+
+void DataStructures::init(DataStructures* D, bool clone, bool printAuxCalls) {
+  assert (!GraphSource && "Already init");
+  GraphSource = D;
+  Clone = clone;
+  TD = D->TD;
+  ActualCallees = D->ActualCallees;
+  GlobalECs = D->getGlobalECs();
+  GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs);
+  if (printAuxCalls) GlobalsGraph->setPrintAuxCalls();
+}
+
+void DataStructures::init(TargetData* T) {
+  assert (!TD && "Already init");
+  GraphSource = 0;
+  Clone = false;
+  TD = T;
+  GlobalsGraph = new DSGraph(GlobalECs, *T);
+}
+
+void DataStructures::releaseMemory() {
+  for (DSInfoTy::iterator I = DSInfo.begin(), E = DSInfo.end(); I != E; ++I) {
+    I->second->getReturnNodes().erase(I->first);
+    if (I->second->getReturnNodes().empty())
+      delete I->second;
+  }
+
+  // Empty map so next time memory is released, data structures are not
+  // re-deleted.
+  DSInfo.clear();
+  ActualCallees.clear();
+  delete GlobalsGraph;
+  GlobalsGraph = 0;
+}

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

==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructureStats.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructureStats.cpp Thu Oct  9 01:24:31 2008
@@ -26,7 +26,7 @@
 namespace {
   STATISTIC (TotalNumCallees, "Total number of callee functions at all indirect call sites");
   STATISTIC (NumIndirectCalls, "Total number of indirect call sites in the program");
-  STATISTIC (NumPoolNodes, "Number of allocation nodes that could be pool allocated");
+  //  STATISTIC (NumPoolNodes, "Number of allocation nodes that could be pool allocated");
 
   // Typed/Untyped memory accesses: If DSA can infer that the types the loads
   // and stores are accessing are correct (ie, the node has not been collapsed),
@@ -88,7 +88,7 @@
        I != E; ++I)
     if (isIndirectCallee(I->getCallSite().getCalledValue())) {
       // This is an indirect function call
-      std::vector<Function*> Callees;
+      std::vector<const Function*> Callees;
       I->getCalleeNode()->addFullFunctionList(Callees);
 
       if (Callees.size() > 0) {

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

==============================================================================
--- poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (original)
+++ poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp Thu Oct  9 01:24:31 2008
@@ -29,7 +29,7 @@
 using namespace llvm;
 
 namespace {
-  RegisterPass<EquivClassGraphs> X("eqdatastructure",
+  RegisterPass<EquivClassGraphs> X("dsa-eq",
                     "Equivalence-class Bottom-up Data Structure Analysis");
   STATISTIC (NumEquivBUInlines,
                                 "Number of graphs inlined");
@@ -39,7 +39,7 @@
 
 char EquivClassGraphs::ID = 0;
 
-EquivClassGraphs::EquivClassGraphs() : ModulePass((intptr_t)&ID) {}
+EquivClassGraphs::EquivClassGraphs() : DataStructures((intptr_t)&ID) {}
 
 #ifndef NDEBUG
 template<typename GT>
@@ -58,12 +58,12 @@
 
 // getSomeCalleeForCallSite - Return any one callee function at a call site.
 //
-Function *EquivClassGraphs::getSomeCalleeForCallSite(const CallSite &CS) const{
+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*, Function *>::const_iterator I =
+  std::map<DSNode*, const Function *>::const_iterator I =
     OneCalledFunction.find(calleeNode);
   return (I == OneCalledFunction.end())? NULL : I->second;
 }
@@ -72,14 +72,7 @@
 // in the program.
 //
 bool EquivClassGraphs::runOnModule(Module &M) {
-  CBU = &getAnalysis<CompleteBUDataStructures>();
-  GlobalECs = CBU->getGlobalECs();
-  DEBUG(CheckAllGraphs(&M, *CBU));
-
-  GlobalsGraph = new DSGraph(CBU->getGlobalsGraph(), GlobalECs);
-  GlobalsGraph->setPrintAuxCalls();
-
-  ActualCallees = CBU->getActualCallees();
+  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.
@@ -90,16 +83,16 @@
   std::map<DSGraph*, unsigned> ValMap;
   unsigned NextID = 1;
 
-  Function *MainFunc = M.getFunction("main");
+  const Function *MainFunc = M.getFunction("main");
   if (MainFunc && !MainFunc->isDeclaration()) {
-    processSCC(getOrCreateGraph(*MainFunc), Stack, NextID, ValMap);
+    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);
+      processSCC(getOrCreateGraph(I), Stack, NextID, ValMap);
 
   DEBUG(CheckAllGraphs(&M, *this));
 
@@ -110,7 +103,7 @@
   // 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);
+    DSGraph &MainGraph = getOrCreateGraph(MainFunc);
     const DSGraph &GG = *MainGraph.getGlobalsGraph();
     ReachabilityCloner RC(MainGraph, GG,
                           DSGraph::DontCloneCallNodes |
@@ -140,7 +133,7 @@
            UI != E; ++UI)
         // This only happens to direct uses by instructions.
         if (Instruction *User = dyn_cast<Instruction>(*UI)) {
-          DSGraph &DSG = getOrCreateGraph(*User->getParent()->getParent());
+          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
@@ -159,46 +152,26 @@
 // unify the N functions together in the FuncECs set.
 //
 void EquivClassGraphs::buildIndirectFunctionSets(Module &M) {
-  const ActualCalleesTy& AC = CBU->getActualCallees();
-
   // 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.
-  Instruction *LastInst = 0;
-  Function *FirstFunc = 0;
-  for (ActualCalleesTy::const_iterator I=AC.begin(), E=AC.end(); I != E; ++I) {
-    if (I->second->isDeclaration())
-      continue;                         // Ignore functions we cannot modify
-
-    CallSite CS = CallSite::get(I->first);
-
-    if (CS.getCalledFunction()) {       // Direct call:
-      FuncECs.insert(I->second);        // -- Make sure function has equiv class
-      FirstFunc = I->second;            // -- First callee at this site
-    } else {                            // Else indirect call
-      // DOUT << "CALLEE: " << I->second->getName()
-      //      << " from : " << I->first;
-      if (I->first != LastInst) {
-        // This is the first callee from this call site.
-        LastInst = I->first;
-        FirstFunc = I->second;
-        // Instead of storing the lastInst For Indirection call Sites we store
-        // the DSNode for the function ptr arguemnt
-        Function *thisFunc = LastInst->getParent()->getParent();
-        DSGraph &TFG = CBU->getDSGraph(*thisFunc);
-        DSNode *calleeNode = TFG.getNodeForValue(CS.getCalledValue()).getNode();
-        OneCalledFunction[calleeNode] = FirstFunc;
-        FuncECs.insert(I->second);
+  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 {
-        // This is not the first possible callee from a particular call site.
-        // Union the callee in with the other functions.
-        FuncECs.unionSets(FirstFunc, I->second);
-#ifndef NDEBUG
-        Function *thisFunc = LastInst->getParent()->getParent();
-        DSGraph &TFG = CBU->getDSGraph(*thisFunc);
-        DSNode *calleeNode = TFG.getNodeForValue(CS.getCalledValue()).getNode();
-        assert(OneCalledFunction.count(calleeNode) > 0 && "Missed a call?");
-#endif
+        FuncECs.unionSets(*csi, F);
       }
     }
 
@@ -207,29 +180,29 @@
     // 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 = CBU->getDSGraph(*I->second);
+    DSGraph& funcDSGraph = getOrCreateGraph(F);
     for (DSGraph::retnodes_iterator RI = funcDSGraph.retnodes_begin(),
            RE = funcDSGraph.retnodes_end(); RI != RE; ++RI)
-      FuncECs.unionSets(FirstFunc, RI->first);
+      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<Function*>::iterator EQSI = FuncECs.begin(), E =
+  for (EquivalenceClasses<const Function*>::iterator EQSI = FuncECs.begin(), E =
          FuncECs.end(); EQSI != E; ++EQSI) {
     if (!EQSI->isLeader()) continue;
 
-    EquivalenceClasses<Function*>::member_iterator SI =
+    EquivalenceClasses<const Function*>::member_iterator SI =
       FuncECs.member_begin(EQSI);
     assert(SI != FuncECs.member_end() && "Empty equiv set??");
-    EquivalenceClasses<Function*>::member_iterator SN = SI;
+    EquivalenceClasses<const Function*>::member_iterator SN = SI;
     ++SN;
     if (SN == FuncECs.member_end())
       continue;   // Single function equivalence set, no merging to do.
 
-    Function* LF = *SI;
+    const Function* LF = *SI;
 
 #ifndef NDEBUG
     DOUT <<"  Equivalence set for leader " << LF->getName() <<" = ";
@@ -241,12 +214,12 @@
     // 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);
+    DSGraph &MergedG = getOrCreateGraph(LF);
 
     // Record the argument nodes for use in merging later below.
     std::vector<DSNodeHandle> ArgNodes;
 
-    for (Function::arg_iterator AI = LF->arg_begin(), E = LF->arg_end();
+    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));
@@ -255,18 +228,16 @@
     // 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(&CBU->getDSGraph(*LF));
+    GraphsMerged.insert(&getOrCreateGraph(LF));
 
     for (++SI; SI != FuncECs.member_end(); ++SI) {
-      Function *F = *SI;
-      DSGraph &CBUGraph = CBU->getDSGraph(*F);
+      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) {
-          assert(DSInfo[I->first] == 0 && "Graph already exists for Fn!");
-          DSInfo[I->first] = &MergedG;
-        }
+               E = CBUGraph.retnodes_end(); I != E; ++I)
+          setDSGraph(*I->first, &MergedG);
 
         // Clone this member of the equivalence class into MergedG.
         MergedG.cloneInto(CBUGraph);
@@ -277,7 +248,7 @@
 
       // 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::arg_iterator AI2 = F->arg_begin(), AI2end = F->arg_end();
+      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()))
@@ -293,31 +264,6 @@
 }
 
 
-DSGraph &EquivClassGraphs::getOrCreateGraph(Function &F) {
-  // Has the graph already been created?
-  DSGraph *&Graph = DSInfo[&F];
-  if (Graph) return *Graph;
-
-  DSGraph &CBUGraph = CBU->getDSGraph(F);
-
-  // Copy the CBU graph...
-  Graph = new DSGraph(CBUGraph, GlobalECs);   // updates the map via reference
-  Graph->setGlobalsGraph(&getGlobalsGraph());
-  Graph->setPrintAuxCalls();
-
-  // Make sure to update the DSInfo map for all functions in the graph!
-  for (DSGraph::retnodes_iterator I = Graph->retnodes_begin();
-       I != Graph->retnodes_end(); ++I)
-    if (I->first != &F) {
-      DSGraph *&FG = DSInfo[I->first];
-      assert(FG == 0 && "Merging function in SCC twice?");
-      FG = Graph;
-    }
-
-  return *Graph;
-}
-
-
 unsigned EquivClassGraphs::
 processSCC(DSGraph &FG, std::vector<DSGraph*> &Stack, unsigned &NextID,
            std::map<DSGraph*, unsigned> &ValMap) {
@@ -339,9 +285,9 @@
     // Loop over all of the actually called functions...
     for (callee_iterator I = callee_begin(Call), E = callee_end(Call);
          I != E; ++I)
-      if (!I->second->isDeclaration()) {
+      if (!(*I)->isDeclaration()) {
         // Process the callee as necessary.
-        unsigned M = processSCC(getOrCreateGraph(*I->second),
+        unsigned M = processSCC(getOrCreateGraph(*I),
                                 Stack, NextID, ValMap);
         if (M < Min) Min = M;
       }
@@ -364,7 +310,7 @@
     // Update the DSInfo map and delete the old graph...
     for (DSGraph::retnodes_iterator I = NG->retnodes_begin();
          I != NG->retnodes_end(); ++I)
-      DSInfo[I->first] = &FG;
+      setDSGraph(*I->first, &FG);
 
     // Remove NG from the ValMap since the pointer may get recycled.
     ValMap.erase(NG);
@@ -416,19 +362,19 @@
 
     // 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->second->isDeclaration())
+      if (!(*I)->isDeclaration())
         break;
 
     // Now check if the graph has changed and if so, clone and inline it.
     if (I != E) {
-      Function *CalleeFunc = I->second;
+      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);
+      CalleeGraph = &getOrCreateGraph(CalleeFunc);
       if (CalleeGraph != &G) {
         ++NumFoldGraphInlines;
         G.mergeInGraph(CS, *CalleeFunc, *CalleeGraph,
@@ -452,8 +398,8 @@
     // same graph as the one inlined above.
     if (CalleeGraph)
       for (++I, ++TNum; I != E; ++I, ++TNum)
-        if (!I->second->isDeclaration())
-          assert(CalleeGraph == &getOrCreateGraph(*I->second) &&
+        if (!(*I)->isDeclaration())
+          assert(CalleeGraph == &getOrCreateGraph(*I) &&
                  "Callees at a call site have different graphs?");
 #endif
   }

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

==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Thu Oct  9 01:24:31 2008
@@ -155,7 +155,7 @@
         
         for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
              I != g.getScalarMap().global_end(); ++I)
-          if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+          if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
             if (!GV->isDeclaration() && GV->isConstant())
               RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
       }
@@ -765,10 +765,9 @@
 char LocalDataStructures::ID;
 
 bool LocalDataStructures::runOnModule(Module &M) {
-  setTargetData(getAnalysis<TargetData>());
+  init(&getAnalysis<TargetData>());
 
   // First step, build the globals graph.
-  GlobalsGraph = new DSGraph(GlobalECs, getTargetData());
   {
     GraphBuilder GGB(*GlobalsGraph);
 
@@ -788,7 +787,7 @@
     if (!I->isDeclaration()) {
       DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
       GraphBuilder GGB(*I, *G);
-      DSInfo.insert(std::make_pair(I, G));
+      setDSGraph(*I, G);
     }
 
   GlobalsGraph->removeTriviallyDeadNodes();
@@ -803,21 +802,3 @@
   return false;
 }
 
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void LocalDataStructures::releaseMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
-

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

==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Thu Oct  9 01:24:31 2008
@@ -43,7 +43,7 @@
 
 static std::string getCaption(const DSNode *N, const DSGraph *G) {
   std::stringstream OS;
-  Module *M = 0;
+  const Module *M = 0;
 
   if (!G) G = N->getParentGraph();
 
@@ -83,7 +83,7 @@
     OS << "\n";
   }
 
-  EquivalenceClasses<GlobalValue*> *GlobalECs = 0;
+  EquivalenceClasses<const GlobalValue*> *GlobalECs = 0;
   if (G) GlobalECs = &G->getGlobalECs();
 
   for (unsigned i = 0, e = N->getGlobalsList().size(); i != e; ++i) {
@@ -91,7 +91,7 @@
 
     // Figure out how many globals are equivalent to this one.
     if (GlobalECs) {
-      EquivalenceClasses<GlobalValue*>::iterator I =
+      EquivalenceClasses<const GlobalValue*>::iterator I =
         GlobalECs->findValue(N->getGlobalsList()[i]);
       if (I != GlobalECs->end()) {
         unsigned NumMembers =
@@ -147,7 +147,7 @@
   ///
   static void addCustomGraphFeatures(const DSGraph *G,
                                      GraphWriter<const DSGraph*> &GW) {
-    Module *CurMod = 0;
+    const Module *CurMod = 0;
     if (G->retnodes_begin() != G->retnodes_end())
       CurMod = G->retnodes_begin()->first->getParent();
     else {
@@ -286,7 +286,7 @@
       bool IsDuplicateGraph = false;
 
       if (I->getName() == "main" || !OnlyPrintMain) {
-        Function *SCCFn = Gr.retnodes_begin()->first;
+        const Function *SCCFn = Gr.retnodes_begin()->first;
         if (&*I == SCCFn) {
           Gr.writeGraphToFile(O, Prefix+I->getName());
         } else {
@@ -296,7 +296,7 @@
             << "\n";
         }
       } else {
-        Function *SCCFn = Gr.retnodes_begin()->first;
+        const Function *SCCFn = Gr.retnodes_begin()->first;
         if (&*I == SCCFn) {
           O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
             << Gr.getGraphSize() << "+" << NumCalls << "]\n";

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

==============================================================================
--- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original)
+++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Oct  9 01:24:31 2008
@@ -31,111 +31,175 @@
 
 char StdLibDataStructures::ID;
 
+#define numOps 10
+
 struct libAction {
-  bool ret_read, ret_write, ret_heap;
-  bool args_read, args_write, args_heap;
+  bool read[numOps];
+  bool write[numOps];
+  bool heap[numOps];
   bool mergeAllArgs;
   bool mergeWithRet;
   bool collapse;
 };
 
+#define NRET_NARGS  {0,0,0,0,0,0,0,0,0,0}
+#define YRET_NARGS  {1,0,0,0,0,0,0,0,0,0}
+#define NRET_YARGS  {0,1,1,1,1,1,1,1,1,1}
+#define YRET_YARGS  {1,1,1,1,1,1,1,1,1,1}
+#define NRET_NYARGS {0,0,1,1,1,1,1,1,1,1}
+#define YRET_NYARGS {1,0,1,1,1,1,1,1,1,1}
+#define NRET_YNARGS {0,1,0,0,0,0,0,0,0,0}
+#define YRET_YNARGS {1,1,0,0,0,0,0,0,0,0}
+
+
 const struct {
   const char* name;
   libAction action;
 } recFuncs[] = {
-  {"calloc",   {false,  true,  true, false, false, false, false, false, false}},
-  {"malloc",   {false,  true,  true, false, false, false, false, false, false}},
-  {"valloc",   {false,  true,  true, false, false, false, false, false, false}},
-  {"memalign", {false,  true,  true, false, false, false, false, false, false}},
-  {"strdup",   {false,  true,  true, false, false, false, false, false,  true}},
-  {"wcsdup",   {false,  true,  true, false, false, false, false, false,  true}},
-  {"free",     {false, false, false, false,  true,  true, false, false, false}},
-  {"realloc",  {false,  true,  true, false,  true,  true, false,  true,  true}},
-  {"atoi",     {false, false, false,  true, false, false, false, false, false}},
-  {"atof",     {false, false, false,  true, false, false, false, false, false}},
-  {"atol",     {false, false, false,  true, false, false, false, false, false}},
-  {"atoll",    {false, false, false,  true, false, false, false, false, false}},
-  {"remove",   {false, false, false,  true, false, false, false, false, false}},
-  {"unlink",   {false, false, false,  true, false, false, false, false, false}},
-  {"rename",   {false, false, false,  true, false, false, false, false, false}},
-  {"memcmp",   {false, false, false,  true, false, false, false, false, false}},
-  {"strcmp",   {false, false, false,  true, false, false, false, false, false}},
-  {"strncmp",  {false, false, false,  true, false, false, false, false, false}},
-  {"execl",    {false, false, false,  true, false, false, false, false, false}},
-  {"execlp",   {false, false, false,  true, false, false, false, false, false}},
-  {"execle",   {false, false, false,  true, false, false, false, false, false}},
-  {"execv",    {false, false, false,  true, false, false, false, false, false}},
-  {"execvp",   {false, false, false,  true, false, false, false, false, false}},
-  {"chmod",    {false, false, false,  true, false, false, false, false, false}},
-  {"puts",     {false, false, false,  true, false, false, false, false, false}},
-  {"write",    {false, false, false,  true, false, false, false, false, false}},
-  {"open",     {false, false, false,  true, false, false, false, false, false}},
-  {"create",   {false, false, false,  true, false, false, false, false, false}},
-  {"truncate", {false, false, false,  true, false, false, false, false, false}},
-  {"chdir",    {false, false, false,  true, false, false, false, false, false}},
-  {"mkdir",    {false, false, false,  true, false, false, false, false, false}},
-  {"rmdir",    {false, false, false,  true, false, false, false, false, false}},
-  {"strlen",   {false, false, false,  true, false, false, false, false, false}},
-  {"read",     {false, false, false, false,  true, false, false, false, false}},
-  {"pipe",     {false, false, false, false,  true, false, false, false, false}},
-  {"wait",     {false, false, false, false,  true, false, false, false, false}},
-  {"time",     {false, false, false, false,  true, false, false, false, false}},
-  {"getrusage",{false, false, false, false,  true, false, false, false, false}},
-  {"memchr",   { true, false, false,  true, false, false, false,  true,  true}},
-  {"memrchr",  { true, false, false,  true, false, false, false,  true,  true}},
-  {"rawmemchr",{ true, false, false,  true, false, false, false,  true,  true}},
-  {"memmove",  {false,  true, false,  true,  true, false,  true,  true,  true}},
-  {"bcopy",    {false, false, false,  true,  true, false,  true, false,  true}},
-  {"strcpy",   {false,  true, false,  true,  true, false,  true,  true,  true}},
-  {"strncpy",  {false,  true, false,  true,  true, false,  true,  true,  true}},
-  {"memccpy",  {false,  true, false,  true,  true, false,  true,  true,  true}},
-  {"wcscpy",   {false,  true, false,  true,  true, false,  true,  true,  true}},
-  {"wcsncpy",  {false,  true, false,  true,  true, false,  true,  true,  true}},
-  {"wmemccpy", {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"stat",       {NRET_YNARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
+  {"fstat",      {NRET_YNARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
+  {"lstat",      {NRET_YNARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
+
+  //printf not strictly true, %n could cause a write
+  {"printf",     {NRET_YARGS,  NRET_NARGS,  NRET_NARGS, false, false, false}},
+  {"fprintf",    {NRET_YARGS,  NRET_YNARGS, NRET_NARGS, false, false, false}},
+  {"sprintf",    {NRET_YARGS,  NRET_YNARGS, NRET_NARGS, false, false, false}},
+  {"snprintf",   {NRET_YARGS,  NRET_YNARGS, NRET_NARGS, false, false, false}},
+
+  {"calloc",     {NRET_NARGS, YRET_NARGS, YRET_NARGS,  false, false, false}},
+  {"malloc",     {NRET_NARGS, YRET_NARGS, YRET_NARGS,  false, false, false}},
+  {"valloc",     {NRET_NARGS, YRET_NARGS, YRET_NARGS,  false, false, false}},
+  {"memalign",   {NRET_NARGS, YRET_NARGS, YRET_NARGS,  false, false, false}},
+  {"realloc",    {NRET_NARGS, YRET_NARGS, YRET_YNARGS, false,  true,  true}},
+  {"free",       {NRET_NARGS, NRET_NARGS, NRET_YNARGS,  false, false, false}},
+  
+  {"strdup",     {NRET_YARGS, YRET_NARGS, YRET_NARGS,  false, true, false}},
+  {"wcsdup",     {NRET_YARGS, YRET_NARGS, YRET_NARGS,  false, true, false}},
+
+  {"atoi",       {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"atof",       {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"atol",       {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"atoll",      {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"atoq",       {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+
+  {"strcmp",     {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"wcscmp",     {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"strncmp",    {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"wcsncmp",    {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"strcasecmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"wcscasecmp", {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"strncasecmp",{NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"wcsncasecmp",{NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"strlen",     {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+  {"wcslen",     {NRET_YARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
+
+  {"memchr",     {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"wmemchr",    {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"memrchr",    {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"strchr",     {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"wcschr",     {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"strrchr",    {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"wcsrchr",    {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+  {"strchrhul",  {YRET_YARGS, NRET_NARGS, NRET_NARGS, false, true, true}},
+
+
+#if 0
+  {"remove",     {false, false, false,  true, false, false, false, false, false}},
+  {"unlink",     {false, false, false,  true, false, false, false, false, false}},
+  {"rename",     {false, false, false,  true, false, false, false, false, false}},
+  {"memcmp",     {false, false, false,  true, false, false, false, false, false}},
+  {"execl",      {false, false, false,  true, false, false, false, false, false}},
+  {"execlp",     {false, false, false,  true, false, false, false, false, false}},
+  {"execle",     {false, false, false,  true, false, false, false, false, false}},
+  {"execv",      {false, false, false,  true, false, false, false, false, false}},
+  {"execvp",     {false, false, false,  true, false, false, false, false, false}},
+  {"chmod",      {false, false, false,  true, false, false, false, false, false}},
+  {"puts",       {false, false, false,  true, false, false, false, false, false}},
+  {"write",      {false, false, false,  true, false, false, false, false, false}},
+  {"open",       {false, false, false,  true, false, false, false, false, false}},
+  {"create",     {false, false, false,  true, false, false, false, false, false}},
+  {"truncate",   {false, false, false,  true, false, false, false, false, false}},
+  {"chdir",      {false, false, false,  true, false, false, false, false, false}},
+  {"mkdir",      {false, false, false,  true, false, false, false, false, false}},
+  {"rmdir",      {false, false, false,  true, false, false, false, false, false}},
+  {"read",       {false, false, false, false,  true, false, false, false, false}},
+  {"pipe",       {false, false, false, false,  true, false, false, false, false}},
+  {"wait",       {false, false, false, false,  true, false, false, false, false}},
+  {"time",       {false, false, false, false,  true, false, false, false, false}},
+  {"getrusage",  {false, false, false, false,  true, false, false, false, false}},
+  {"memmove",    {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"bcopy",      {false, false, false,  true,  true, false,  true, false,  true}},
+  {"strcpy",     {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"strncpy",    {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"memccpy",    {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"wcscpy",     {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"wcsncpy",    {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"wmemccpy",   {false,  true, false,  true,  true, false,  true,  true,  true}},
+  {"fclose",     {false, false, false,  true,  true, false, false, false, false}},
+  {"fopen",      {false,  true,  true,  true, false, false, false, false, false}},
+  {"getcwd",     { true,  true,  true,  true,  true,  true, false,  true,  true}},
+#endif
+  //C++ functions, as mangled on linux gcc 4.2
+  //operator new(unsigned long)
+  {"_Znwm",      {NRET_NARGS, YRET_NARGS, YRET_NARGS,  false, false, false}},
+  //operator new[](unsigned long)
+  {"_Znam",      {NRET_NARGS, YRET_NARGS, YRET_NARGS,  false, false, false}},
+  //operator delete(void*)
+  {"_ZdlPv",     {NRET_NARGS, NRET_NARGS, NRET_YNARGS,  false, false, false}},
+  //operator delete[](void*)
+  {"_ZdaPv",     {NRET_NARGS, NRET_NARGS, NRET_YNARGS,  false, false, false}},
+
 };
 
-bool StdLibDataStructures::runOnModule(Module &M) {
-  LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
-  setGraphSource(&LocalDSA);
-  setTargetData(LocalDSA.getTargetData());
-  setGraphClone(false);
-  GlobalECs = LocalDSA.getGlobalECs();
+void StdLibDataStructures::eraseCallsTo(Function* F) {
+  for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+       ii != ee; ++ii)
+    if (CallInst* CI = dyn_cast<CallInst>(ii))
+      if (CI->getOperand(0) == F) {
+        DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
+        //delete the call
+        DOUT << "Removing " << F->getName() << " from " << CI->getParent()->getParent()->getName() << "\n";
+        Graph.removeFunctionCalls(*F);
+      }
+}
 
-  GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
-  GlobalsGraph->setPrintAuxCalls();
+bool StdLibDataStructures::runOnModule(Module &M) {
+  init(&getAnalysis<LocalDataStructures>(), false, true);
 
   //Clone Module
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
     if (!I->isDeclaration())
       getOrCreateGraph(&*I);
 
+  //Functions we handle by summary
+
   for (int x = 0; recFuncs[x].name; ++x)
     if (Function* F = M.getFunction(recFuncs[x].name))
-      if (F->isDeclaration())
+      if (F->isDeclaration()) {
         for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
              ii != ee; ++ii)
           if (CallInst* CI = dyn_cast<CallInst>(ii))
             if (CI->getOperand(0) == F) {
               DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
-              if (recFuncs[x].action.ret_read)
+              if (recFuncs[x].action.read[0])
                 Graph.getNodeForValue(CI).getNode()->setReadMarker();
-              if (recFuncs[x].action.ret_write)
+              if (recFuncs[x].action.write[0])
                 Graph.getNodeForValue(CI).getNode()->setModifiedMarker();
-              if (recFuncs[x].action.ret_heap)
+              if (recFuncs[x].action.heap[0])
                 Graph.getNodeForValue(CI).getNode()->setHeapMarker();
 
-              if (recFuncs[x].action.args_read)
-                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+              for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                if (recFuncs[x].action.read[y])
                   if (isa<PointerType>(CI->getOperand(y)->getType()))
                     if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
                       Node->setReadMarker();
-              if (recFuncs[x].action.args_write)
-                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+              for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                if (recFuncs[x].action.write[y])
                   if (isa<PointerType>(CI->getOperand(y)->getType()))
                     if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
                       Node->setModifiedMarker();
-              if (recFuncs[x].action.args_heap)
-                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+              for (unsigned y = 1; y < CI->getNumOperands(); ++y)
+                if (recFuncs[x].action.heap[y])
                   if (isa<PointerType>(CI->getOperand(y)->getType()))
                     if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
                       Node->setHeapMarker();
@@ -156,32 +220,19 @@
                 for (unsigned y = 1; y < CI->getNumOperands(); ++y)
                   if (isa<PointerType>(CI->getOperand(y)->getType()))
                     if (DSNode * Node=Graph.getNodeForValue(CI->getOperand(y)).getNode())
-                    Node->foldNodeCompletely();
+                      Node->foldNodeCompletely();
               }
-
+            }
+        for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
+             ii != ee; ++ii)
+          if (CallInst* CI = dyn_cast<CallInst>(ii))
+            if (CI->getOperand(0) == F) {
+              DSGraph& Graph = getDSGraph(*CI->getParent()->getParent());
               //delete the call
               DOUT << "Removing " << F->getName() << " from " << CI->getParent()->getParent()->getName() << "\n";
               Graph.removeFunctionCalls(*F);
             }
+      }
   
   return false;
 }
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void StdLibDataStructures::releaseMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
-

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

==============================================================================
--- poolalloc/trunk/lib/DSA/Steensgaard.cpp (original)
+++ poolalloc/trunk/lib/DSA/Steensgaard.cpp Thu Oct  9 01:24:31 2008
@@ -27,7 +27,7 @@
   class Steens : public ModulePass, public AliasAnalysis {
     DSGraph *ResultGraph;
 
-    EquivalenceClasses<GlobalValue*> GlobalECs;  // Always empty
+    EquivalenceClasses<const GlobalValue*> GlobalECs;  // Always empty
   public:
     static char ID;
     Steens() : ModulePass((intptr_t)&ID), ResultGraph(0) {}
@@ -73,7 +73,7 @@
     virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
 
   private:
-    void ResolveFunctionCall(Function *F, const DSCallSite &Call,
+    void ResolveFunctionCall(const Function *F, const DSCallSite &Call,
                              DSNodeHandle &RetVal);
   };
 
@@ -93,7 +93,7 @@
 /// with the specified call site descriptor.  This function links the arguments
 /// and the return value for the call site context-insensitively.
 ///
-void Steens::ResolveFunctionCall(Function *F, const DSCallSite &Call,
+void Steens::ResolveFunctionCall(const Function *F, const DSCallSite &Call,
                                  DSNodeHandle &RetVal) {
   assert(ResultGraph != 0 && "Result graph not allocated!");
   DSGraph::ScalarMapTy &ValMap = ResultGraph->getScalarMap();
@@ -104,7 +104,7 @@
 
   // Loop over all pointer arguments, resolving them to their provided pointers
   unsigned PtrArgIdx = 0;
-  for (Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
        AI != AE && PtrArgIdx < Call.getNumPtrArgs(); ++AI) {
     DSGraph::ScalarMapTy::iterator I = ValMap.find(AI);
     if (I != ValMap.end())    // If its a pointer argument...
@@ -150,7 +150,7 @@
     DSCallSite &CurCall = *CI++;
 
     // Loop over the called functions, eliminating as many as possible...
-    std::vector<Function*> CallTargets;
+    std::vector<const Function*> CallTargets;
     if (CurCall.isDirectCall())
       CallTargets.push_back(CurCall.getCalleeFunc());
     else
@@ -158,7 +158,7 @@
 
     for (unsigned c = 0; c != CallTargets.size(); ) {
       // If we can eliminate this function call, do so!
-      Function *F = CallTargets[c];
+      const Function *F = CallTargets[c];
       if (!F->isDeclaration()) {
         ResolveFunctionCall(F, CurCall, ResultGraph->getReturnNodes()[F]);
         CallTargets[c] = CallTargets.back();

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

==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Thu Oct  9 01:24:31 2008
@@ -48,7 +48,7 @@
   for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
     DSNodeHandle &NH = N->getLink(i*N->getPointerSize());
     if (DSNode *NN = NH.getNode()) {
-      std::vector<Function*> Functions;
+      std::vector<const Function*> Functions;
       NN->addFullFunctionList(Functions);
       ArgsRemainIncomplete.insert(Functions.begin(), Functions.end());
       markReachableFunctionsExternallyAccessible(NN, Visited);
@@ -61,14 +61,7 @@
 // program.
 //
 bool TDDataStructures::runOnModule(Module &M) {
-  BUInfo = &getAnalysis<BUDataStructures>();
-  setGraphSource(BUInfo);
-  setTargetData(BUInfo->getTargetData());
-  setGraphClone(true);
-
-  GlobalECs = BUInfo->getGlobalECs();
-  GlobalsGraph = new DSGraph(BUInfo->getGlobalsGraph(), GlobalECs);
-  GlobalsGraph->setPrintAuxCalls();
+  init(&getAnalysis<BUDataStructures>(), true, true);
 
   // Figure out which functions must not mark their arguments complete because
   // they are accessible outside this compilation unit.  Currently, these
@@ -144,7 +137,8 @@
 }
 
 
-void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
+void TDDataStructures::ComputePostOrder(const Function &F,
+                                        hash_set<DSGraph*> &Visited,
                                         std::vector<DSGraph*> &PostOrder) {
   if (F.isDeclaration()) return;
   DSGraph &G = getOrCreateGraph(&F);
@@ -154,39 +148,14 @@
   // Recursively traverse all of the callee graphs.
   for (DSGraph::fc_iterator CI = G.fc_begin(), CE = G.fc_end(); CI != CE; ++CI){
     Instruction *CallI = CI->getCallSite().getInstruction();
-    for (BUDataStructures::callee_iterator I = BUInfo->callee_begin(CallI),
-           E = BUInfo->callee_end(CallI); I != E; ++I)
-      ComputePostOrder(*I->second, Visited, PostOrder);
+    for (callee_iterator I = callee_begin(CallI),
+           E = callee_end(CallI); I != E; ++I)
+      ComputePostOrder(**I, Visited, PostOrder);
   }
 
   PostOrder.push_back(&G);
 }
 
-
-
-
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-// FIXME: This should be releaseMemory and will work fine, except that LoadVN
-// has no way to extend the lifetime of the pass, which screws up ds-aa.
-//
-void TDDataStructures::releaseMyMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
-
 /// InlineCallersIntoGraph - Inline all of the callers of the specified DS graph
 /// into it, then recompute completeness of nodes in the resultant graph.
 void TDDataStructures::InlineCallersIntoGraph(DSGraph &DSG) {
@@ -235,7 +204,7 @@
     // Inline all call sites from this caller graph.
     do {
       const DSCallSite &CS = *EdgesFromCaller.back().CS;
-      Function &CF = *EdgesFromCaller.back().CalledFunction;
+      const Function &CF = *EdgesFromCaller.back().CalledFunction;
       DOUT << "   [TD] Inlining graph into Fn '" << CF.getName() << "' from ";
       if (CallerGraph.getReturnNodes().empty())
         DOUT << "SYNTHESIZED INDIRECT GRAPH";
@@ -300,21 +269,21 @@
 
     Instruction *CallI = CI->getCallSite().getInstruction();
     // For each function in the invoked function list at this call site...
-    BUDataStructures::callee_iterator IPI =
-      BUInfo->callee_begin(CallI), IPE = BUInfo->callee_end(CallI);
+    callee_iterator IPI =
+      callee_begin(CallI), IPE = callee_end(CallI);
 
     // Skip over all calls to this graph (SCC calls).
-    while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
+    while (IPI != IPE && &getDSGraph(**IPI) == &DSG)
       ++IPI;
 
     // All SCC calls?
     if (IPI == IPE) continue;
 
-    Function *FirstCallee = IPI->second;
+    const Function *FirstCallee = *IPI;
     ++IPI;
 
     // Skip over more SCC calls.
-    while (IPI != IPE && &getDSGraph(*IPI->second) == &DSG)
+    while (IPI != IPE && &getDSGraph(**IPI) == &DSG)
       ++IPI;
 
     // If there is exactly one callee from this call site, remember the edge in
@@ -331,15 +300,14 @@
     // this set of targets.  If so, we don't want to do M*N inlining operations,
     // so we build up a new, private, graph that represents the calls of all
     // calls to this set of functions.
-    std::vector<Function*> Callees;
-    for (BUDataStructures::ActualCalleesTy::const_iterator I =
-           BUInfo->callee_begin(CallI), E = BUInfo->callee_end(CallI);
+    std::vector<const Function*> Callees;
+    for (callee_iterator I = callee_begin(CallI), E = callee_end(CallI);
          I != E; ++I)
-      if (!I->second->isDeclaration())
-        Callees.push_back(I->second);
+      if (!(*I)->isDeclaration())
+        Callees.push_back(*I);
     std::sort(Callees.begin(), Callees.end());
 
-    std::map<std::vector<Function*>, DSGraph*>::iterator IndCallRecI =
+    std::map<std::vector<const Function*>, DSGraph*>::iterator IndCallRecI =
       IndCallMap.lower_bound(Callees);
 
     DSGraph *IndCallGraph;

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

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Thu Oct  9 01:24:31 2008
@@ -393,6 +393,7 @@
                                            OldFuncTy->isVarArg());
   // Create the new function...
   Function *New = Function::Create(FuncTy, Function::InternalLinkage, F.getName());
+  New->copyAttributesFrom(&F);
   F.getParent()->getFunctionList().insert(&F, New);
   CloneToOrigMap[New] = &F;   // Remember original function.
 

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

==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Thu Oct  9 01:24:31 2008
@@ -70,9 +70,15 @@
     void visitMemAlignCall(CallSite CS);
     void visitStrdupCall(CallSite CS);
     void visitFreeInst(FreeInst &FI);
-    void visitCallSite(CallSite CS);
-    void visitCallInst(CallInst &CI) { visitCallSite(&CI); }
-    void visitInvokeInst(InvokeInst &II) { visitCallSite(&II); }
+    void visitCallSite(CallSite &CS);
+    void visitCallInst(CallInst &CI) {
+      CallSite CS(&CI);
+      visitCallSite(CS);
+    }
+    void visitInvokeInst(InvokeInst &II) {
+      CallSite CS(&II);
+      visitCallSite(CS);
+    }
     void visitLoadInst(LoadInst &I);
     void visitStoreInst (StoreInst &I);
 
@@ -532,8 +538,8 @@
 }
 
 
-void FuncTransform::visitCallSite(CallSite CS) {
-  Function *CF = CS.getCalledFunction();
+void FuncTransform::visitCallSite(CallSite& CS) {
+  const Function *CF = CS.getCalledFunction();
   Instruction *TheCall = CS.getInstruction();
 
   // If the called function is casted from one function type to another, peer
@@ -614,11 +620,10 @@
 
     if (!CF) 
       for (EquivClassGraphs::callee_iterator I = ECGraphs.callee_begin(OrigInst), 
-           E = ECGraphs.callee_end(OrigInst); I != E; ++I)
-        if (I->second) {
-          CF = I->second;
-          break;
-        }
+             E = ECGraphs.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.
@@ -627,11 +632,11 @@
     if (!CF) {
       DSGraph* dg = &ECGraphs.getDSGraph(*OrigInst->getParent()->getParent());
       DSNode* d = dg->getNodeForValue(OrigInst->getOperand(0)).getNode();
-      const std::vector<GlobalValue*> &g = d->getGlobalsList();
-      for(std::vector<GlobalValue*>::const_iterator ii = g.begin(), ee = g.end();
+      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< GlobalValue *> & EC = ECGraphs.getGlobalECs();
-        for (EquivalenceClasses<GlobalValue *>::member_iterator MI = EC.findLeader(*ii);
+        EquivalenceClasses< const GlobalValue *> & EC = ECGraphs.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))) {
 	    std::cerr << "\n***\nPA: *** WARNING (FuncTransform::visitCallSite): "
@@ -654,6 +659,7 @@
       std::cerr << "\n***\nPA: *** WARNING (FuncTransform::visitCallSite): "
                 << "Unknown callees for call-site in function "
                 << CS.getCaller()->getName() << "\n***\n";
+      abort();
       return;
     }
 
@@ -665,8 +671,8 @@
     EquivClassGraphs::callee_iterator I =
       ECGraphs.callee_begin(OrigInst), E = ECGraphs.callee_end(OrigInst);
     for (; I != E; ++I)
-      if (!I->second->isDeclaration())
-        assert(CalleeGraph == &ECGraphs.getDSGraph(*I->second) &&
+      if (!(*I)->isDeclaration())
+        assert(CalleeGraph == &ECGraphs.getDSGraph(**I) &&
                "Callees at call site do not have a common graph!");
 #endif    
 
@@ -692,7 +698,7 @@
     NewCallee = CastInst::createPointerCast(CS.getCalledValue(), PFTy, "tmp", TheCall);
   }
 
-  Function::arg_iterator FAI = CF->arg_begin(), E = CF->arg_end();
+  Function::const_arg_iterator FAI = CF->arg_begin(), E = CF->arg_end();
   CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
   for ( ; FAI != E && AI != AE; ++FAI, ++AI)
     if (!isa<Constant>(*AI))





More information about the llvm-commits mailing list