[llvm-commits] CVS: llvm-poolalloc/lib/DSA/BottomUpClosure.cpp DataStructure.cpp Local.cpp Steensgaard.cpp TopDownClosure.cpp

Andrew Lenharth alenhar2 at cs.uiuc.edu
Wed Apr 11 10:38:05 PDT 2007



Changes in directory llvm-poolalloc/lib/DSA:

BottomUpClosure.cpp updated: 1.130 -> 1.131
DataStructure.cpp updated: 1.259 -> 1.260
Local.cpp updated: 1.168 -> 1.169
Steensgaard.cpp updated: 1.69 -> 1.70
TopDownClosure.cpp updated: 1.98 -> 1.99
---
Log message:

Minor refactoring, and cutting out stuff that should be (and is) in another branch

---
Diffs of the changes:  (+396 -821)

 BottomUpClosure.cpp |  198 ------------
 DataStructure.cpp   |  219 ++++++++++++--
 Local.cpp           |  797 ++++++++++++----------------------------------------
 Steensgaard.cpp     |    1 
 TopDownClosure.cpp  |    2 
 5 files changed, 396 insertions(+), 821 deletions(-)


Index: llvm-poolalloc/lib/DSA/BottomUpClosure.cpp
diff -u llvm-poolalloc/lib/DSA/BottomUpClosure.cpp:1.130 llvm-poolalloc/lib/DSA/BottomUpClosure.cpp:1.131
--- llvm-poolalloc/lib/DSA/BottomUpClosure.cpp:1.130	Fri Feb 23 16:49:32 2007
+++ llvm-poolalloc/lib/DSA/BottomUpClosure.cpp	Wed Apr 11 12:37:43 2007
@@ -30,120 +30,8 @@
   STATISTIC (NumBUInlines, "Number of graphs inlined");
   STATISTIC (NumCallEdges, "Number of 'actual' call edges");
 
-  cl::opt<bool>
-  AddGlobals("budatastructures-annotate-calls", cl::Hidden,
-	     cl::desc("Annotate call sites with functions as they are resolved"));
-  cl::opt<bool>
-  UpdateGlobals("budatastructures-update-from-globals", cl::Hidden,
-		cl::desc("Update local graph from global graph when processing function"));
-
   RegisterPass<BUDataStructures>
-  X("budatastructure", "Bottom-up Data Structure Analysis");
-}
-
-static bool GetAllCalleesN(const DSCallSite &CS,
-                          std::vector<Function*> &Callees);
-
-/// BuildGlobalECs - Look at all of the nodes in the globals graph.  If any node
-/// contains multiple globals, DSA will never, ever, be able to tell the globals
-/// 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.
-static void BuildGlobalECs(DSGraph &GG, std::set<GlobalValue*> &ECGlobals) {
-  DSScalarMap &SM = GG.getScalarMap();
-  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
-  for (DSGraph::node_iterator I = GG.node_begin(), E = GG.node_end();
-       I != E; ++I) {
-    if (I->getGlobalsList().size() <= 1) continue;
-
-    // First, build up the equivalence set for this block of globals.
-    const std::vector<GlobalValue*> &GVs = I->getGlobalsList();
-    GlobalValue *First = GVs[0];
-    for (unsigned i = 1, e = GVs.size(); i != e; ++i)
-      GlobalECs.unionSets(First, GVs[i]);
-
-    // Next, get the leader element.
-    assert(First == GlobalECs.getLeaderValue(First) &&
-           "First did not end up being the leader?");
-
-    // Next, remove all globals from the scalar map that are not the leader.
-    assert(GVs[0] == First && "First had to be at the front!");
-    for (unsigned i = 1, e = GVs.size(); i != e; ++i) {
-      ECGlobals.insert(GVs[i]);
-      SM.erase(SM.find(GVs[i]));
-    }
-
-    // Finally, change the global node to only contain the leader.
-    I->clearGlobals();
-    I->addGlobal(First);
-  }
-
-  DEBUG(GG.AssertGraphOK());
-}
-
-/// EliminateUsesOfECGlobals - Once we have determined that some globals are in
-/// really just equivalent to some other globals, remove the globals from the
-/// specified DSGraph (if present), and merge any nodes with their leader nodes.
-static void EliminateUsesOfECGlobals(DSGraph &G,
-                                     const std::set<GlobalValue*> &ECGlobals) {
-  DSScalarMap &SM = G.getScalarMap();
-  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
-
-  bool MadeChange = false;
-  for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
-       GI != E; ) {
-    GlobalValue *GV = *GI++;
-    if (!ECGlobals.count(GV)) continue;
-
-    const DSNodeHandle &GVNH = SM[GV];
-    assert(!GVNH.isNull() && "Global has null NH!?");
-
-    // Okay, this global is in some equivalence class.  Start by finding the
-    // leader of the class.
-    GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
-
-    // If the leader isn't already in the graph, insert it into the node
-    // corresponding to GV.
-    if (!SM.global_count(Leader)) {
-      GVNH.getNode()->addGlobal(Leader);
-      SM[Leader] = GVNH;
-    } else {
-      // Otherwise, the leader is in the graph, make sure the nodes are the
-      // merged in the specified graph.
-      const DSNodeHandle &LNH = SM[Leader];
-      if (LNH.getNode() != GVNH.getNode())
-        LNH.mergeWith(GVNH);
-    }
-
-    // Next step, remove the global from the DSNode.
-    GVNH.getNode()->removeGlobal(GV);
-
-    // Finally, remove the global from the ScalarMap.
-    SM.erase(GV);
-    MadeChange = true;
-  }
-
-  DEBUG(if(MadeChange) G.AssertGraphOK());
-}
-
-static void AddGlobalToNode(BUDataStructures* B, DSCallSite D, Function* F) {
-  if(!AddGlobals)
-    return;
-  if(D.isIndirectCall()) {
-    DSGraph* GI = &B->getDSGraph(D.getCaller());
-    DSNodeHandle& NHF = GI->getNodeForValue(F);
-    DSCallSite DL = GI->getDSCallSiteForCallSite(D.getCallSite());
-    if (DL.getCalleeNode() != NHF.getNode() || NHF.isNull()) {
-      if (NHF.isNull()) {
-        DSNode *N = new DSNode(F->getType()->getElementType(), GI);   // Create the node
-        N->addGlobal(F);
-        NHF.setTo(N,0);
-        DOUT << "Adding " << F->getName() << " to a call node in "
-             << D.getCaller().getName() << "\n";
-      }
-      DL.getCalleeNode()->mergeWith(NHF, 0);
-    }
-  }
+  X("dsa-bu", "Bottom-up Data Structure Analysis");
 }
 
 // run - Calculate the bottom up data structure graphs for each function in the
@@ -151,6 +39,9 @@
 //
 bool BUDataStructures::runOnModule(Module &M) {
   LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
+  setGraphSource(&LocalDSA);
+  setTargetData(LocalDSA.getTargetData());
+  setGraphClone(false);
   GlobalECs = LocalDSA.getGlobalECs();
 
   GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph(), GlobalECs);
@@ -197,17 +88,7 @@
   // Mark external globals incomplete.
   GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
 
-  // Grow the equivalence classes for the globals to include anything that we
-  // now know to be aliased.
-  std::set<GlobalValue*> ECGlobals;
-  BuildGlobalECs(*GlobalsGraph, ECGlobals);
-  if (!ECGlobals.empty()) {
-    NamedRegionTimer X("Bottom-UP EC Cleanup");
-    DOUT << "Eliminating " << ECGlobals.size() << " EC Globals!\n";
-    for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-           E = DSInfo.end(); I != E; ++I)
-      EliminateUsesOfECGlobals(*I->second, ECGlobals);
-  }
+  formGlobalECs();
 
   // Merge the globals variables (not the calls) from the globals graph back
   // into the main function's graph so that the main function contains all of
@@ -228,23 +109,6 @@
     MainGraph.maskIncompleteMarkers();
     MainGraph.markIncompleteNodes(DSGraph::MarkFormalArgs |
                                   DSGraph::IgnoreGlobals);
-
-    //Debug messages if along the way we didn't resolve a call site
-    //also update the call graph and callsites we did find.
-    for(DSGraph::afc_iterator ii = MainGraph.afc_begin(),
-          ee = MainGraph.afc_end(); ii != ee; ++ii) {
-      std::vector<Function*> Funcs;
-      GetAllCalleesN(*ii, Funcs);
-      DOUT << "Lost site\n";
-      DEBUG(ii->getCallSite().getInstruction()->dump());
-      for (std::vector<Function*>::iterator iif = Funcs.begin(), eef = Funcs.end();
-           iif != eef; ++iif) {
-        AddGlobalToNode(this, *ii, *iif);
-        DOUT << "Adding\n";
-        ActualCallees.insert(std::make_pair(ii->getCallSite().getInstruction(), *iif));
-      }
-    }
-
   }
 
   NumCallEdges += ActualCallees.size();
@@ -252,25 +116,6 @@
   return false;
 }
 
-DSGraph &BUDataStructures::getOrCreateGraph(Function *F) {
-  // Has the graph already been created?
-  DSGraph *&Graph = DSInfo[F];
-  if (Graph) return *Graph;
-
-  DSGraph &LocGraph = getAnalysis<LocalDataStructures>().getDSGraph(*F);
-
-  // Steal the local graph.
-  Graph = new DSGraph(GlobalECs, LocGraph.getTargetData());
-  Graph->spliceFrom(LocGraph);
-
-  Graph->setGlobalsGraph(GlobalsGraph);
-  Graph->setPrintAuxCalls();
-
-  // Start with a copy of the original call sites...
-  Graph->getAuxFunctionCalls() = Graph->getFunctionCalls();
-  return *Graph;
-}
-
 static bool isVAHackFn(const Function *F) {
   return F->getName() == "printf"  || F->getName() == "sscanf" ||
     F->getName() == "fprintf" || F->getName() == "open" ||
@@ -302,33 +147,6 @@
   }
 }
 
-//returns true if all callees were resolved
-static bool GetAllCalleesN(const DSCallSite &CS,
-                          std::vector<Function*> &Callees) {
-  if (CS.isDirectCall()) {
-    if (isResolvableFunc(CS.getCalleeFunc())) {
-      Callees.push_back(CS.getCalleeFunc());
-      return true;
-    } else
-      return false;
-  } else {
-    // Get all callees.
-    bool retval = CS.getCalleeNode()->isComplete();
-    unsigned OldSize = Callees.size();
-    CS.getCalleeNode()->addFullFunctionList(Callees);
-
-    // If any of the callees are unresolvable, remove that one
-    for (unsigned i = OldSize; i != Callees.size(); ++i)
-      if (!isResolvableFunc(Callees[i])) {
-        Callees.erase(Callees.begin()+i);
-        --i;
-       retval = false;
-      }
-    return retval;
-    //return false;
-  }
-}
-
 /// 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) {
@@ -357,8 +175,6 @@
   }
 
   DSGraph &Graph = getOrCreateGraph(F);
-  if (UpdateGlobals)
-    Graph.updateFromGlobalGraph();
 
   // Find all callee functions.
   std::vector<Function*> CalleeFunctions;
@@ -496,8 +312,8 @@
   if (F->getName() == "free") { // Taking the address of free.
 
     // Free should take a single pointer argument, mark it as heap memory.
-    DSNode *N = new DSNode(0, DSG);
-    N->setHeapNodeMarker();
+    DSNodeHandle N(new DSNode(0, DSG));
+    N.getNode()->setHeapNodeMarker();
     DSG->getNodeForValue(F->arg_begin()).mergeWith(N);
 
   } else {


Index: llvm-poolalloc/lib/DSA/DataStructure.cpp
diff -u llvm-poolalloc/lib/DSA/DataStructure.cpp:1.259 llvm-poolalloc/lib/DSA/DataStructure.cpp:1.260
--- llvm-poolalloc/lib/DSA/DataStructure.cpp:1.259	Fri Feb 23 16:49:32 2007
+++ llvm-poolalloc/lib/DSA/DataStructure.cpp	Wed Apr 11 12:37:43 2007
@@ -1,4 +1,3 @@
-#define JTC 0
 //===- DataStructure.cpp - Implement the core data structure analysis -----===//
 //
 //                     The LLVM Compiler Infrastructure
@@ -30,7 +29,6 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/ADT/hash_map"
-#include "poolalloc/Config/config.h"
 
 #include <iostream>
 #include <algorithm>
@@ -1471,9 +1469,7 @@
   AuxFunctionCalls.clear();
   ScalarMap.clear();
   ReturnNodes.clear();
-#ifdef LLVA_KERNEL
-  PoolDescriptors.clear();
-#endif  
+
   // Drop all intra-node references, so that assertions don't fail...
   for (node_iterator NI = node_begin(), E = node_end(); NI != E; ++NI)
     NI->dropAllReferences();
@@ -1514,7 +1510,7 @@
   if (GlobalValue *GV = dyn_cast<GlobalValue>(Ptr)) {
     N->addGlobal(GV);
   } else if (isa<MallocInst>(Ptr)) {
-    N->setHeapNodeMarker();
+   N->setHeapNodeMarker();
   } else if (isa<AllocaInst>(Ptr)) {
     N->setAllocaNodeMarker();
   } else {
@@ -1630,17 +1626,6 @@
 
   // Merge the scalar map in.
   ScalarMap.spliceFrom(RHS.ScalarMap);
-
-#ifdef LLVA_KERNEL
-  //Take all from the pooldescriptor map
-#if 0
-  PoolDescriptors.swap(RHS.getPoolDescriptorsMap());
-#else
-  hash_map<const DSNode *, MetaPoolHandle*>& rhsmap = RHS.getPoolDescriptorsMap();
-  PoolDescriptors.insert(rhsmap.begin(), rhsmap.end());
-#endif
-  RHS.getPoolDescriptorsMap().clear();
-#endif  
 }
 
 /// spliceFrom - Copy all entries from RHS, then clear RHS.
@@ -1670,7 +1655,7 @@
   Args.push_back(getReturnNodeFor(*F));
   for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
        AI != E; ++AI)
-    if (isPointerType(AI->getType())) {
+    if (isa<PointerType>(AI->getType())) {
       Args.push_back(getNodeForValue(AI));
       assert(!Args.back().isNull() && "Pointer argument w/o scalarmap entry!?");
     }
@@ -1897,7 +1882,7 @@
   std::vector<DSNodeHandle> Args;
 
   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
-    if (isPointerType(I->getType()))
+    if (isa<PointerType>(I->getType()))
       Args.push_back(getNodeForValue(I));
 
   return DSCallSite(CallSite(), getReturnNodeFor(F), &F, Args);
@@ -1908,7 +1893,7 @@
 DSCallSite DSGraph::getDSCallSiteForCallSite(CallSite CS) const {
   DSNodeHandle RetVal;
   Instruction *I = CS.getInstruction();
-  if (isPointerType(I->getType()))
+  if (isa<PointerType>(I->getType()))
     RetVal = getNodeForValue(I);
 
   std::vector<DSNodeHandle> Args;
@@ -1916,7 +1901,7 @@
 
   // Calculate the arguments vector...
   for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
-    if (isPointerType((*I)->getType()))
+    if (isa<PointerType>((*I)->getType()))
       if (isa<ConstantPointerNull>(*I))
         Args.push_back(DSNodeHandle());
       else
@@ -1978,7 +1963,7 @@
       Function &F = *FI->first;
       for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
            I != E; ++I)
-        if (isPointerType(I->getType()))
+        if (isa<PointerType>(I->getType()))
           markIncompleteNode(getNodeForValue(I).getNode());
       markIncompleteNode(FI->second.getNode());
     }
@@ -2548,7 +2533,7 @@
        RI != E; ++RI) {
     Function &F = *RI->first;
     for (Function::arg_iterator AI = F.arg_begin(); AI != F.arg_end(); ++AI)
-      if (isPointerType(AI->getType()))
+      if (isa<PointerType>(AI->getType()))
         assert(!getNodeForValue(AI).isNull() &&
                "Pointer argument must be in the scalar map!");
   }
@@ -2678,3 +2663,191 @@
       RC.merge(getNodeForValue(*I), It->second);
   }
 }
+
+
+////////////////////////////////////////////////////////////////////////////////
+//Base DataStructures impl:
+////////////////////////////////////////////////////////////////////////////////
+
+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 DataStructures::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 DataStructures::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();
+}
+
+DSGraph& DataStructures::getOrCreateGraph(Function* F) {
+  assert(F && "No function");
+  DSGraph *&G = DSInfo[F];
+  if (!G) {
+    //Clone or Steal the Source Graph
+    DSGraph &BaseGraph = GraphSource->getDSGraph(*F);
+    if (Clone) {
+      G = new DSGraph(BaseGraph, GlobalECs, DSGraph::DontCloneAuxCallNodes);
+    } else {
+      G = new DSGraph(GlobalECs, GraphSource->getTargetData());
+      G->spliceFrom(BaseGraph);
+      G->getAuxFunctionCalls() = G->getFunctionCalls();
+    }
+    G->setPrintAuxCalls();
+    G->setGlobalsGraph(GlobalsGraph);
+    
+    // Note that this graph is the graph for ALL of the function in the SCC, not
+    // just F.
+    for (DSGraph::retnodes_iterator RI = G->retnodes_begin(),
+           E = G->retnodes_end(); RI != E; ++RI)
+      if (RI->first != F)
+        DSInfo[RI->first] = G;
+  }
+  return *G;
+}
+
+
+void DataStructures::formGlobalECs() {
+  // Grow the equivalence classes for the globals to include anything that we
+  // now know to be aliased.
+  std::set<GlobalValue*> ECGlobals;
+  buildGlobalECs(ECGlobals);
+  if (!ECGlobals.empty()) {
+    DOUT << "Eliminating " << ECGlobals.size() << " EC Globals!\n";
+    for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
+           E = DSInfo.end(); I != E; ++I)
+      eliminateUsesOfECGlobals(*I->second, ECGlobals);
+  }
+}
+
+/// BuildGlobalECs - Look at all of the nodes in the globals graph.  If any node
+/// contains multiple globals, DSA will never, ever, be able to tell the globals
+/// 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) {
+  DSScalarMap &SM = GlobalsGraph->getScalarMap();
+  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+  for (DSGraph::node_iterator I = GlobalsGraph->node_begin(), 
+         E = GlobalsGraph->node_end();
+       I != E; ++I) {
+    if (I->getGlobalsList().size() <= 1) continue;
+
+    // First, build up the equivalence set for this block of globals.
+    DSNode::globals_iterator i = I->globals_begin();
+    GlobalValue *First = *i++;
+    for( ; i != I->globals_end(); ++i) {
+      GlobalECs.unionSets(First, *i);
+      ECGlobals.insert(*i);
+      SM.erase(SM.find(*i));
+    }
+
+    // Next, get the leader element.
+    assert(First == GlobalECs.getLeaderValue(First) &&
+           "First did not end up being the leader?");
+
+    // Finally, change the global node to only contain the leader.
+    I->clearGlobals();
+    I->addGlobal(First);
+  }
+
+  DEBUG(GlobalsGraph->AssertGraphOK());
+}
+
+/// EliminateUsesOfECGlobals - Once we have determined that some globals are in
+/// 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) {
+  DSScalarMap &SM = G.getScalarMap();
+  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
+
+  bool MadeChange = false;
+  for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
+       GI != E; ) {
+    GlobalValue *GV = *GI++;
+    if (!ECGlobals.count(GV)) continue;
+
+    const DSNodeHandle &GVNH = SM[GV];
+    assert(!GVNH.isNull() && "Global has null NH!?");
+
+    // Okay, this global is in some equivalence class.  Start by finding the
+    // leader of the class.
+    GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
+
+    // If the leader isn't already in the graph, insert it into the node
+    // corresponding to GV.
+    if (!SM.global_count(Leader)) {
+      GVNH.getNode()->addGlobal(Leader);
+      SM[Leader] = GVNH;
+    } else {
+      // Otherwise, the leader is in the graph, make sure the nodes are the
+      // merged in the specified graph.
+      const DSNodeHandle &LNH = SM[Leader];
+      if (LNH.getNode() != GVNH.getNode())
+        LNH.mergeWith(GVNH);
+    }
+
+    // Next step, remove the global from the DSNode.
+    GVNH.getNode()->removeGlobal(GV);
+
+    // Finally, remove the global from the ScalarMap.
+    SM.erase(GV);
+    MadeChange = true;
+  }
+
+  DEBUG(if(MadeChange) G.AssertGraphOK());
+}


Index: llvm-poolalloc/lib/DSA/Local.cpp
diff -u llvm-poolalloc/lib/DSA/Local.cpp:1.168 llvm-poolalloc/lib/DSA/Local.cpp:1.169
--- llvm-poolalloc/lib/DSA/Local.cpp:1.168	Fri Feb 23 16:49:32 2007
+++ llvm-poolalloc/lib/DSA/Local.cpp	Wed Apr 11 12:37:43 2007
@@ -1,4 +1,3 @@
-#define JTC 0
 //===- Local.cpp - Compute a local data structure graph for a function ----===//
 //
 //                     The LLVM Compiler Infrastructure
@@ -26,7 +25,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Timer.h"
-#include "poolalloc/Config/config.h"
 #include <iostream>
 
 // FIXME: This should eventually be a FunctionPass that is automatically
@@ -36,18 +34,8 @@
 
 using namespace llvm;
 
-#ifdef LLVA_KERNEL
-static STATISTIC (CacheAllocs , "Number of kmem_cache_alloc calls");
-static STATISTIC (KMallocs    , "Number of kmalloc calls");
-static STATISTIC (GlobalPools , "Number of global pools");
-#endif
-
 static RegisterPass<LocalDataStructures>
-X("datastructure", "Local Data Structure Analysis");
-
-static cl::opt<bool>
-TrackIntegersAsPointers("dsa-track-integers", cl::Hidden,
-         cl::desc("If this is set, track integers as potential pointers"));
+X("dsa-local", "Local Data Structure Analysis");
 
 static cl::opt<bool>
 IgnoreSetCC("dsa-ignore-setcc", cl::Hidden,
@@ -65,29 +53,7 @@
           cl::desc("List of functions that free memory from the heap"),
           cl::CommaSeparated, cl::Hidden);
 
-namespace llvm {
-namespace DS {
-  // isPointerType - Return true if this type is big enough to hold a pointer.
-  bool isPointerType(const Type *Ty) {
-    if (isa<PointerType>(Ty))
-      return true;
-    else if (TrackIntegersAsPointers && Ty->isPrimitiveType() &&Ty->isInteger())
-      return Ty->getPrimitiveSizeInBits() >= PointerSize;
-    return false;
-  }
-}}
-
-using namespace DS;
-
 namespace {
-  cl::opt<bool>
-  DisableDirectCallOpt("disable-direct-call-dsopt", cl::Hidden,
-                       cl::desc("Disable direct call optimization in "
-                                "DSGraph construction"));
-  cl::opt<bool>
-  DisableFieldSensitivity("disable-ds-field-sensitivity", cl::Hidden,
-                          cl::desc("Disable field sensitivity in DSGraphs"));
-
   //===--------------------------------------------------------------------===//
   //  GraphBuilder Class
   //===--------------------------------------------------------------------===//
@@ -97,109 +63,21 @@
   ///
   class GraphBuilder : InstVisitor<GraphBuilder> {
     DSGraph &G;
-    DSNodeHandle *RetNode;               // Node that gets returned...
-    DSScalarMap &ScalarMap;
-    std::list<DSCallSite> *FunctionCalls;
-    Value * KMallocPool;
-  public:
-    GraphBuilder(Function &f, DSGraph &g, DSNodeHandle &retNode,
-                 std::list<DSCallSite> &fc)
-      : G(g), RetNode(&retNode), ScalarMap(G.getScalarMap()),
-        FunctionCalls(&fc) {
-      // Find the type unsafe pool in the program
-      KMallocPool = f.getParent()->getNamedGlobal ("KmallocPool");
-      
-#if 1
-      //
-      // Determine if the function somehow escapes
-      //
-      bool escapes = false;
-      if (!(f.hasInternalLinkage())) {
-        escapes = true;
-      }
-      Value::use_iterator U;
-      for (U=f.use_begin(); U != f.use_end(); ++U) {
-        if (isa<GlobalValue>(U)) {
-          std::cerr << "LLVA: isa: " << f.getName() << " " << *U << std::endl;
-          escapes = true;
-          break;
-        }
-      }
-#endif
-      // Create scalar nodes for all pointer arguments...
-      for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end();
-           I != E; ++I) {
-        if (isPointerType(I->getType())) {
-          DSNode * Node = getValueDest(*I).getNode();
-          if (!(f.hasInternalLinkage())) {
-            Node->setExternalMarker();
-          }
-        }
-      }
-
-      visit(f);  // Single pass over the function
-#if JTC
-std::cerr << "LLVA: Function " << f.getName() << "\n";
-      for (DSScalarMap::iterator I = ScalarMap.begin(), E=ScalarMap.end();
-           I != E;
-           ++I)
-      {
-        std::cerr << "LLVA:\t" << I->first->getName() << ": " << (void *)(I->second.getNode()) << "\n";
-      }
-#endif
-    }
-
-    // GraphBuilder ctor for working on the globals graph
-    GraphBuilder(DSGraph &g)
-      : G(g), RetNode(0), ScalarMap(G.getScalarMap()), FunctionCalls(0) {
-    }
-    void mergeInGlobalInitializer(GlobalVariable *GV);
+    Function* FB;
 
-  private:
-    // Visitor functions, used to handle each instruction type we encounter...
-    friend class InstVisitor<GraphBuilder>;
-    void visitMallocInst(MallocInst &MI) { handleAlloc(MI, true); }
-    void visitAllocaInst(AllocaInst &AI) { handleAlloc(AI, false); }
-    void handleAlloc(AllocationInst &AI, bool isHeap);
-
-    void visitPHINode(PHINode &PN);
-    void visitSelectInst(SelectInst &SI);
-
-    void visitGetElementPtrInst(User &GEP);
-    void visitReturnInst(ReturnInst &RI);
-    void visitLoadInst(LoadInst &LI);
-    void visitStoreInst(StoreInst &SI);
-    void visitCallInst(CallInst &CI);
-    void visitInvokeInst(InvokeInst &II);
-    void visitICmpInst(ICmpInst &I);
-    void visitFCmpInst(FCmpInst &I);
-    void visitFreeInst(FreeInst &FI);
-    void visitCastInst(CastInst &CI);
-    void visitInstruction(Instruction &I);
-
-    bool visitIntrinsic(CallSite CS, Function* F);
-    bool visitExternal(CallSite CS, Function* F);
-    void visitCallSite(CallSite CS);
-    void visitVAArgInst(VAArgInst   &I);
+    ////////////////////////////////////////////////////////////////////////////
+    // Helper functions used to implement the visitation functions...
 
     void MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C);
-  private:
-    // Helper functions used to implement the visitation functions...
 
     /// createNode - Create a new DSNode, ensuring that it is properly added to
     /// the graph.
     ///
-    DSNode *createNode(const Type *Ty = 0) {
-      DSNode *N = new DSNode(Ty, &G);   // Create the node
-      if (DisableFieldSensitivity) {
-        // Create node handle referring to the old node so that it is
-        // immediately removed from the graph when the node handle is destroyed.
-        DSNodeHandle OldNNH = N;
-        N->foldNodeCompletely();
-        if (DSNode *FN = N->getForwardNode())
-          N = FN;
-      }
-      return N;
+    DSNode *createNode(const Type *Ty = 0) 
+    {   
+      DSNode* ret = new DSNode(Ty, &G);
+      assert(ret->getParentGraph() && "No parent?");
+      return ret;
     }
 
     /// setDestTo - Set the ScalarMap entry for the specified value to point to
@@ -217,45 +95,89 @@
     /// null), then we create a new node, link it, then return it.
     ///
     DSNodeHandle &getLink(const DSNodeHandle &Node, unsigned Link = 0);
-  };
-}
 
-using namespace DS;
+    ////////////////////////////////////////////////////////////////////////////
+    // Visitor functions, used to handle each instruction type we encounter...
+    friend class InstVisitor<GraphBuilder>;
 
-//===----------------------------------------------------------------------===//
-// DSGraph constructor - Simply use the GraphBuilder to construct the local
-// graph.
-DSGraph::DSGraph(EquivalenceClasses<GlobalValue*> &ECs, const TargetData &td,
-                 Function &F, DSGraph *GG)
-  : GlobalsGraph(GG), ScalarMap(ECs), TD(td) {
-  PrintAuxCalls = false;
-
-  DOUT << "  [Loc] Calculating graph for: " << F.getName() << "\n";
-
-  // Use the graph builder to construct the local version of the graph
-  GraphBuilder B(F, *this, ReturnNodes[&F], FunctionCalls);
-#ifndef NDEBUG
-  Timer::addPeakMemoryMeasurement();
-#endif
+    void visitMallocInst(MallocInst &MI)
+    { setDestTo(MI, createNode()->setHeapNodeMarker()); }
 
-  // If there are any constant globals referenced in this function, merge their
-  // initializers into the local graph from the globals graph.
-  if (ScalarMap.global_begin() != ScalarMap.global_end()) {
-    ReachabilityCloner RC(*this, *GG, 0);
-
-    for (DSScalarMap::global_iterator I = ScalarMap.global_begin();
-         I != ScalarMap.global_end(); ++I)
-      if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
-        if (!GV->isDeclaration() && GV->isConstant())
-          RC.merge(ScalarMap[GV], GG->ScalarMap[GV]);
-  }
+    void visitAllocaInst(AllocaInst &AI)
+    { setDestTo(AI, createNode()->setAllocaNodeMarker()); }
 
-  markIncompleteNodes(DSGraph::MarkFormalArgs);
+    void visitFreeInst(FreeInst &FI)
+    { if (DSNode *N = getValueDest(*FI.getOperand(0)).getNode())
+        N->setHeapNodeMarker();
+    }
 
-  // Remove any nodes made dead due to merging...
-  removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-}
+    //the simple ones
+    void visitPHINode(PHINode &PN);
+    void visitSelectInst(SelectInst &SI);
+    void visitLoadInst(LoadInst &LI);
+    void visitStoreInst(StoreInst &SI);
+    void visitReturnInst(ReturnInst &RI);
+    void visitVAArgInst(VAArgInst   &I);
+    void visitIntToPtrInst(IntToPtrInst &I);
+    void visitPtrToIntInst(PtrToIntInst &I);
+    void visitBitCastInst(BitCastInst &I);
 
+    //the nasty ones
+    void visitGetElementPtrInst(User &GEP);
+    void visitCallInst(CallInst &CI);
+    void visitInvokeInst(InvokeInst &II);
+    void visitInstruction(Instruction &I);
+
+    bool visitIntrinsic(CallSite CS, Function* F);
+    bool visitExternal(llvm::CallSite, llvm::Function*);
+    void visitCallSite(CallSite CS);
+
+  public:
+    GraphBuilder(Function &f, DSGraph &g)
+      : G(g), FB(&f) {
+      // Create scalar nodes for all pointer arguments...
+      for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end();
+           I != E; ++I) {
+        if (isa<PointerType>(I->getType())) {
+          DSNode * Node = getValueDest(*I).getNode();
+
+          if (!(f.hasInternalLinkage())) {
+            Node->setExternalMarker();
+          }
+        }
+      }
+
+      // Create an entry for the return, which tracks which functions are in the graph
+      g.getOrCreateReturnNodeFor(f);
+
+      visit(f);  // Single pass over the function
+
+      // If there are any constant globals referenced in this function, merge their
+      // initializers into the local graph from the globals graph.
+      if (g.getScalarMap().global_begin() != g.getScalarMap().global_end()) {
+        ReachabilityCloner RC(g, *g.getGlobalsGraph(), 0);
+        
+        for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
+             I != g.getScalarMap().global_end(); ++I)
+          if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I))
+            if (!GV->isDeclaration() && GV->isConstant())
+              RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
+      }
+      
+      g.markIncompleteNodes(DSGraph::MarkFormalArgs);
+      
+      // Remove any nodes made dead due to merging...
+      g.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
+    }
+
+    // GraphBuilder ctor for working on the globals graph
+    explicit GraphBuilder(DSGraph& g)
+      :G(g), FB(0)
+    {}
+
+    void mergeInGlobalInitializer(GlobalVariable *GV);
+  };
+}
 
 //===----------------------------------------------------------------------===//
 // Helper method implementations...
@@ -265,10 +187,10 @@
 ///
 DSNodeHandle GraphBuilder::getValueDest(Value &Val) {
   Value *V = &Val;
-  if (isa<Constant>(V) && cast<Constant>(V)->isNullValue())
+  if (isa<Constant>(V) && cast<Constant>(V)->isNullValue()) 
     return 0;  // Null doesn't point to anything, don't add to ScalarMap!
 
-  DSNodeHandle &NH = ScalarMap[V];
+  DSNodeHandle &NH = G.getNodeForValue(V);
   if (!NH.isNull())
     return NH;     // Already have a node?  Just return it...
 
@@ -289,20 +211,19 @@
           NH = createNode()->setUnknownNodeMarker();
       } else if (CE->getOpcode() == Instruction::GetElementPtr) {
         visitGetElementPtrInst(*CE);
-        DSScalarMap::iterator I = ScalarMap.find(CE);
-        assert(I != ScalarMap.end() && "GEP didn't get processed right?");
-        NH = I->second;
+        assert(G.hasNodeForValue(CE) && "GEP didn't get processed right?");
+        NH = G.getNodeForValue(CE);
       } else {
         // This returns a conservative unknown node for any unhandled ConstExpr
         return NH = createNode()->setUnknownNodeMarker();
       }
       if (NH.isNull()) {  // (getelementptr null, X) returns null
-        ScalarMap.erase(V);
+        G.eraseNodeForValue(V);
         return 0;
       }
       return NH;
     } else if (isa<UndefValue>(C)) {
-      ScalarMap.erase(V);
+      G.eraseNodeForValue(V);
       return 0;
     } else {
       assert(0 && "Unknown constant type!");
@@ -340,7 +261,7 @@
 /// merge the two destinations together.
 ///
 void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
-  ScalarMap[&V].mergeWith(NH);
+  G.getNodeForValue(&V).mergeWith(NH);
 }
 
 
@@ -348,73 +269,93 @@
 // Specific instruction type handler implementations...
 //
 
-/// Alloca & Malloc instruction implementation - Simply create a new memory
-/// object, pointing the scalar to it.
-///
-void GraphBuilder::handleAlloc(AllocationInst &AI, bool isHeap) {
-  DSNode *N = createNode();
-  if (isHeap)
-    N->setHeapNodeMarker();
-  else
-    N->setAllocaNodeMarker();
-  setDestTo(AI, N);
-}
-
 // PHINode - Make the scalar for the PHI node point to all of the things the
 // incoming values point to... which effectively causes them to be merged.
 //
 void GraphBuilder::visitPHINode(PHINode &PN) {
-  if (!isPointerType(PN.getType())) return; // Only pointer PHIs
+  if (!isa<PointerType>(PN.getType())) return; // Only pointer PHIs
 
-  DSNodeHandle &PNDest = ScalarMap[&PN];
+  DSNodeHandle &PNDest = G.getNodeForValue(&PN);
   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
     PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
 }
 
 void GraphBuilder::visitSelectInst(SelectInst &SI) {
-  if (!isPointerType(SI.getType())) return; // Only pointer Selects
+  if (!isa<PointerType>(SI.getType())) return; // Only pointer Selects
 
-  DSNodeHandle &Dest = ScalarMap[&SI];
+  DSNodeHandle &Dest = G.getNodeForValue(&SI);
   Dest.mergeWith(getValueDest(*SI.getOperand(1)));
   Dest.mergeWith(getValueDest(*SI.getOperand(2)));
 }
 
-void GraphBuilder::visitICmpInst(ICmpInst &SCI) {
-  if (!isPointerType(SCI.getOperand(0)->getType()) ||
-      isa<ConstantPointerNull>(SCI.getOperand(1))) return; // Only pointers
-  if(!IgnoreSetCC)
-    ScalarMap[SCI.getOperand(0)].mergeWith(getValueDest(*SCI.getOperand(1)));
+void GraphBuilder::visitLoadInst(LoadInst &LI) {
+  DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
+
+  // Make that the node is read from...
+  Ptr.getNode()->setReadMarker();
+
+  // Ensure a typerecord exists...
+  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
+
+  if (isa<PointerType>(LI.getType()))
+    setDestTo(LI, getLink(Ptr));
 }
 
-void GraphBuilder::visitFCmpInst(FCmpInst &SCI) {
-  if (!isPointerType(SCI.getOperand(0)->getType()) ||
-      isa<ConstantPointerNull>(SCI.getOperand(1))) return; // Only pointers
-  if(!IgnoreSetCC)
-    ScalarMap[SCI.getOperand(0)].mergeWith(getValueDest(*SCI.getOperand(1)));
+void GraphBuilder::visitStoreInst(StoreInst &SI) {
+  const Type *StoredTy = SI.getOperand(0)->getType();
+  DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
+  if (Dest.isNull()) return;
+
+  // Mark that the node is written to...
+  Dest.getNode()->setModifiedMarker();
+
+  // Ensure a type-record exists...
+  Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());
+
+  // Avoid adding edges from null, or processing non-"pointer" stores
+  if (isa<PointerType>(StoredTy))
+    Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
 }
 
+void GraphBuilder::visitReturnInst(ReturnInst &RI) {
+  if (RI.getNumOperands() && isa<PointerType>(RI.getOperand(0)->getType()))
+    G.getOrCreateReturnNodeFor(*FB).mergeWith(getValueDest(*RI.getOperand(0)));
+}
 
-void GraphBuilder::visitGetElementPtrInst(User &GEP) {
+void GraphBuilder::visitVAArgInst(VAArgInst &I) {
+  //FIXME: also updates the argument
+  DSNodeHandle Ptr = getValueDest(*I.getOperand(0));
+  if (Ptr.isNull()) return;
 
-#ifdef LLVA_KERNEL
-#if 1
-  int debug = 0;
-  if (isa<Instruction>(GEP)) {
-    Instruction * IGEP = (Instruction *)(&GEP);
-    if (IGEP->getParent()->getParent()->getName() == "alloc_vfsmnt")
-    {
-#if 0
-      if (G.getPoolDescriptorsMap().count(N) != 0)
-        if (G.getPoolDescriptorsMap()[N])
-  std::cerr << "LLVA: GEP[" << count << "]: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[N]->getMetaPoolValue()->getName() << "\n";
-#else
-    debug = 1;
-#endif
-    }
-  }
-#endif
-#endif
+  // Make that the node is read and written
+  Ptr.getNode()->setReadMarker()->setModifiedMarker();
+
+  // Ensure a type record exists.
+  DSNode *PtrN = Ptr.getNode();
+  PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset(), false);
+
+  if (isa<PointerType>(I.getType()))
+    setDestTo(I, getLink(Ptr));
+}
 
+void GraphBuilder::visitIntToPtrInst(IntToPtrInst &I) {
+  setDestTo(I, createNode()->setUnknownNodeMarker()); //->setIntToPtrMarker()); 
+}
+
+void GraphBuilder::visitPtrToIntInst(PtrToIntInst& I) {
+//   if (DSNode* N = getValueDest(*I.getOperand(0)).getNode())
+//     N->setPtrToIntMarker();
+}
+
+
+void GraphBuilder::visitBitCastInst(BitCastInst &I) {
+  if (!isa<PointerType>(I.getType())) return; // Only pointers
+  DSNodeHandle Ptr = getValueDest(*I.getOperand(0));
+  if (Ptr.isNull()) return;
+  setDestTo(I, Ptr);
+}
+
+void GraphBuilder::visitGetElementPtrInst(User &GEP) {
   DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
   if (Value.isNull())
     Value = createNode();
@@ -434,11 +375,6 @@
   if (AllZeros || (!Value.isNull() &&
                    Value.getNode()->isNodeCompletelyFolded())) {
     setDestTo(GEP, Value);
-#if 0
-if (debug) std::cerr << "LLVA: GEP: All Zeros\n";
-  if (G.getPoolDescriptorsMap()[Value.getNode()])
-    std::cerr << "LLVA: GEP: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[Value.getNode()]->getName() << "\n";
-#endif
     return;
   }
 
@@ -570,74 +506,6 @@
 
 }
 
-void GraphBuilder::visitLoadInst(LoadInst &LI) {
-  DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
-  if (Ptr.isNull())
-    Ptr = createNode();
-
-  // Make that the node is read from...
-  Ptr.getNode()->setReadMarker();
-
-  // Ensure a typerecord exists...
-  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
-
-  if (isPointerType(LI.getType()))
-    setDestTo(LI, getLink(Ptr));
-#if 0
-  if (G.getPoolDescriptorsMap()[getLink(Ptr).getNode()])
-    std::cerr << "LLVA: Load: Pool for " << LI.getName() << " is " << G.getPoolDescriptorsMap()[getLink(Ptr).getNode()]->getName() << "\n";
-#endif
-}
-
-void GraphBuilder::visitStoreInst(StoreInst &SI) {
-  const Type *StoredTy = SI.getOperand(0)->getType();
-  DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
-  if (Dest.isNull()) return;
-
-  // Mark that the node is written to...
-  Dest.getNode()->setModifiedMarker();
-
-  // Ensure a type-record exists...
-  Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());
-
-  // Avoid adding edges from null, or processing non-"pointer" stores
-  if (isPointerType(StoredTy))
-    Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
-#ifdef LLVA_KERNEL
-#if 1
-  {
-    if (SI.getParent()->getParent()->getName() == "alloc_vfsmnt") {
-      DSNode * N = getValueDest(*SI.getOperand(1)).getNode();
-      if (G.getPoolDescriptorsMap().count(N) != 0)
-        if (G.getPoolDescriptorsMap()[N])
-          std::cerr << "LLVA: Store: Pool for " << SI.getName() << " is " << G.getPoolDescriptorsMap()[N]->getName() << "\n";
-    }
-  }
-#endif
-#endif
-}
-
-void GraphBuilder::visitReturnInst(ReturnInst &RI) {
-  if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()))
-    RetNode->mergeWith(getValueDest(*RI.getOperand(0)));
-}
-
-void GraphBuilder::visitVAArgInst(VAArgInst &I) {
-  //FIXME: also updates the argument
-  DSNodeHandle Ptr = getValueDest(*I.getOperand(0));
-  if (Ptr.isNull()) return;
-
-  // Make that the node is read from.
-  Ptr.getNode()->setReadMarker();
-
-  // Ensure a type record exists.
-  DSNode *PtrN = Ptr.getNode();
-  PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset(), false);
-
-  if (isPointerType(I.getType()))
-    setDestTo(I, getLink(Ptr));
-}
-
 
 void GraphBuilder::visitCallInst(CallInst &CI) {
   visitCallSite(&CI);
@@ -730,7 +598,7 @@
     // These functions read all of their pointer operands.
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI) {
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
     }
@@ -748,7 +616,7 @@
     // These functions write all of their pointer operands.
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI) {
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setModifiedMarker();
     }
@@ -757,7 +625,7 @@
              F->getName() == "lstat") {
     // These functions read their first operand if its a pointer.
     CallSite::arg_iterator AI = CS.arg_begin();
-    if (isPointerType((*AI)->getType())) {
+    if (isa<PointerType>((*AI)->getType())) {
       DSNodeHandle Path = getValueDest(**AI);
       if (DSNode *N = Path.getNode()) N->setReadMarker();
     }
@@ -793,7 +661,7 @@
     // These functions read all of their pointer operands.
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI)
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
 
@@ -903,7 +771,7 @@
     // Any pointer arguments are read.
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI)
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
     return true;
@@ -922,7 +790,7 @@
     // Any pointer arguments are read.
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI)
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker()->setModifiedMarker();
     return true;
@@ -953,7 +821,7 @@
     
     for (; AI != E; ++AI) {
       // printf reads all pointer arguments.
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
     }
@@ -986,14 +854,14 @@
     
     // Read the format
     if (AI != E) {
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
       ++AI;
     }
     
     // Read the valist, and the pointed-to objects.
-    if (AI != E && isPointerType((*AI)->getType())) {
+    if (AI != E && isa<PointerType>((*AI)->getType())) {
       const DSNodeHandle &VAList = getValueDest(**AI);
       if (DSNode *N = VAList.getNode()) {
         N->setReadMarker();
@@ -1033,7 +901,7 @@
     
     for (; AI != E; ++AI) {
       // scanf writes all pointer arguments.
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setModifiedMarker();
     }
@@ -1068,7 +936,7 @@
     
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI)
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
     
@@ -1078,7 +946,7 @@
   } else if (F->getName() == "__assert_fail") {
     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
          AI != E; ++AI)
-      if (isPointerType((*AI)->getType()))
+      if (isa<PointerType>((*AI)->getType()))
         if (DSNode *N = getValueDest(**AI).getNode())
           N->setReadMarker();
     return true;
@@ -1269,167 +1137,7 @@
   Value *Callee = CS.getCalledValue();
 
   // Special case handling of certain libc allocation functions here.
-  if (Function *F = dyn_cast<Function>(Callee)) {
-#ifdef LLVA_KERNEL    
-    if (F->getName() == "kmem_cache_alloc") {
-      DEBUG(std::cerr << "LLVA: kmem_cache_alloc" << std::endl);
-      // Update the statistics count
-      ++CacheAllocs;
-      
-      // Create a new DSNode for this memory allocation
-      DSNode *N = createNode();
-      N->setHeapNodeMarker();
-      setDestTo(*CS.getInstruction(), N);
-
-      // Get the pool handle
-      if (CS.arg_begin() == CS.arg_end()) {
-        abort(); //Handle this later
-        // Treat it as  a kmalloc
-        N->foldNodeCompletely();
-        //This becomes a kmalloc pool
-        MetaPoolHandle* mpvh = new MetaPoolHandle(new MetaPool(KMallocPool));
-        G.getPoolDescriptorsMap()[N] = mpvh;
-      } else {
-        Value *actualPD = *(CS.arg_begin());
-        if (!isa<GlobalValue>(actualPD)) {
-          std::cerr << "WARNING: Pool is not global.  Function = " << CS.getCaller()->getName() << "\n";
-        } else {
-          ++GlobalPools;
-        }
-        Value *TheMetaPool = actualPD;
-        //Get the Module first
-        Module * M = F->getParent();
-        if (G.getPoolDescriptorsMap().count(N)== 0) {
-          //Here we insert a global meta pool
-          //Now create a meta pool for this value, DSN Node
-          const Type * VoidPtrType = PointerType::get(Type::Int8Ty);              
-          TheMetaPool = new GlobalVariable(
-                                           /*type=*/ VoidPtrType,
-                                           /*isConstant=*/ false,
-                                           /*Linkage=*/ GlobalValue::InternalLinkage,
-                                           /*initializer=*/ Constant::getNullValue(VoidPtrType),
-                                           /*name=*/ "_metaPool_",
-                                           /*parent=*/ M );
-          //Inserted a global meta pool 
-        }
-#if 1
-        else {
-          // Lookup the meta pool
-          TheMetaPool = G.getPoolForNode(N)->getMetaPoolValue();
-        }
-#endif
-        //Now insert a function call that takes care of adding this pool to the global pool
-        
-        //First get the Insert point
-        Instruction *InsertPoint = CS.getInstruction();
-        
-        //Assumes AddPoolDescToMetaPool is in the module
-        const Type * VoidPtrType = PointerType::get(Type::Int8Ty);
-        const Type * VoidPtrPtrType = PointerType::get(VoidPtrType);
-        CastInst *CastMetaPool = 
-          CastInst::createPointerCast (TheMetaPool, 
-                       VoidPtrPtrType, "metapool.casted", InsertPoint);
-        CastInst *CastActualPD = 
-          CastInst::createPointerCast (actualPD, 
-                       PointerType::get(Type::Int8Ty), "poolhandle.lscasted", InsertPoint);
-        
-        // Create the call to AddPoolDescToMetaPool 
-        std::vector<Value *> args(1,CastMetaPool);
-        args.push_back(CastActualPD);
-
-        //Get the AddPoolDescToMetaPool function from the module
-        //FIXME optimize it by getting it once per module 
-        std::vector<const Type *> Arg(1, VoidPtrPtrType);
-        Arg.push_back(VoidPtrType);
-        FunctionType *AddPoolDescToMetaPoolTy =
-          FunctionType::get(Type::VoidTy,Arg, false);
-        Function *AddPoolDescToMetaPool = M->getOrInsertFunction("AddPoolDescToMetaPool", AddPoolDescToMetaPoolTy);
-
-        
-        new CallInst(AddPoolDescToMetaPool,args,"", InsertPoint);
-#if 0
-        MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(TheMetaPool));
-#else
-        MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(TheMetaPool), CS.getInstruction());
-#endif
-        G.getPoolDescriptorsMap()[N] = tmpvh;
-      }
-      return;
-    } else if (F->getName() == "poolalloc") {
-      if (CS.getCaller()->getName() == "kmem_cache_alloc")
-        return;
-      // Update the statistics
-      ++KMallocs;
-      
-      // Create a DSNode for the memory allocated by this function call
-      DSNode *N = createNode();
-      N->setHeapNodeMarker();
-      setDestTo(*CS.getInstruction(), N);
-      
-      // Get the pool handle, if possible
-      if (CS.arg_begin() == CS.arg_end()) {
-        abort() ; //Handle this later
-        // Treat it as kmalloc
-        N->foldNodeCompletely();
-        //This becomes a kmalloc pool
-        //So get the kmalloc pool
-        MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(KMallocPool));
-        G.getPoolDescriptorsMap()[N] = tmpvh;
-      } else {
-        Value *actualPD = *(CS.arg_begin());
-        if (!isa<GlobalValue>(actualPD)) {
-          std::cerr << "WARNING: Pool is not global.  Function = " << CS.getCaller()->getName() << "\n";
-        } else {
-          ++GlobalPools;
-        }
-        Value *TheMetaPool = actualPD;
-        Module * M = F->getParent();
-        if (G.getPoolDescriptorsMap().count(N)== 0) {
-          //Here we insert a global meta pool
-          //Get the Module first
-          //Now create a meta pool for this value, DSN Node
-          const Type * VoidPtrType = PointerType::get(Type::Int8Ty);              
-          TheMetaPool = new GlobalVariable(
-                                           /*type=*/ VoidPtrType,
-                                           /*isConstant=*/ false,
-                                           /*Linkage=*/ GlobalValue::InternalLinkage,
-                                           /*initializer=*/ Constant::getNullValue(VoidPtrType),
-                                           /*name=*/ "_metaPool_",
-                                           /*parent=*/ M );
-          //Inserted a global meta pool 
-        }
-        //Now insert a function call that takes care of adding this pool to the global pool
-        //First get the Insert point
-        Instruction *InsertPoint = CS.getInstruction();
-        
-        //Assumes AddPoolDescToMetaPool is in the module
-        const Type * VoidPtrType = PointerType::get(Type::Int8Ty);
-        const Type * VoidPtrPtrType = PointerType::get(VoidPtrType);
-        CastInst *CastMetaPool = 
-          CastInst::createPointerCast (TheMetaPool, 
-                       VoidPtrPtrType, "metapool.casted", InsertPoint);
-        CastInst *CastActualPD = 
-          CastInst::createPointerCast (actualPD, 
-                       PointerType::get(Type::Int8Ty), "poolhandle.lscasted", InsertPoint);
-        
-        // Create the call to AddPoolDescToMetaPool 
-        std::vector<Value *> args(1,CastMetaPool);
-        args.push_back(CastActualPD);
-
-        //FIXME optimize it by getting it once per module 
-        std::vector<const Type *> Arg(1, VoidPtrPtrType);
-        Arg.push_back(VoidPtrType);
-        FunctionType *AddPoolDescToMetaPoolTy =
-          FunctionType::get(Type::VoidTy,Arg, false);
-        Function *AddPoolDescToMetaPool = M->getOrInsertFunction("AddPoolDescToMetaPool", AddPoolDescToMetaPoolTy);
-        
-        new CallInst(AddPoolDescToMetaPool,args,"", InsertPoint);
-        MetaPoolHandle* tmpvh = new MetaPoolHandle(new MetaPool(TheMetaPool));
-        G.getPoolDescriptorsMap()[N] = tmpvh;
-      }
-      return;
-    }
-#endif
+  if (Function *F = dyn_cast<Function>(Callee))
     if (F->isDeclaration())
       if (F->isIntrinsic() && visitIntrinsic(CS, F))
         return;
@@ -1457,11 +1165,11 @@
 
         // Unknown function, warn if it returns a pointer type or takes a
         // pointer argument.
-        bool Warn = isPointerType(CS.getInstruction()->getType());
+        bool Warn = isa<PointerType>(CS.getInstruction()->getType());
         if (!Warn)
           for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
                I != E; ++I)
-            if (isPointerType((*I)->getType())) {
+            if (isa<PointerType>((*I)->getType())) {
               Warn = true;
               break;
             }
@@ -1470,16 +1178,15 @@
                << F->getName() << "' will cause pessimistic results!\n";
         }
       }
-  }
 
   // Set up the return value...
   DSNodeHandle RetVal;
   Instruction *I = CS.getInstruction();
-  if (isPointerType(I->getType()))
+  if (isa<PointerType>(I->getType()))
     RetVal = getValueDest(*I);
 
   DSNode *CalleeNode = 0;
-  if (DisableDirectCallOpt || !isa<Function>(Callee)) {
+  if (!isa<Function>(Callee)) {
     CalleeNode = getValueDest(*Callee).getNode();
     if (CalleeNode == 0) {
       cerr << "WARNING: Program is calling through a null pointer?\n"<< *I;
@@ -1492,58 +1199,26 @@
 
   // Calculate the arguments vector...
   for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
-    if (isPointerType((*I)->getType()))
+    if (isa<PointerType>((*I)->getType()))
       Args.push_back(getValueDest(**I));
 
   // Add a new function call entry...
   if (CalleeNode)
-    FunctionCalls->push_back(DSCallSite(CS, RetVal, CalleeNode, Args));
+    G.getFunctionCalls().push_back(DSCallSite(CS, RetVal, CalleeNode, Args));
   else
-    FunctionCalls->push_back(DSCallSite(CS, RetVal, cast<Function>(Callee),
-                                        Args));
+    G.getFunctionCalls().push_back(DSCallSite(CS, RetVal, cast<Function>(Callee),
+                                              Args));
 }
 
-void GraphBuilder::visitFreeInst(FreeInst &FI) {
-  // Mark that the node is written to...
-  if (DSNode *N = getValueDest(*FI.getOperand(0)).getNode())
-    N->setModifiedMarker()->setHeapNodeMarker();
-}
-
-/// Handle casts...
-void GraphBuilder::visitCastInst(CastInst &CI) {
-  // Pointers can only be cast with BitCast so check that the instruction
-  // is a BitConvert. If not, its guaranteed not to involve any pointers so
-  // we don't do anything.
-  switch (CI.getOpcode()) {
-  default: break;
-  case Instruction::BitCast:
-  case Instruction::IntToPtr:
-    if (isPointerType(CI.getType()))
-      if (isPointerType(CI.getOperand(0)->getType())) {
-        DSNodeHandle Ptr = getValueDest(*CI.getOperand(0));
-        if (Ptr.getNode() == 0) return;
-        // Cast one pointer to the other, just act like a copy instruction
-        setDestTo(CI, Ptr);
-      } else {
-        // Cast something (floating point, small integer) to a pointer.  We 
-        // need to track the fact that the node points to SOMETHING, just 
-        // something we don't know about.  Make an "Unknown" node.
-        setDestTo(CI, createNode()->setUnknownNodeMarker());
-      }
-    break;
-  }
-}
-
-
 // visitInstruction - For all other instruction types, if we have any arguments
 // that are of pointer type, make them have unknown composition bits, and merge
 // the nodes together.
 void GraphBuilder::visitInstruction(Instruction &Inst) {
   DSNodeHandle CurNode;
-  if (isPointerType(Inst.getType()))
+  if (isa<PointerType>(Inst.getType()))
     CurNode = getValueDest(Inst);
   for (User::op_iterator I = Inst.op_begin(), E = Inst.op_end(); I != E; ++I)
-    if (isPointerType((*I)->getType()))
+    if (isa<PointerType>((*I)->getType()))
       CurNode.mergeWith(getValueDest(**I));
 
   if (DSNode *N = CurNode.getNode())
@@ -1564,7 +1239,7 @@
   NHN->mergeTypeInfo(C->getType(), NH.getOffset());
 
   if (C->getType()->isFirstClassType()) {
-    if (isPointerType(C->getType()))
+    if (isa<PointerType>(C->getType()))
       // Avoid adding edges from null, or processing non-"pointer" stores
       NH.addEdgeTo(getValueDest(*C));
     return;
@@ -1606,93 +1281,11 @@
 }
 
 
-/// BuildGlobalECs - Look at all of the nodes in the globals graph.  If any node
-/// contains multiple globals, DSA will never, ever, be able to tell the globals
-/// 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.
-static void BuildGlobalECs(DSGraph &GG, std::set<GlobalValue*> &ECGlobals) {
-  DSScalarMap &SM = GG.getScalarMap();
-  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
-  for (DSGraph::node_iterator I = GG.node_begin(), E = GG.node_end();
-       I != E; ++I) {
-    if (I->getGlobalsList().size() <= 1) continue;
-
-    // First, build up the equivalence set for this block of globals.
-    const std::vector<GlobalValue*> &GVs = I->getGlobalsList();
-    GlobalValue *First = GVs[0];
-    for (unsigned i = 1, e = GVs.size(); i != e; ++i)
-      GlobalECs.unionSets(First, GVs[i]);
-
-    // Next, get the leader element.
-    assert(First == GlobalECs.getLeaderValue(First) &&
-           "First did not end up being the leader?");
-
-    // Next, remove all globals from the scalar map that are not the leader.
-    assert(GVs[0] == First && "First had to be at the front!");
-    for (unsigned i = 1, e = GVs.size(); i != e; ++i) {
-      ECGlobals.insert(GVs[i]);
-      SM.erase(SM.find(GVs[i]));
-    }
-
-    // Finally, change the global node to only contain the leader.
-    I->clearGlobals();
-    I->addGlobal(First);
-  }
-
-  DEBUG(GG.AssertGraphOK());
-}
-
-/// EliminateUsesOfECGlobals - Once we have determined that some globals are in
-/// really just equivalent to some other globals, remove the globals from the
-/// specified DSGraph (if present), and merge any nodes with their leader nodes.
-static void EliminateUsesOfECGlobals(DSGraph &G,
-                                     const std::set<GlobalValue*> &ECGlobals) {
-  DSScalarMap &SM = G.getScalarMap();
-  EquivalenceClasses<GlobalValue*> &GlobalECs = SM.getGlobalECs();
-
-  bool MadeChange = false;
-  for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
-       GI != E; ) {
-    GlobalValue *GV = *GI++;
-    if (!ECGlobals.count(GV)) continue;
-
-    const DSNodeHandle &GVNH = SM[GV];
-    assert(!GVNH.isNull() && "Global has null NH!?");
-
-    // Okay, this global is in some equivalence class.  Start by finding the
-    // leader of the class.
-    GlobalValue *Leader = GlobalECs.getLeaderValue(GV);
-
-    // If the leader isn't already in the graph, insert it into the node
-    // corresponding to GV.
-    if (!SM.global_count(Leader)) {
-      GVNH.getNode()->addGlobal(Leader);
-      SM[Leader] = GVNH;
-    } else {
-      // Otherwise, the leader is in the graph, make sure the nodes are the
-      // merged in the specified graph.
-      const DSNodeHandle &LNH = SM[Leader];
-      if (LNH.getNode() != GVNH.getNode())
-        LNH.mergeWith(GVNH);
-    }
-
-    // Next step, remove the global from the DSNode.
-    GVNH.getNode()->removeGlobal(GV);
-
-    // Finally, remove the global from the ScalarMap.
-    SM.erase(GV);
-    MadeChange = true;
-  }
-
-  DEBUG(if(MadeChange) G.AssertGraphOK());
-}
-
 bool LocalDataStructures::runOnModule(Module &M) {
-  const TargetData &TD = getAnalysis<TargetData>();
+  setTargetData(getAnalysis<TargetData>());
 
   // First step, build the globals graph.
-  GlobalsGraph = new DSGraph(GlobalECs, TD);
+  GlobalsGraph = new DSGraph(GlobalECs, getTargetData());
   {
     GraphBuilder GGB(*GlobalsGraph);
 
@@ -1705,16 +1298,16 @@
 
   // Next step, iterate through the nodes in the globals graph, unioning
   // together the globals into equivalence classes.
-  std::set<GlobalValue*> ECGlobals;
-  BuildGlobalECs(*GlobalsGraph, ECGlobals);
-  DOUT << "Eliminating " << ECGlobals.size() << " EC Globals!\n";
-  ECGlobals.clear();
+  formGlobalECs();
 
   // Calculate all of the graphs...
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration())
-      DSInfo.insert(std::make_pair(I, new DSGraph(GlobalECs, TD, *I,
-                                                  GlobalsGraph)));
+    if (!I->isDeclaration()) {
+      DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
+      GraphBuilder GGB(*I, *G);
+      DSInfo.insert(std::make_pair(I, G));
+    }
+
   GlobalsGraph->removeTriviallyDeadNodes();
   GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
 
@@ -1722,13 +1315,7 @@
   // the globals graph, see if we have further constrained the globals in the
   // program if so, update GlobalECs and remove the extraneous globals from the
   // program.
-  BuildGlobalECs(*GlobalsGraph, ECGlobals);
-  if (!ECGlobals.empty()) {
-    DOUT << "Eliminating " << ECGlobals.size() << " EC Globals!\n";
-    for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-           E = DSInfo.end(); I != E; ++I)
-      EliminateUsesOfECGlobals(*I->second, ECGlobals);
-  }
+  formGlobalECs();
 
   return false;
 }


Index: llvm-poolalloc/lib/DSA/Steensgaard.cpp
diff -u llvm-poolalloc/lib/DSA/Steensgaard.cpp:1.69 llvm-poolalloc/lib/DSA/Steensgaard.cpp:1.70
--- llvm-poolalloc/lib/DSA/Steensgaard.cpp:1.69	Fri Feb 23 16:49:32 2007
+++ llvm-poolalloc/lib/DSA/Steensgaard.cpp	Wed Apr 11 12:37:43 2007
@@ -28,7 +28,6 @@
     DSGraph *ResultGraph;
 
     EquivalenceClasses<GlobalValue*> GlobalECs;  // Always empty
-    PoolDescriptorMapType PoolDescriptors; 
   public:
     Steens() : ResultGraph(0) {}
     ~Steens() {


Index: llvm-poolalloc/lib/DSA/TopDownClosure.cpp
diff -u llvm-poolalloc/lib/DSA/TopDownClosure.cpp:1.98 llvm-poolalloc/lib/DSA/TopDownClosure.cpp:1.99
--- llvm-poolalloc/lib/DSA/TopDownClosure.cpp:1.98	Fri Feb 23 16:49:32 2007
+++ llvm-poolalloc/lib/DSA/TopDownClosure.cpp	Wed Apr 11 12:37:43 2007
@@ -33,7 +33,7 @@
 
 namespace {
   RegisterPass<TDDataStructures>   // Register the pass
-  Y("tddatastructure", "Top-down Data Structure Analysis");
+  Y("dsa-td", "Top-down Data Structure Analysis");
 
   STATISTIC (NumTDInlines, "Number of graphs inlined");
 }






More information about the llvm-commits mailing list