diff --git a/poolalloc/lib/rDSA/BottomUpClosure.cpp b/poolalloc/lib/rDSA/BottomUpClosure.cpp
deleted file mode 100644
index a1a48f9..0000000
--- a/poolalloc/lib/rDSA/BottomUpClosure.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-//===- BottomUpClosure.cpp - Compute bottom-up interprocedural closure ----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the BUDataStructures class, which represents the
-// Bottom-Up Interprocedural closure of the data structure graph over the
-// program.  This is useful for applications like pool allocation, but **not**
-// applications like alias analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "dsa-bu"
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FormattedStream.h"
-
-using namespace llvm;
-
-namespace {
-  STATISTIC (MaxSCC, "Maximum SCC Size in Call Graph");
-  STATISTIC (NumInlines, "Number of graphs inlined");
-  STATISTIC (NumCallEdges, "Number of 'actual' call edges");
-
-  RegisterPass<BUDataStructures>
-  X("dsa-bu", "Bottom-up Data Structure Analysis");
-}
-
-char BUDataStructures::ID;
-
-// run - Calculate the bottom up data structure graphs for each function in the
-// program.
-//
-bool BUDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<StdLibDataStructures>(), false, true, false, false );
-
-  return runOnModuleInternal(M);
-}
-
-bool BUDataStructures::runOnModuleInternal(Module& M) {
-  std::vector<const Function*> Stack;
-  hash_map<const Function*, unsigned> ValMap;
-  unsigned NextID = 1;
-
-  Function *MainFunc = M.getFunction("main");
-  if (MainFunc && !MainFunc->isDeclaration()) {
-    calculateGraphs(MainFunc, Stack, NextID, ValMap);
-    CloneAuxIntoGlobal(getDSGraph(MainFunc));
-  } else {
-    DEBUG(errs() << debugname << ": No 'main' function found!\n");
-  }
-
-  // Calculate the graphs for any functions that are unreachable from main...
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && !hasDSGraph(I)) {
-      if (MainFunc)
-        DEBUG(errs() << debugname << ": Function unreachable from main: "
-	      << I->getName() << "\n");
-      calculateGraphs(I, Stack, NextID, ValMap);     // Calculate all graphs.
-      CloneAuxIntoGlobal(getDSGraph(I));
-    }
-
-  // If we computed any temporary indcallgraphs, free them now.
-  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.
-    delete I->second.first;
-  }
-  IndCallGraphMap.clear();
-
-  // At the end of the bottom-up pass, the globals graph becomes complete.
-  // FIXME: This is not the right way to do this, but it is sorta better than
-  // nothing!  In particular, externally visible globals and unresolvable call
-  // nodes at the end of the BU phase should make things that they point to
-  // incomplete in the globals graph.
-  //
-
-  finalizeGlobals();
-
-  GlobalsGraph->removeTriviallyDeadNodes(true);
-  GlobalsGraph->maskIncompleteMarkers();
-
-  // Mark external globals incomplete.
-  GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
-
-  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
-  // the information about global pools and GV usage in the program.
-  if (MainFunc && !MainFunc->isDeclaration()) {
-    DSGraph* MainGraph = getDSGraph(MainFunc);
-    const DSGraph* GG = MainGraph->getGlobalsGraph();
-    ReachabilityCloner RC(MainGraph, GG,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-
-    // Clone the global nodes into this graph.
-    for (DSScalarMap::global_iterator I = GG->getScalarMap().global_begin(),
-           E = GG->getScalarMap().global_end(); I != E; ++I)
-      if (isa<GlobalVariable>(*I))
-        RC.getClonedNH(GG->getNodeForValue(*I));
-
-    MainGraph->maskIncompleteMarkers();
-    MainGraph->markIncompleteNodes(DSGraph::MarkFormalArgs |
-                                   DSGraph::IgnoreGlobals);
-  }
-
-  NumCallEdges += callee.size();
-
-  return false;
-}
-
-void BUDataStructures::finalizeGlobals(void) {
-  // Any unresolved call can be removed (resolved) if it does not contain
-  // external functions and it is not reachable from any call that does
-  // contain external functions
-  std::set<DSCallSite> GoodCalls, BadCalls;
-  for (DSGraph::afc_iterator ii = GlobalsGraph->afc_begin(), 
-         ee = GlobalsGraph->afc_end(); ii != ee; ++ii)
-    if (ii->isDirectCall() || ii->getCalleeNode()->NodeType.isExternFunctionNode())
-      BadCalls.insert(*ii);
-    else
-      GoodCalls.insert(*ii);
-  hash_set<const DSNode*> reachable;
-  for (std::set<DSCallSite>::iterator ii = BadCalls.begin(),
-         ee = BadCalls.end(); ii != ee; ++ii) {
-    ii->getRetVal().getNode()->markReachableNodes(reachable);
-    for (unsigned x = 0; x < ii->getNumPtrArgs(); ++x)
-      ii->getPtrArg(x).getNode()->markReachableNodes(reachable);
-  }
-  unsigned counter = 0;
-  for (std::set<DSCallSite>::iterator ii = GoodCalls.begin(),
-         ee = GoodCalls.end(); ii != ee; ++ii)
-    if (reachable.find(ii->getCalleeNode()) == reachable.end()) {
-      GlobalsGraph->getAuxFunctionCalls()
-        .erase(std::find(GlobalsGraph->getAuxFunctionCalls().begin(),
-                         GlobalsGraph->getAuxFunctionCalls().end(),
-                         *ii));
-      ++counter;
-    }
-  std::cerr << "Removed " << counter << " calls in finalizeGlobals\n";
-  GlobalsGraph->getScalarMap().clear_scalars();
-}
-
-static void GetAllCallees(const DSCallSite &CS,
-                          std::vector<const Function*> &Callees) {
-  if (CS.isDirectCall()) {
-    if (!CS.getCalleeFunc()->isDeclaration())
-      Callees.push_back(CS.getCalleeFunc());
-  } else if (!CS.getCalleeNode()->NodeType.isIncompleteNode()) {
-    // Get all callees.
-    if (!CS.getCalleeNode()->NodeType.isExternFunctionNode())
-      CS.getCalleeNode()->addFullFunctionList(Callees);
-  }
-}
-
-static void GetAnyCallees(const DSCallSite &CS,
-                          std::vector<const Function*> &Callees) {
-  if (CS.isDirectCall()) {
-    if (!CS.getCalleeFunc()->isDeclaration())
-      Callees.push_back(CS.getCalleeFunc());
-  } else {
-    // Get all callees.
-    unsigned OldSize = Callees.size();
-    CS.getCalleeNode()->addFullFunctionList(Callees);
-    
-    // If any of the callees are unresolvable, remove them
-    for (unsigned i = OldSize; i != Callees.size(); )
-      if (Callees[i]->isDeclaration()) {
-        Callees.erase(Callees.begin()+i);
-      } else 
-        ++i;
-  }
-}
-
-/// GetAllAuxCallees - Return a list containing all of the resolvable callees in
-/// the aux list for the specified graph in the Callees vector.
-static void GetAllAuxCallees(DSGraph* G, std::vector<const Function*> &Callees) {
-  Callees.clear();
-  for (DSGraph::afc_iterator I = G->afc_begin(), E = G->afc_end(); I != E; ++I)
-    GetAllCallees(*I, Callees);
-}
-
-/*
-/// 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<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(const Function *F,
-                                           std::vector<const Function*> &Stack,
-                                           unsigned &NextID,
-                                           hash_map<const Function*, unsigned> &ValMap) {
-  assert(!ValMap.count(F) && "Shouldn't revisit functions!");
-  unsigned Min = NextID++, MyID = Min;
-  ValMap[F] = Min;
-  Stack.push_back(F);
-
-  // FIXME!  This test should be generalized to be any function that we have
-  // already processed, in the case when there isn't a main or there are
-  // unreachable functions!
-  if (F->isDeclaration()) {   // sprintf, fprintf, sscanf, etc...
-    // No callees!
-    Stack.pop_back();
-    ValMap[F] = ~0;
-    return Min;
-  }
-
-  DSGraph* Graph = getOrFetchDSGraph(F);
-
-  // Find all callee functions.
-  std::vector<const Function*> CalleeFunctions;
-  GetAllAuxCallees(Graph, CalleeFunctions);
-  std::sort(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) {
-    const Function *Callee = CalleeFunctions[i];
-    unsigned M;
-    // Have we visited the destination function yet?
-    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.
-      M = It->second;
-    if (M < Min) Min = M;
-  }
-
-  assert(ValMap[F] == MyID && "SCC construction assumption wrong!");
-  if (Min != MyID)
-    return Min;         // This is part of a larger SCC!
-
-  // If this is a new SCC, process it now.
-  if (Stack.back() == F) {           // Special case the single "SCC" case here.
-    DEBUG(errs() << "Visiting single node SCC #: " << MyID << " fn: "
-	  << F->getName() << "\n");
-    Stack.pop_back();
-    DEBUG(errs() << "  [BU] Calculating graph for: " << F->getName()<< "\n");
-    calculateGraph(Graph);
-    DEBUG(errs() << "  [BU] Done inlining: " << F->getName() << " ["
-	  << Graph->getGraphSize() << "+" << Graph->getAuxFunctionCalls().size()
-	  << "]\n");
-
-    if (MaxSCC < 1) MaxSCC = 1;
-
-    // Should we revisit the graph?  Only do it if there are now new resolvable
-    // callees or new callees
-    GetAllAuxCallees(Graph, CalleeFunctions);
-    if (CalleeFunctions.size()) {
-      DEBUG(errs() << "Recalculating " << F->getName() << " due to new knowledge\n");
-      ValMap.erase(F);
-      return calculateGraphs(F, Stack, NextID, ValMap);
-    } else {
-      ValMap[F] = ~0U;
-      return MyID;
-    }
-  } else {
-    // SCCFunctions - Keep track of the functions in the current SCC
-    //
-    std::vector<DSGraph*> SCCGraphs;
-
-    unsigned SCCSize = 1;
-    const Function *NF = Stack.back();
-    ValMap[NF] = ~0U;
-    DSGraph* SCCGraph = getDSGraph(NF);
-
-    // First thing first, collapse all of the DSGraphs into a single graph for
-    // the entire SCC.  Splice all of the graphs into one and discard all of the
-    // old graphs.
-    //
-    while (NF != F) {
-      Stack.pop_back();
-      NF = Stack.back();
-      ValMap[NF] = ~0U;
-
-      DSGraph* NFG = getDSGraph(NF);
-
-      if (NFG != SCCGraph) {
-        // Update the Function -> DSG map.
-        for (DSGraph::retnodes_iterator I = NFG->retnodes_begin(),
-               E = NFG->retnodes_end(); I != E; ++I)
-          setDSGraph(I->first, SCCGraph);
-        
-        SCCGraph->spliceFrom(NFG);
-        delete NFG;
-        ++SCCSize;
-      }
-    }
-    Stack.pop_back();
-
-    DEBUG(errs() << "Calculating graph for SCC #: " << MyID << " of size: "
-	  << SCCSize << "\n");
-
-    // Compute the Max SCC Size.
-    if (MaxSCC < SCCSize)
-      MaxSCC = SCCSize;
-
-    // Clean up the graph before we start inlining a bunch again...
-    SCCGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-    // Now that we have one big happy family, resolve all of the call sites in
-    // the graph...
-    calculateGraph(SCCGraph);
-    DEBUG(errs() << "  [BU] Done inlining SCC  [" << SCCGraph->getGraphSize()
-	  << "+" << SCCGraph->getAuxFunctionCalls().size() << "]\n"
-	  << "DONE with SCC #: " << MyID << "\n");
-
-    // We never have to revisit "SCC" processed functions...
-    return MyID;
-  }
-
-  return MyID;  // == Min
-}
-
-void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) {
-  DSGraph* GG = G->getGlobalsGraph();
-  ReachabilityCloner RC(GG, G, 0);
-
-  for(DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end();
-      ii != ee; ++ii) {
-    //cerr << "Pushing " << ii->getCallSite().getInstruction()->getOperand(0) << "\n";
-    //If we can, merge with an existing call site for this instruction
-    if (GG->hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) {
-      DSGraph::afc_iterator GGii;
-      for(GGii = GG->afc_begin(); GGii != GG->afc_end(); ++GGii)
-        if (GGii->getCallSite().getInstruction()->getOperand(0) ==
-            ii->getCallSite().getInstruction()->getOperand(0))
-          break;
-      if (GGii != GG->afc_end())
-        RC.cloneCallSite(*ii).mergeWith(*GGii);
-      else
-        GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
-    } else {
-      GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
-    }
-  }
-}
-
-void BUDataStructures::calculateGraph(DSGraph* Graph) {
-  DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
-
-  // If this graph contains the main function, clone the globals graph into this
-  // graph before we inline callees and other fun stuff.
-  bool ContainsMain = false;
-  DSGraph::ReturnNodesTy &ReturnNodes = Graph->getReturnNodes();
-
-  for (DSGraph::ReturnNodesTy::iterator I = ReturnNodes.begin(),
-         E = ReturnNodes.end(); I != E; ++I)
-    if (I->first->hasExternalLinkage() && I->first->getName() == "main") {
-      ContainsMain = true;
-      break;
-    }
-
-  // If this graph contains main, copy the contents of the globals graph over.
-  // Note that this is *required* for correctness.  If a callee contains a use
-  // of a global, we have to make sure to link up nodes due to global-argument
-  // bindings.
-  if (ContainsMain || ReInlineGlobals) {
-    const DSGraph* GG = Graph->getGlobalsGraph();
-    ReachabilityCloner RC(Graph, GG,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-    if (ContainsMain) {
-      // Clone the global nodes into this graph.
-      for (DSScalarMap::global_iterator I = GG->getScalarMap().global_begin(),
-             E = GG->getScalarMap().global_end(); I != E; ++I)
-        if (isa<GlobalVariable>(*I))
-          RC.getClonedNH(GG->getNodeForValue(*I));
-    } else {
-      // Clone used the global nodes into this graph.
-      for (DSScalarMap::global_iterator I = Graph->getScalarMap().global_begin(),
-             E = Graph->getScalarMap().global_end(); I != E; ++I)
-        if (isa<GlobalVariable>(*I))
-          RC.getClonedNH(GG->getNodeForValue(*I));
-    }
-  }
-
-  // Move our call site list into TempFCs so that inline call sites go into the
-  // new call site list and doesn't invalidate our iterators!
-  std::list<DSCallSite> TempFCs;
-  std::list<DSCallSite> &AuxCallsList = Graph->getAuxFunctionCalls();
-  TempFCs.swap(AuxCallsList);
-
-  std::vector<const Function*> CalledFuncs;
-  while (!TempFCs.empty()) {
-    DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
-    
-    DSCallSite &CS = *TempFCs.begin();
-    Instruction *TheCall = CS.getCallSite().getInstruction();
-
-    CalledFuncs.clear();
-
-    GetAllCallees(CS, CalledFuncs);
-    bool isComplete = true;
-
-    if (CalledFuncs.empty()) {
-      // Remember that we could not resolve this yet!
-      isComplete = false;
-      GetAnyCallees(CS, CalledFuncs);
-      if (useCallGraph)
-        for (calleeTy::iterator ii = callee.begin(CS.getCallSite().getInstruction()),
-               ee = callee.end(CS.getCallSite().getInstruction()); ii != ee; ++ii)
-          CalledFuncs.push_back(*ii);
-      std::sort(CalledFuncs.begin(), CalledFuncs.end());
-      std::vector<const Function*>::iterator uid = std::unique(CalledFuncs.begin(), CalledFuncs.end());
-      CalledFuncs.resize(uid - CalledFuncs.begin());
-    }
-
-    DSGraph *GI;
-    
-    for (std::vector<const Function*>::iterator ii = CalledFuncs.begin(), ee = CalledFuncs.end();
-         ii != ee; ++ii) 
-      callee.add(TheCall, *ii);
-
-    if (CalledFuncs.size() == 1 && (isComplete || hasDSGraph(CalledFuncs[0]))) {
-      const Function *Callee = CalledFuncs[0];
-
-      // Get the data structure graph for the called function.
-      GI = getDSGraph(Callee);  // Graph to inline
-      DEBUG(GI->AssertGraphOK(); GI->getGlobalsGraph()->AssertGraphOK());
-      DEBUG(errs() << "    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|
-                          (isComplete?0:DSGraph::DontCloneAuxCallNodes));
-      ++NumInlines;
-      DEBUG(Graph->AssertGraphOK(););
-    } else if (CalledFuncs.size() > 1) {
-      DEBUG(errs() << "In Fns: " << Graph->getFunctionNames() << "\n");
-      DEBUG(errs() << "  calls " << CalledFuncs.size()
-            << " fns from site: " << CS.getCallSite().getInstruction()
-            << "  " << *CS.getCallSite().getInstruction());
-      DEBUG(errs() << "   Fns =");
-      unsigned NumPrinted = 0;
-      
-      for (std::vector<const Function*>::iterator I = CalledFuncs.begin(),
-             E = CalledFuncs.end(); I != E; ++I)
-        if (NumPrinted++ < 8) {
-	  DEBUG(errs() << " " << (*I)->getName());
-	}
-      DEBUG(errs() << "\n");
-      
-      if (!isComplete) {
-        for (unsigned x = 0; x < CalledFuncs.size(); )
-          if (!hasDSGraph(CalledFuncs[x]))
-            CalledFuncs.erase(CalledFuncs.begin() + x);
-          else
-            ++x;
-      }
-      if (CalledFuncs.size()) {
-        // See if we already computed a graph for this set of callees.
-        std::sort(CalledFuncs.begin(), CalledFuncs.end());
-        std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
-          IndCallGraphMap[CalledFuncs];
-        
-        if (IndCallGraph.first == 0) {
-          std::vector<const Function*>::iterator I = CalledFuncs.begin(),
-            E = CalledFuncs.end();
-          
-          // Start with a copy of the first graph.
-          GI = IndCallGraph.first = 
-	    new DSGraph(getDSGraph(*I), GlobalECs, Graph->getGlobalsGraph(), 0);
-          std::vector<DSNodeHandle> &Args = IndCallGraph.second;
-          
-          // Get the argument nodes for the first callee.  The return value is
-          // the 0th index in the vector.
-          GI->getFunctionArgumentsForCall(*I, Args);
-          
-          // Merge all of the other callees into this graph.
-          for (++I; I != E; ++I) {
-            // If the graph already contains the nodes for the function, don't
-            // bother merging it in again.
-            if (!GI->containsFunction(*I)) {
-              GI->cloneInto(getDSGraph(*I));
-              ++NumInlines;
-            }
-            
-            std::vector<DSNodeHandle> NextArgs;
-            GI->getFunctionArgumentsForCall(*I, NextArgs);
-            unsigned i = 0, e = Args.size();
-            for (; i != e; ++i) {
-              if (i == NextArgs.size()) break;
-              Args[i].mergeWith(NextArgs[i]);
-            }
-            for (e = NextArgs.size(); i != e; ++i)
-              Args.push_back(NextArgs[i]);
-          }
-          
-          // Clean up the final graph!
-          GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-        } else {
-          DEBUG(errs() << "***\n*** RECYCLED GRAPH ***\n***\n");
-        }
-        
-        GI = IndCallGraph.first;
-        
-        // Merge the unified graph into this graph now.
-        DEBUG(errs() << "    Inlining multi callee graph "
-	      << "[" << GI->getGraphSize() << "+"
-	      << GI->getAuxFunctionCalls().size() << "] into '"
-	      << Graph->getFunctionNames() << "' [" << Graph->getGraphSize() <<"+"
-	      << Graph->getAuxFunctionCalls().size() << "]\n");
-        
-        Graph->mergeInGraph(CS, IndCallGraph.second, *GI,
-                            DSGraph::StripAllocaBit |
-                            DSGraph::DontCloneCallNodes|
-                            (isComplete?0:DSGraph::DontCloneAuxCallNodes));
-        ++NumInlines;
-      }
-    }
-    DEBUG(Graph->AssertGraphOK(););
-    DEBUG(Graph->getGlobalsGraph()->AssertGraphOK());
-    if (!isComplete)
-      AuxCallsList.push_front(CS);
-    TempFCs.erase(TempFCs.begin());
-  }
-
-  // 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());
-}
-
diff --git a/poolalloc/lib/rDSA/CompleteBottomUp.cpp b/poolalloc/lib/rDSA/CompleteBottomUp.cpp
deleted file mode 100644
index f8e0b00..0000000
--- a/poolalloc/lib/rDSA/CompleteBottomUp.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-//===- CompleteBottomUp.cpp - Complete Bottom-Up Data Structure Graphs ----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the exact same as the bottom-up graphs, but we use take a completed
-// call graph and inline all indirect callees into their callers graphs, making
-// the result more useful for things like pool allocation.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "dsa-cbu"
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Debug.h"
-using namespace llvm;
-
-namespace {
-  RegisterPass<CompleteBUDataStructures>
-  X("dsa-cbu", "'Complete' Bottom-up Data Structure Analysis");
-}
-
-char CompleteBUDataStructures::ID;
-
-// run - Calculate the bottom up data structure graphs for each function in the
-// program.
-//
-bool CompleteBUDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<BUDataStructures>(), false, true, false, true);
-
-  buildIndirectFunctionSets(M);
-  formGlobalECs();
-
-  return runOnModuleInternal(M);
-}
-
-void CompleteBUDataStructures::buildIndirectFunctionSets(Module &M) {
-  // Loop over all of the indirect calls in the program.  If a call site can
-  // call multiple different functions, we need to unify all of the callees into
-  // the same equivalence class.
-  std::vector<const Instruction*> keys;
-  callee.get_keys(back_inserter(keys));
-
-  //mege nodes in the global graph for these functions
-  for (std::vector<const Instruction*>::iterator ii = keys.begin(), ee = keys.end();
-       ii != ee; ++ii) {
-    if (*ii) {
-      calleeTy::iterator csi = callee.begin(*ii), cse = callee.end(*ii); 
-      if (csi != cse) ++csi;
-      DSGraph* G = getOrFetchDSGraph((*ii)->getParent()->getParent());
-      for ( ; csi != cse; ++csi) {
-        G->getNodeForValue(*csi).mergeWith(G->getNodeForValue((*ii)->getOperand(0)));
-        G->getNodeForValue((*ii)->getOperand(0)).getNode()->NodeType.setGlobalNode();
-        G->getNodeForValue((*ii)->getOperand(0)).getNode()->addGlobal(*csi);
-      }
-    }
-  }
-}
diff --git a/poolalloc/lib/rDSA/DataStructure.cpp b/poolalloc/lib/rDSA/DataStructure.cpp
deleted file mode 100644
index a2a5e14..0000000
--- a/poolalloc/lib/rDSA/DataStructure.cpp
+++ /dev/null
@@ -1,2693 +0,0 @@
-//===- DataStructure.cpp - Implement the core data structure analysis -----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the core data structure functionality.
-//
-//===----------------------------------------------------------------------===//
-
-#include "rdsa/DSGraphTraits.h"
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "rdsa/DSSupport.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Instructions.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/DataLayout.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SCCIterator.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "poolalloc/ADT/HashExtras.h"
-
-#include <iostream>
-#include <algorithm>
-using namespace llvm;
-
-#define COLLAPSE_ARRAYS_AGGRESSIVELY 0
-namespace {
-  STATISTIC (NumFolds, "Number of nodes completely folded");
-  STATISTIC (NumCallNodesMerged, "Number of call nodes merged");
-  STATISTIC (NumNodeAllocated  , "Number of nodes allocated");
-  STATISTIC (NumDNE            , "Number of nodes removed by reachability");
-  STATISTIC (NumTrivialDNE     , "Number of nodes trivially removed");
-  STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed");
-  static cl::opt<unsigned>
-  DSAFieldLimit("dsa-field-limit", cl::Hidden,
-                cl::desc("Number of fields to track before collapsing a node"),
-                cl::init(256));
-}
-
-/// isForwarding - Return true if this NodeHandle is forwarding to another
-/// one.
-bool DSNodeHandle::isForwarding() const {
-  return N && N->isForwarding();
-}
-
-DSNode *DSNodeHandle::HandleForwarding() const {
-  assert(N->isForwarding() && "Can only be invoked if forwarding!");
-  DEBUG(
-        { //assert not looping
-          DSNode* NH = N;
-          std::set<DSNode*> seen;
-          while(NH && NH->isForwarding()) {
-            assert(seen.find(NH) == seen.end() && "Loop detected");
-            seen.insert(NH);
-            NH = NH->ForwardNH.N;
-          }
-        }
-        );
-  // Handle node forwarding here!
-  DSNode *Next = N->ForwardNH.getNode();  // Cause recursive shrinkage
-  Offset += N->ForwardNH.getOffset();
-
-  if (--N->NumReferrers == 0) {
-    // Removing the last referrer to the node, sever the forwarding link
-    N->stopForwarding();
-  }
-
-  N = Next;
-  N->NumReferrers++;
-  if (N->Size <= Offset) {
-    assert(N->Size <= 1 && "Forwarded to shrunk but not collapsed node?");
-    Offset = 0;
-  }
-  return N;
-}
-
-//===----------------------------------------------------------------------===//
-// DSScalarMap Implementation
-//===----------------------------------------------------------------------===//
-
-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<const GlobalValue*>::iterator ECI = GlobalECs.findValue(GV);
-  if (ECI != GlobalECs.end()) {
-    const GlobalValue *Leader = *GlobalECs.findLeader(ECI);
-    if (Leader != GV) {
-      GV = Leader;
-      iterator I = ValueMap.find(GV);
-      if (I != ValueMap.end())
-        return I->second;
-    }
-  }
-
-  // Okay, this is either not an equivalenced global or it is the leader, it
-  // will be inserted into the scalar map now.
-  GlobalSet.insert(GV);
-
-  return ValueMap.insert(std::make_pair(GV, DSNodeHandle())).first->second;
-}
-
-
-//===----------------------------------------------------------------------===//
-// DSNode Implementation
-//===----------------------------------------------------------------------===//
-
-DSNode::DSNode(const Type *T, DSGraph *G)
-  : NumReferrers(0), Size(0), ParentGraph(G), Ty(Type::getVoidTy(getGlobalContext())) {
-  // Add the type entry if it is specified...
-  if (T) mergeTypeInfo(T, 0);
-  if (G) G->addNode(this);
-  ++NumNodeAllocated;
-}
-
-// DSNode copy constructor... do not copy over the referrers list!
-DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks)
-  : NumReferrers(0), Size(N.Size), ParentGraph(G),
-    Ty(N.Ty), Globals(N.Globals), NodeType(N.NodeType) {
-  if (!NullLinks) {
-    Links = N.Links;
-  } else
-    Links.resize(N.Links.size()); // Create the appropriate number of null links
-  G->addNode(this);
-  ++NumNodeAllocated;
-}
-
-DSNode::~DSNode() {
-  dropAllReferences();
-  assert(hasNoReferrers() && "Referrers to dead node exist!");
-}
-
-/// getDataLayout - Get the target data object used to construct this node.
-///
-const DataLayout &DSNode::getDataLayout() const {
-  return ParentGraph->getDataLayout();
-}
-
-void DSNode::assertOK() const {
-  assert((Ty != Type::getVoidTy(getGlobalContext()) ||
-          (Ty == Type::getVoidTy(getGlobalContext()) 
-           && (Size == 0 || NodeType.isArrayNode()))) &&
-         "Node not OK!");
-
-  assert(ParentGraph && "Node has no parent?");
-  const DSScalarMap &SM = ParentGraph->getScalarMap();
-  for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
-    assert(SM.global_count(Globals[i]));
-    assert(SM.find(Globals[i])->second.getNode() == this);
-  }
-}
-
-/// forwardNode - Mark this node as being obsolete, and all references to it
-/// should be forwarded to the specified node and offset.
-///
-void DSNode::forwardNode(DSNode *To, unsigned Offset) {
-  assert(this != To && "Cannot forward a node to itself!");
-  assert(ForwardNH.isNull() && "Already forwarding from this node!");
-  if (To->Size <= 1) Offset = 0;
-  assert((Offset < To->Size || (Offset == To->Size && Offset == 0)) &&
-         "Forwarded offset is wrong!");
-  ForwardNH.setTo(To, Offset);
-  NodeType.setDeadNode();
-  Size = 0;
-  Ty = Type::getVoidTy(getGlobalContext());
-
-  // Remove this node from the parent graph's Nodes list.
-  ParentGraph->unlinkNode(this);
-  ParentGraph = 0;
-}
-
-// 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(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<const GlobalValue*>::iterator I =
-    std::lower_bound(Globals.begin(), Globals.end(), GV);
-
-  if (I == Globals.end() || *I != GV) {
-    Globals.insert(I, GV);
-    NodeType.setGlobalNode();
-  }
-}
-
-/// addFunction - Add an entry for a function value to the
-/// Functionss list.  This also marks the node with the 'F' flag if
-/// it does not already have it.
-///
-void DSNode::addFunction(const Function* FV) {
-  if (FV->isDeclaration())
-    NodeType.setExternFunctionNode();
-  else
-    NodeType.setFunctionNode();
-  addGlobal(FV);
-}
-
-// removeGlobal - Remove the specified global that is explicitly in the globals
-// list.
-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);
-}
-
-/// foldNodeCompletely - If we determine that this node has some funny
-/// behavior happening to it that we cannot represent, we fold it down to a
-/// single, completely pessimistic, node.  This node is represented as a
-/// single byte with a single TypeEntry of "void".
-///
-void DSNode::foldNodeCompletely() {
-  if (isNodeCompletelyFolded()) return;  // If this node is already folded...
-
-  ++NumFolds;
-
-  // If this node has a size that is <= 1, we don't need to create a forwarding
-  // node.
-  if (getSize() <= 1) {
-    NodeType.setArrayNode();
-    Ty = Type::getVoidTy(getGlobalContext());
-    Size = 1;
-    assert(Links.size() <= 1 && "Size is 1, but has more links?");
-    Links.resize(1);
-  } else {
-    // Create the node we are going to forward to.  This is required because
-    // some referrers may have an offset that is > 0.  By forcing them to
-    // forward, the forwarder has the opportunity to correct the offset.
-    DSNode *DestNode = new DSNode(0, ParentGraph);
-    DestNode->NodeType = NodeType;
-    DestNode->NodeType.setArrayNode();
-    DestNode->Ty = Type::getVoidTy(getGlobalContext());
-    DestNode->Size = 1;
-    DestNode->Globals.swap(Globals);
-    
-    // Start forwarding to the destination node...
-    forwardNode(DestNode, 0);
-
-
-    if (!Links.empty()) {
-      DestNode->Links.reserve(1);
-
-      DSNodeHandle NH(DestNode);
-      DestNode->Links.push_back(Links[0]);
-
-      // If we have links, merge all of our outgoing links together...
-      for (unsigned i = Links.size()-1; i != 0; --i)
-        NH.getNode()->Links[0].mergeWith(Links[i]);
-      Links.clear();
-    } else {
-      DestNode->Links.resize(1);
-    }
-  }
-}
-
-/// isNodeCompletelyFolded - Return true if this node has been completely
-/// folded down to something that can never be expanded, effectively losing
-/// all of the field sensitivity that may be present in the node.
-///
-bool DSNode::isNodeCompletelyFolded() const {
-  return getSize() == 1 && Ty == Type::getVoidTy(getGlobalContext()) && NodeType.isArrayNode();
-}
-
-/// 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<const GlobalValue*> &List) const {
-  if (globals_begin() == globals_end()) return;
-
-  EquivalenceClasses<const GlobalValue*> &EC = getParentGraph()->getGlobalECs();
-
-  for (globals_iterator I = globals_begin(), E = globals_end(); I != E; ++I) {
-    EquivalenceClasses<const GlobalValue*>::iterator ECI = EC.findValue(*I);
-    if (ECI == EC.end())
-      List.push_back(*I);
-    else
-      List.insert(List.end(), EC.member_begin(ECI), EC.member_end());
-  }
-}
-
-/// addFullFunctionList - Identical to addFullGlobalsList, but only return the
-/// functions in the full list.
-void DSNode::addFullFunctionList(std::vector<const Function*> &List) const {
-  if (globals_begin() == globals_end()) return;
-
-  EquivalenceClasses<const GlobalValue*> &EC = getParentGraph()->getGlobalECs();
-
-  for (globals_iterator I = globals_begin(), E = globals_end(); I != E; ++I) {
-    EquivalenceClasses<const GlobalValue*>::iterator ECI = EC.findValue(*I);
-    if (ECI == EC.end()) {
-      if (const Function *F = dyn_cast<Function>(*I))
-        List.push_back(F);
-    } else {
-      for (EquivalenceClasses<const GlobalValue*>::member_iterator MI =
-             EC.member_begin(ECI), E = EC.member_end(); MI != E; ++MI)
-        if (const Function *F = dyn_cast<Function>(*MI))
-          List.push_back(F);
-    }
-  }
-}
-
-namespace {
-  /// TypeElementWalker Class - Used for implementation of physical subtyping...
-  ///
-  class TypeElementWalker {
-    struct StackState {
-      const Type *Ty;
-      unsigned Offset;
-      unsigned Idx;
-      StackState(const Type *T, unsigned Off = 0)
-        : Ty(T), Offset(Off), Idx(0) {}
-    };
-
-    std::vector<StackState> Stack;
-    const DataLayout &TD;
-  public:
-    TypeElementWalker(const Type *T, const DataLayout &td) : TD(td) {
-      Stack.push_back(T);
-      StepToLeaf();
-    }
-
-    bool isDone() const { return Stack.empty(); }
-    const Type *getCurrentType()   const { return Stack.back().Ty;     }
-    unsigned    getCurrentOffset() const { return Stack.back().Offset; }
-
-    void StepToNextType() {
-      PopStackAndAdvance();
-      StepToLeaf();
-    }
-
-  private:
-    /// PopStackAndAdvance - Pop the current element off of the stack and
-    /// advance the underlying element to the next contained member.
-    void PopStackAndAdvance() {
-      assert(!Stack.empty() && "Cannot pop an empty stack!");
-      Stack.pop_back();
-      while (!Stack.empty()) {
-        StackState &SS = Stack.back();
-        if (const StructType *ST = dyn_cast<StructType>(SS.Ty)) {
-          ++SS.Idx;
-          if (SS.Idx != ST->getNumElements()) {
-            const StructLayout *SL = TD.getStructLayout(ST);
-            SS.Offset +=
-               unsigned(SL->getElementOffset(SS.Idx)-SL->getElementOffset(SS.Idx-1));
-            return;
-          }
-          Stack.pop_back();  // At the end of the structure
-        } else {
-          const ArrayType *AT = cast<ArrayType>(SS.Ty);
-          ++SS.Idx;
-          if (SS.Idx != AT->getNumElements()) {
-            SS.Offset += unsigned(TD.getTypeAllocSize(AT->getElementType()));
-            return;
-          }
-          Stack.pop_back();  // At the end of the array
-        }
-      }
-    }
-
-    /// StepToLeaf - Used by physical subtyping to move to the first leaf node
-    /// on the type stack.
-    void StepToLeaf() {
-      if (Stack.empty()) return;
-      while (!Stack.empty() && !Stack.back().Ty->isFirstClassType()) {
-        StackState &SS = Stack.back();
-        if (const StructType *ST = dyn_cast<StructType>(SS.Ty)) {
-          if (ST->getNumElements() == 0) {
-            assert(SS.Idx == 0);
-            PopStackAndAdvance();
-          } else {
-            // Step into the structure...
-            assert(SS.Idx < ST->getNumElements());
-            const StructLayout *SL = TD.getStructLayout(ST);
-            Stack.push_back(StackState(ST->getElementType(SS.Idx),
-                            SS.Offset+unsigned(SL->getElementOffset(SS.Idx))));
-          }
-        } else {
-          const ArrayType *AT = cast<ArrayType>(SS.Ty);
-          if (AT->getNumElements() == 0) {
-            assert(SS.Idx == 0);
-            PopStackAndAdvance();
-          } else {
-            // Step into the array...
-            assert(SS.Idx < AT->getNumElements());
-            Stack.push_back(StackState(AT->getElementType(),
-                                       SS.Offset+SS.Idx*
-                             unsigned(TD.getTypeAllocSize(AT->getElementType()))));
-          }
-        }
-      }
-    }
-  };
-} // end anonymous namespace
-
-/// ElementTypesAreCompatible - Check to see if the specified types are
-/// "physically" compatible.  If so, return true, else return false.  We only
-/// have to check the fields in T1: T2 may be larger than T1.  If AllowLargerT1
-/// is true, then we also allow a larger T1.
-///
-static bool ElementTypesAreCompatible(const Type *T1, const Type *T2,
-                                      bool AllowLargerT1, const DataLayout &TD){
-  TypeElementWalker T1W(T1, TD), T2W(T2, TD);
-
-  while (!T1W.isDone() && !T2W.isDone()) {
-    if (T1W.getCurrentOffset() != T2W.getCurrentOffset())
-      return false;
-
-    const Type *T1 = T1W.getCurrentType();
-    const Type *T2 = T2W.getCurrentType();
-    if (T1 != T2 && !T1->canLosslesslyBitCastTo(T2))
-      return false;
-
-    T1W.StepToNextType();
-    T2W.StepToNextType();
-  }
-
-  return AllowLargerT1 || T1W.isDone();
-}
-
-
-/// mergeTypeInfo - This method merges the specified type into the current node
-/// at the specified offset.  This may update the current node's type record if
-/// this gives more information to the node, it may do nothing to the node if
-/// this information is already known, or it may merge the node completely (and
-/// return true) if the information is incompatible with what is already known.
-///
-/// This method returns true if the node is completely folded, otherwise false.
-///
-bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset,
-                           bool FoldIfIncompatible) {
-  //DOUT << "merging " << *NewTy << " at " << Offset << " with " << *Ty << "\n";
-  const DataLayout &TD = getDataLayout();
-  // Check to make sure the Size member is up-to-date.  Size can be one of the
-  // following:
-  //  Size = 0, Ty = Void: Nothing is known about this node.
-  //  Size = 0, Ty = FnTy: FunctionPtr doesn't have a size, so we use zero
-  //  Size = 1, Ty = Void, Array = 1: The node is collapsed
-  //  Otherwise, sizeof(Ty) = Size
-  //
-  assert(((Size == 0 && Ty == Type::getVoidTy(getGlobalContext()) && !NodeType.isArrayNode()) ||
-          (Size == 0 && !Ty->isSized() && !NodeType.isArrayNode()) ||
-          (Size == 1 && Ty == Type::getVoidTy(getGlobalContext()) && NodeType.isArrayNode()) ||
-          (Size == 0 && !Ty->isSized() && !NodeType.isArrayNode()) ||
-          (TD.getTypeAllocSize(Ty) == Size)) &&
-         "Size member of DSNode doesn't match the type structure!");
-  assert(NewTy != Type::getVoidTy(getGlobalContext()) && "Cannot merge void type into DSNode!");
-
-  if (Offset == 0 && NewTy == Ty)
-    return false;  // This should be a common case, handle it efficiently
-
-  // Return true immediately if the node is completely folded.
-  if (isNodeCompletelyFolded()) return true;
-
-  // If this is an array type, eliminate the outside arrays because they won't
-  // be used anyway.  This greatly reduces the size of large static arrays used
-  // as global variables, for example.
-  //
-  bool WillBeArray = false;
-  while (const ArrayType *AT = dyn_cast<ArrayType>(NewTy)) {
-    // FIXME: we might want to keep small arrays, but must be careful about
-    // things like: [2 x [10000 x int*]]
-    NewTy = AT->getElementType();
-    WillBeArray = true;
-  }
-
-  // Figure out how big the new type we're merging in is...
-  unsigned NewTySize = NewTy->isSized() ? (unsigned)TD.getTypeAllocSize(NewTy) : 0;
-
-  // Otherwise check to see if we can fold this type into the current node.  If
-  // we can't, we fold the node completely, if we can, we potentially update our
-  // internal state.
-  //
-  if (Ty == Type::getVoidTy(getGlobalContext())) {
-    // If this is the first type that this node has seen, just accept it without
-    // question....
-    assert(Offset == 0 && !NodeType.isArrayNode() &&
-           "Cannot have an offset into a void node!");
-
-    // If this node would have to have an unreasonable number of fields, just
-    // collapse it.  This can occur for fortran common blocks, which have stupid
-    // things like { [100000000 x double], [1000000 x double] }.
-    unsigned NumFields = NewTySize;
-    if (NumFields > DSAFieldLimit) {
-      foldNodeCompletely();
-      return true;
-    }
-
-    Ty = NewTy;
-    NodeType.maskFlags(~DSFlags::ArrayNode);
-    if (WillBeArray) NodeType.setArrayNode();
-    Size = NewTySize;
-
-    // Calculate the number of outgoing links from this node.
-    Links.resize(NumFields);
-    return false;
-  }
-
-  // Handle node expansion case here...
-  if (Offset+NewTySize > Size) {
-    // It is illegal to grow this node if we have treated it as an array of
-    // objects...
-    if (NodeType.isArrayNode()) {
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-    }
-
-    // If this node would have to have an unreasonable number of fields, just
-    // collapse it.  This can occur for fortran common blocks, which have stupid
-    // things like { [100000000 x double], [1000000 x double] }.
-    unsigned NumFields = NewTySize+Offset;
-    if (NumFields > DSAFieldLimit) {
-      foldNodeCompletely();
-      return true;
-    }
-
-    if (Offset) {
-      //handle some common cases:
-      // Ty:    struct { t1, t2, t3, t4, ..., tn}
-      // NewTy: struct { offset, stuff...}
-      // try merge with NewTy: struct {t1, t2, stuff...} if offset lands exactly
-      // on a field in Ty
-      if (isa<StructType>(NewTy) && isa<StructType>(Ty)) {
-        //DOUT << "Ty: " << *Ty << "\nNewTy: " << *NewTy << "@" << Offset << "\n";
-        const StructType *STy = cast<StructType>(Ty);
-        const StructLayout &SL = *TD.getStructLayout(STy);
-        unsigned i = SL.getElementContainingOffset(Offset);
-        //Either we hit it exactly or give up
-        if (SL.getElementOffset(i) != Offset) {
-          if (FoldIfIncompatible) foldNodeCompletely();
-          return true;
-        }
-        std::vector<const Type*> nt;
-        for (unsigned x = 0; x < i; ++x)
-          nt.push_back(STy->getElementType(x));
-        STy = cast<StructType>(NewTy);
-        nt.insert(nt.end(), STy->element_begin(), STy->element_end());
-        //and merge
-        STy = StructType::get(STy->getContext(), nt);
-        //DOUT << "Trying with: " << *STy << "\n";
-        return mergeTypeInfo(STy, 0);
-      }
-
-      //Ty: struct { t1, t2, t3 ... tn}
-      //NewTy T offset x
-      //try merge with NewTy: struct : {t1, t2, T} if offset lands on a field
-      //in Ty
-      if (isa<StructType>(Ty)) {
-        //DOUT << "Ty: " << *Ty << "\nNewTy: " << *NewTy << "@" << Offset << "\n";
-        const StructType *STy = cast<StructType>(Ty);
-        const StructLayout &SL = *TD.getStructLayout(STy);
-        unsigned i = SL.getElementContainingOffset(Offset);
-        //Either we hit it exactly or give up
-        if (SL.getElementOffset(i) != Offset) {
-          if (FoldIfIncompatible) foldNodeCompletely();
-          return true;
-        }
-        std::vector<const Type*> nt;
-        for (unsigned x = 0; x < i; ++x)
-          nt.push_back(STy->getElementType(x));
-        nt.push_back(NewTy);
-        //and merge
-        STy = StructType::get(STy->getContext(), nt);
-        //DOUT << "Trying with: " << *STy << "\n";
-        return mergeTypeInfo(STy, 0);
-      }
-
-      assert(0 &&
-             "UNIMP: Trying to merge a growth type into "
-             "offset != 0: Collapsing!");
-      abort();
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-
-    }
-
-
-    // Okay, the situation is nice and simple, we are trying to merge a type in
-    // at offset 0 that is bigger than our current type.  Implement this by
-    // switching to the new type and then merge in the smaller one, which should
-    // hit the other code path here.  If the other code path decides it's not
-    // ok, it will collapse the node as appropriate.
-    //
-
-    const Type *OldTy = Ty;
-    Ty = NewTy;
-    NodeType.maskFlags(~DSFlags::ArrayNode);
-    if (WillBeArray) NodeType.setArrayNode();
-    Size = NewTySize;
-
-    // Must grow links to be the appropriate size...
-    Links.resize(NumFields);
-
-    // Merge in the old type now... which is guaranteed to be smaller than the
-    // "current" type.
-    return mergeTypeInfo(OldTy, 0);
-  }
-
-  assert(Offset <= Size &&
-         "Cannot merge something into a part of our type that doesn't exist!");
-
-  // Find the section of Ty that NewTy overlaps with... first we find the
-  // type that starts at offset Offset.
-  //
-  unsigned O = 0;
-  const Type *SubType = Ty;
-  while (O < Offset) {
-    assert(Offset-O < TD.getTypeAllocSize(SubType) && "Offset out of range!");
-
-    switch (SubType->getTypeID()) {
-    case Type::StructTyID: {
-      const StructType *STy = cast<StructType>(SubType);
-      const StructLayout &SL = *TD.getStructLayout(STy);
-      unsigned i = SL.getElementContainingOffset(Offset-O);
-
-      // The offset we are looking for must be in the i'th element...
-      SubType = STy->getElementType(i);
-      O += (unsigned)SL.getElementOffset(i);
-      break;
-    }
-    case Type::ArrayTyID: {
-      SubType = cast<ArrayType>(SubType)->getElementType();
-      unsigned ElSize = (unsigned)TD.getTypeAllocSize(SubType);
-      unsigned Remainder = (Offset-O) % ElSize;
-      O = Offset-Remainder;
-      break;
-    }
-    default:
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-    }
-  }
-
-  assert(O == Offset && "Could not achieve the correct offset!");
-
-  // If we found our type exactly, early exit
-  if (SubType == NewTy) return false;
-
-  // Differing function types don't require us to merge.  They are not values
-  // anyway.
-  if (isa<FunctionType>(SubType) &&
-      isa<FunctionType>(NewTy)) return false;
-
-  unsigned SubTypeSize = SubType->isSized() ?
-       (unsigned)TD.getTypeAllocSize(SubType) : 0;
-
-  // Ok, we are getting desperate now.  Check for physical subtyping, where we
-  // just require each element in the node to be compatible.
-  if (NewTySize <= SubTypeSize && NewTySize && NewTySize < 256 &&
-      SubTypeSize && SubTypeSize < 256 &&
-      ElementTypesAreCompatible(NewTy, SubType, !NodeType.isArrayNode(), TD))
-    return false;
-
-  // Okay, so we found the leader type at the offset requested.  Search the list
-  // of types that starts at this offset.  If SubType is currently an array or
-  // structure, the type desired may actually be the first element of the
-  // composite type...
-  //
-  unsigned PadSize = SubTypeSize; // Size, including pad memory which is ignored
-  while (SubType != NewTy) {
-    const Type *NextSubType = 0;
-    unsigned NextSubTypeSize = 0;
-    unsigned NextPadSize = 0;
-    switch (SubType->getTypeID()) {
-    case Type::StructTyID: {
-      const StructType *STy = cast<StructType>(SubType);
-      const StructLayout &SL = *TD.getStructLayout(STy);
-      if (STy->getNumElements() > 1)
-        NextPadSize = (unsigned)SL.getElementOffset(1);
-      else
-        NextPadSize = SubTypeSize;
-      NextSubType = STy->getElementType(0);
-      NextSubTypeSize = (unsigned)TD.getTypeAllocSize(NextSubType);
-      break;
-    }
-    case Type::ArrayTyID:
-      NextSubType = cast<ArrayType>(SubType)->getElementType();
-      NextSubTypeSize = (unsigned)TD.getTypeAllocSize(NextSubType);
-      NextPadSize = NextSubTypeSize;
-      break;
-    default: ;
-      // fall out
-    }
-
-    if (NextSubType == 0)
-      break;   // In the default case, break out of the loop
-
-    if (NextPadSize < NewTySize)
-      break;   // Don't allow shrinking to a smaller type than NewTySize
-    SubType = NextSubType;
-    SubTypeSize = NextSubTypeSize;
-    PadSize = NextPadSize;
-  }
-
-  // If we found the type exactly, return it...
-  if (SubType == NewTy)
-    return false;
-
-  // Check to see if we have a compatible, but different type...
-  if (NewTySize == SubTypeSize) {
-    // Check to see if this type is obviously convertible... int -> uint f.e.
-    if (NewTy->canLosslesslyBitCastTo(SubType))
-      return false;
-
-    // Check to see if we have a pointer & integer mismatch going on here,
-    // loading a pointer as a long, for example.
-    //
-    if ((SubType->isInteger() && isa<PointerType>(NewTy)) ||
-        (NewTy->isInteger() && isa<PointerType>(SubType)))
-      return false;
-  } else if (NewTySize > SubTypeSize && NewTySize <= PadSize) {
-    // We are accessing the field, plus some structure padding.  Ignore the
-    // structure padding.
-    return false;
-  }
-
-  const Module *M = 0;
-  if (getParentGraph()->retnodes_begin() != getParentGraph()->retnodes_end())
-    M = getParentGraph()->retnodes_begin()->first->getParent();
-
-  /*
-  DOUT << "MergeTypeInfo Folding OrigTy: ";
-  raw_stderr_ostream stream;
-  DEBUG(WriteTypeSymbolic(stream, Ty, M);
-        stream << "\n due to:";
-        WriteTypeSymbolic(stream, NewTy, M);
-        stream << " @ " << Offset << "!\n" << "SubType: ";
-        WriteTypeSymbolic(stream, SubType, M);
-        stream << "\n\n");
-  */
-
-  if (FoldIfIncompatible) foldNodeCompletely();
-  return true;
-}
-
-
-
-/// addEdgeTo - Add an edge from the current node to the specified node.  This
-/// can cause merging of nodes in the graph.
-///
-void DSNode::addEdgeTo(unsigned Offset, const DSNodeHandle &NH) {
-  if (NH.isNull()) return;       // Nothing to do
-
-  if (isNodeCompletelyFolded())
-    Offset = 0;
-
-  DSNodeHandle &ExistingEdge = getLink(Offset);
-  if (!ExistingEdge.isNull()) {
-    // Merge the two nodes...
-    ExistingEdge.mergeWith(NH);
-  } else {                             // No merging to perform...
-    setLink(Offset, NH);               // Just force a link in there...
-  }
-}
-
-
-void DSNode::mergeGlobals(const DSNode &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.Globals.begin(), RHS.Globals.end(), 
-                 back_it);
-  DEBUG(
-        for (std::vector<const GlobalValue*>::iterator ii = Temp.begin(), 
-               ee = Temp.end(); ii != ee; ++ii)
-          assert(isa<GlobalValue>(*ii) && "Non global merged");
-        );
-  Globals.swap(Temp);
-}
-
-// MergeNodes - Helper function for DSNode::mergeWith().
-// This function does the hard work of merging two nodes, CurNodeH
-// and NH after filtering out trivial cases and making sure that
-// CurNodeH.offset >= NH.offset.
-//
-// ***WARNING***
-// Since merging may cause either node to go away, we must always
-// use the node-handles to refer to the nodes.  These node handles are
-// automatically updated during merging, so will always provide access
-// to the correct node after a merge.
-//
-void DSNode::MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH) {
-  assert(CurNodeH.getOffset() >= NH.getOffset() &&
-         "This should have been enforced in the caller.");
-  assert(CurNodeH.getNode()->getParentGraph()==NH.getNode()->getParentGraph() &&
-         "Cannot merge two nodes that are not in the same graph!");
-
-  // Now we know that Offset >= NH.Offset, so convert it so our "Offset" (with
-  // respect to NH.Offset) is now zero.  NOffset is the distance from the base
-  // of our object that N starts from.
-  //
-  unsigned NOffset = CurNodeH.getOffset()-NH.getOffset();
-  unsigned NSize = NH.getNode()->getSize();
-
-  // If the two nodes are of different size, and the smaller node has the array
-  // bit set, collapse!
-  if (NSize != CurNodeH.getNode()->getSize()) {
-#if COLLAPSE_ARRAYS_AGGRESSIVELY
-    if (NSize < CurNodeH.getNode()->getSize()) {
-      if (NH.getNode()->isArray())
-        NH.getNode()->foldNodeCompletely();
-    } else if (CurNodeH.getNode()->isArray()) {
-      NH.getNode()->foldNodeCompletely();
-    }
-#endif
-  }
-
-  // Merge the type entries of the two nodes together...
-  if (NH.getNode()->Ty != Type::getVoidTy(getGlobalContext()))
-    CurNodeH.getNode()->mergeTypeInfo(NH.getNode()->Ty, NOffset);
-  assert(!CurNodeH.getNode()->NodeType.isDeadNode());
-
-  // If we are merging a node with a completely folded node, then both nodes are
-  // now completely folded.
-  //
-  if (CurNodeH.getNode()->isNodeCompletelyFolded()) {
-    if (!NH.getNode()->isNodeCompletelyFolded()) {
-      NH.getNode()->foldNodeCompletely();
-      assert(NH.getNode() && NH.getOffset() == 0 &&
-             "folding did not make offset 0?");
-      NOffset = NH.getOffset();
-      NSize = NH.getNode()->getSize();
-      assert(NOffset == 0 && NSize == 1);
-    }
-  } else if (NH.getNode()->isNodeCompletelyFolded()) {
-    CurNodeH.getNode()->foldNodeCompletely();
-    assert(CurNodeH.getNode() && CurNodeH.getOffset() == 0 &&
-           "folding did not make offset 0?");
-    NSize = NH.getNode()->getSize();
-    NOffset = NH.getOffset();
-    assert(NOffset == 0 && NSize == 1);
-  }
-
-  DSNode *N = NH.getNode();
-  if (CurNodeH.getNode() == N || N == 0) return;
-  assert(!CurNodeH.getNode()->NodeType.isDeadNode());
-
-  // Merge the NodeType information.
-  CurNodeH.getNode()->NodeType.mergeFlags(N->NodeType.getFlags());
-
-  // Start forwarding to the new node!
-  N->forwardNode(CurNodeH.getNode(), NOffset);
-  assert(!CurNodeH.getNode()->NodeType.isDeadNode());
-
-  // Make all of the outgoing links of N now be outgoing links of CurNodeH.
-  //
-  for (unsigned i = 0; i < N->getNumLinks(); ++i) {
-    DSNodeHandle &Link = N->getLink(i);
-    if (Link.getNode()) {
-      // Compute the offset into the current node at which to
-      // merge this link.  In the common case, this is a linear
-      // relation to the offset in the original node (with
-      // wrapping), but if the current node gets collapsed due to
-      // recursive merging, we must make sure to merge in all remaining
-      // links at offset zero.
-      unsigned MergeOffset = 0;
-      DSNode *CN = CurNodeH.getNode();
-      if (CN->Size != 1)
-        MergeOffset = (i+NOffset) % CN->getSize();
-      CN->addEdgeTo(MergeOffset, Link);
-    }
-  }
-
-  // Now that there are no outgoing edges, all of the Links are dead.
-  N->Links.clear();
-
-  // Merge the globals list...
-  if (!N->Globals.empty()) {
-    CurNodeH.getNode()->mergeGlobals(*N);
-
-    // Delete the globals from the old node...
-    N->Globals.clear();
-  }
-}
-
-
-/// mergeWith - Merge this node and the specified node, moving all links to and
-/// from the argument node into the current node, deleting the node argument.
-/// Offset indicates what offset the specified node is to be merged into the
-/// current node.
-///
-/// The specified node may be a null pointer (in which case, we update it to
-/// point to this node).
-///
-void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
-  //DOUT << "mergeWith: " << this << " becomes " << NH.getNode() << "\n";
-  DSNode *N = NH.getNode();
-  if (N == this && NH.getOffset() == Offset)
-    return;  // Noop
-
-  // If the RHS is a null node, make it point to this node!
-  if (N == 0) {
-    NH.mergeWith(DSNodeHandle(this, Offset));
-    return;
-  }
-
-  assert(!N->NodeType.isDeadNode() && !NodeType.isDeadNode());
-  assert(!hasNoReferrers() && "Should not try to fold a useless node!");
-
-  if (N == this) {
-    // We cannot merge two pieces of the same node together, collapse the node
-    // completely.
-    //DOUT << "Attempting to merge two chunks of the same node together!\n";
-    foldNodeCompletely();
-    return;
-  }
-
-  // If both nodes are not at offset 0, make sure that we are merging the node
-  // at an later offset into the node with the zero offset.
-  //
-  if (Offset < NH.getOffset()) {
-    N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset());
-    return;
-  } else if (Offset == NH.getOffset() && getSize() < N->getSize()) {
-    // If the offsets are the same, merge the smaller node into the bigger node
-    N->mergeWith(DSNodeHandle(this, Offset), NH.getOffset());
-    return;
-  }
-
-  // Ok, now we can merge the two nodes.  Use a static helper that works with
-  // two node handles, since "this" may get merged away at intermediate steps.
-  DSNodeHandle CurNodeH(this, Offset);
-  DSNodeHandle NHCopy(NH);
-  if (CurNodeH.getOffset() >= NHCopy.getOffset())
-    DSNode::MergeNodes(CurNodeH, NHCopy);
-  else
-    DSNode::MergeNodes(NHCopy, CurNodeH);
-}
-
-
-//===----------------------------------------------------------------------===//
-// ReachabilityCloner Implementation
-//===----------------------------------------------------------------------===//
-
-DSNodeHandle ReachabilityCloner::getClonedNH(const DSNodeHandle &SrcNH) {
-  if (SrcNH.isNull()) return DSNodeHandle();
-  const DSNode *SN = SrcNH.getNode();
-
-  DSNodeHandle &NH = NodeMap[SN];
-  if (!NH.isNull()) {   // Node already mapped?
-    DSNode *NHN = NH.getNode();
-    return DSNodeHandle(NHN, NH.getOffset()+SrcNH.getOffset());
-  }
-
-  // If SrcNH has globals and the destination graph has one of the same globals,
-  // merge this node with the destination node, which is much more efficient.
-  if (SN->globals_begin() != SN->globals_end()) {
-    DSScalarMap &DestSM = Dest->getScalarMap();
-    for (DSNode::globals_iterator I = SN->globals_begin(),E = SN->globals_end();
-         I != E; ++I) {
-      const GlobalValue *GV = *I;
-      DSScalarMap::iterator GI = DestSM.find(GV);
-      if (GI != DestSM.end() && !GI->second.isNull()) {
-        // We found one, use merge instead!
-        merge(GI->second, Src->getNodeForValue(GV));
-        assert(!NH.isNull() && "Didn't merge node!");
-        DSNode *NHN = NH.getNode();
-        return DSNodeHandle(NHN, NH.getOffset()+SrcNH.getOffset());
-      }
-    }
-  }
-
-  DSNode *DN = new DSNode(*SN, Dest, true /* Null out all links */);
-  DN->NodeType.maskFlags(BitsToKeep);
-  NH = DN;
-
-  // Next, recursively clone all outgoing links as necessary.  Note that
-  // adding these links can cause the node to collapse itself at any time, and
-  // the current node may be merged with arbitrary other nodes.  For this
-  // reason, we must always go through NH.
-  DN = 0;
-  for (unsigned i = 0, e = SN->getNumLinks(); i != e; ++i) {
-    const DSNodeHandle &SrcEdge = SN->getLink(i);
-    if (!SrcEdge.isNull()) {
-      const DSNodeHandle &DestEdge = getClonedNH(SrcEdge);
-      // Compute the offset into the current node at which to
-      // merge this link.  In the common case, this is a linear
-      // relation to the offset in the original node (with
-      // wrapping), but if the current node gets collapsed due to
-      // recursive merging, we must make sure to merge in all remaining
-      // links at offset zero.
-      unsigned MergeOffset = 0;
-      DSNode *CN = NH.getNode();
-      if (CN->getSize() != 1)
-        MergeOffset = (i+NH.getOffset()) % CN->getSize();
-      CN->addEdgeTo(MergeOffset, DestEdge);
-    }
-  }
-
-  // If this node contains any globals, make sure they end up in the scalar
-  // map with the correct offset.
-  for (DSNode::globals_iterator I = SN->globals_begin(), E = SN->globals_end();
-       I != E; ++I) {
-    const GlobalValue *GV = *I;
-    const DSNodeHandle &SrcGNH = Src->getNodeForValue(GV);
-    DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
-    assert(DestGNH.getNode() == NH.getNode() &&"Global mapping inconsistent");
-    Dest->getNodeForValue(GV).mergeWith(DSNodeHandle(DestGNH.getNode(),
-                                        DestGNH.getOffset()+SrcGNH.getOffset()));
-  }
-  NH.getNode()->mergeGlobals(*SN);
-
-  return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset());
-}
-
-void ReachabilityCloner::merge(const DSNodeHandle &NH,
-                               const DSNodeHandle &SrcNH) {
-  if (SrcNH.isNull()) return;  // Noop
-  if (NH.isNull()) {
-    // If there is no destination node, just clone the source and assign the
-    // destination node to be it.
-    NH.mergeWith(getClonedNH(SrcNH));
-    return;
-  }
-
-  // Okay, at this point, we know that we have both a destination and a source
-  // node that need to be merged.  Check to see if the source node has already
-  // been cloned.
-  const DSNode *SN = SrcNH.getNode();
-  DSNodeHandle &SCNH = NodeMap[SN];  // SourceClonedNodeHandle
-  if (!SCNH.isNull()) {   // Node already cloned?
-    DSNode *SCNHN = SCNH.getNode();
-    NH.mergeWith(DSNodeHandle(SCNHN,
-                              SCNH.getOffset()+SrcNH.getOffset()));
-    return;  // Nothing to do!
-  }
-
-  // Okay, so the source node has not already been cloned.  Instead of creating
-  // a new DSNode, only to merge it into the one we already have, try to perform
-  // the merge in-place.  The only case we cannot handle here is when the offset
-  // into the existing node is less than the offset into the virtual node we are
-  // merging in.  In this case, we have to extend the existing node, which
-  // requires an allocation anyway.
-  DSNode *DN = NH.getNode();   // Make sure the Offset is up-to-date
-  if (NH.getOffset() >= SrcNH.getOffset()) {
-    if (!DN->isNodeCompletelyFolded()) {
-      // Make sure the destination node is folded if the source node is folded.
-      if (SN->isNodeCompletelyFolded()) {
-        DN->foldNodeCompletely();
-        DN = NH.getNode();
-      } else if (SN->getSize() != DN->getSize()) {
-        // If the two nodes are of different size, and the smaller node has the
-        // array bit set, collapse!
-#if COLLAPSE_ARRAYS_AGGRESSIVELY
-        if (SN->getSize() < DN->getSize()) {
-          if (SN->isArray()) {
-            DN->foldNodeCompletely();
-            DN = NH.getNode();
-          }
-        } else if (DN->isArray()) {
-          DN->foldNodeCompletely();
-          DN = NH.getNode();
-        }
-#endif
-      }
-
-      // Merge the type entries of the two nodes together...
-      if (SN->getType() != Type::getVoidTy(getGlobalContext()) && !DN->isNodeCompletelyFolded()) {
-        DN->mergeTypeInfo(SN->getType(), NH.getOffset()-SrcNH.getOffset());
-        DN = NH.getNode();
-      }
-    }
-
-    assert(!DN->NodeType.isDeadNode());
-
-    // Merge the NodeType information.
-    DN->NodeType.mergeFlags(SN->NodeType.getFlags() & BitsToKeep);
-
-    // Before we start merging outgoing links and updating the scalar map, make
-    // sure it is known that this is the representative node for the src node.
-    SCNH = DSNodeHandle(DN, NH.getOffset()-SrcNH.getOffset());
-
-    // If the source node contains any globals, make sure they end up in the
-    // scalar map with the correct offset.
-    if (SN->globals_begin() != SN->globals_end()) {
-      // Update the globals in the destination node itself.
-      DN->mergeGlobals(*SN);
-
-      // Update the scalar map for the graph we are merging the source node
-      // into.
-      for (DSNode::globals_iterator I = SN->globals_begin(),
-             E = SN->globals_end(); I != E; ++I) {
-        const GlobalValue *GV = *I;
-        const DSNodeHandle &SrcGNH = Src->getNodeForValue(GV);
-        DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
-        assert(DestGNH.getNode()==NH.getNode() &&"Global mapping inconsistent");
-        Dest->getNodeForValue(GV).mergeWith(DSNodeHandle(DestGNH.getNode(),
-                                      DestGNH.getOffset()+SrcGNH.getOffset()));
-      }
-      NH.getNode()->mergeGlobals(*SN);
-    }
-  } else {
-    // We cannot handle this case without allocating a temporary node.  Fall
-    // back on being simple.
-    DSNode *NewDN = new DSNode(*SN, Dest, true /* Null out all links */);
-    NewDN->NodeType.maskFlags(BitsToKeep);
-
-    unsigned NHOffset = NH.getOffset();
-    NH.mergeWith(DSNodeHandle(NewDN, SrcNH.getOffset()));
-
-    assert(NH.getNode() &&
-           (NH.getOffset() > NHOffset ||
-            (NH.getOffset() == 0 && NH.getNode()->isNodeCompletelyFolded())) &&
-           "Merging did not adjust the offset!");
-
-    // Before we start merging outgoing links and updating the scalar map, make
-    // sure it is known that this is the representative node for the src node.
-    SCNH = DSNodeHandle(NH.getNode(), NH.getOffset()-SrcNH.getOffset());
-
-    // If the source node contained any globals, make sure to create entries
-    // in the scalar map for them!
-    for (DSNode::globals_iterator I = SN->globals_begin(),
-           E = SN->globals_end(); I != E; ++I) {
-      const GlobalValue *GV = *I;
-      const DSNodeHandle &SrcGNH = Src->getNodeForValue(GV);
-      DSNodeHandle &DestGNH = NodeMap[SrcGNH.getNode()];
-      assert(DestGNH.getNode()==NH.getNode() &&"Global mapping inconsistent");
-      assert(SrcGNH.getNode() == SN && "Global mapping inconsistent");
-      Dest->getNodeForValue(GV).mergeWith(DSNodeHandle(DestGNH.getNode(),
-                                    DestGNH.getOffset()+SrcGNH.getOffset()));
-    }
-  }
-
-  // Next, recursively merge all outgoing links as necessary.  Note that
-  // adding these links can cause the destination node to collapse itself at
-  // any time, and the current node may be merged with arbitrary other nodes.
-  // For this reason, we must always go through NH.
-  DN = 0;
-  for (unsigned i = 0, e = SN->getNumLinks(); i != e; ++i) {
-    const DSNodeHandle &SrcEdge = SN->getLink(i);
-    if (!SrcEdge.isNull()) {
-      // Compute the offset into the current node at which to
-      // merge this link.  In the common case, this is a linear
-      // relation to the offset in the original node (with
-      // wrapping), but if the current node gets collapsed due to
-      // recursive merging, we must make sure to merge in all remaining
-      // links at offset zero.
-      DSNode *CN = SCNH.getNode();
-      unsigned MergeOffset =
-        (i+SCNH.getOffset()) % CN->getSize();
-
-      DSNodeHandle Tmp = CN->getLink(MergeOffset);
-      if (!Tmp.isNull()) {
-        // Perform the recursive merging.  Make sure to create a temporary NH,
-        // because the Link can disappear in the process of recursive merging.
-        merge(Tmp, SrcEdge);
-      } else {
-        Tmp.mergeWith(getClonedNH(SrcEdge));
-        // Merging this could cause all kinds of recursive things to happen,
-        // culminating in the current node being eliminated.  Since this is
-        // possible, make sure to reaquire the link from 'CN'.
-
-        unsigned MergeOffset = 0;
-        CN = SCNH.getNode();
-        MergeOffset = (i+SCNH.getOffset()) %CN->getSize();
-        CN->getLink(MergeOffset).mergeWith(Tmp);
-      }
-    }
-  }
-}
-
-/// mergeCallSite - Merge the nodes reachable from the specified src call
-/// site into the nodes reachable from DestCS.
-void ReachabilityCloner::mergeCallSite(DSCallSite &DestCS,
-                                       const DSCallSite &SrcCS) {
-  merge(DestCS.getRetVal(), SrcCS.getRetVal());
-  unsigned MinArgs = DestCS.getNumPtrArgs();
-  if (SrcCS.getNumPtrArgs() < MinArgs) MinArgs = SrcCS.getNumPtrArgs();
-
-  for (unsigned a = 0; a != MinArgs; ++a)
-    merge(DestCS.getPtrArg(a), SrcCS.getPtrArg(a));
-
-  for (unsigned a = MinArgs, e = SrcCS.getNumPtrArgs(); a != e; ++a)
-    DestCS.addPtrArg(getClonedNH(SrcCS.getPtrArg(a)));
-}
-
-DSCallSite ReachabilityCloner::cloneCallSite(const DSCallSite& SrcCS) {
-  std::vector<DSNodeHandle> Args;
-  for(unsigned x = 0; x < SrcCS.getNumPtrArgs(); ++x)
-    Args.push_back(getClonedNH(SrcCS.getPtrArg(x)));
-  if (SrcCS.isDirectCall())
-    return DSCallSite(SrcCS.getCallSite(),
-                      getClonedNH(SrcCS.getRetVal()),
-                      SrcCS.getCalleeFunc(),
-                      Args);
-  else
-    return DSCallSite(SrcCS.getCallSite(),
-                      getClonedNH(SrcCS.getRetVal()),
-                      getClonedNH(SrcCS.getCalleeNode()).getNode(),
-                      Args);
-}
-
-//===----------------------------------------------------------------------===//
-// DSCallSite Implementation
-//===----------------------------------------------------------------------===//
-
-// Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
-const Function &DSCallSite::getCaller() const {
-  return *Site.getInstruction()->getParent()->getParent();
-}
-
-void DSCallSite::InitNH(DSNodeHandle &NH, const DSNodeHandle &Src,
-                        ReachabilityCloner &RC) {
-  NH = RC.getClonedNH(Src);
-}
-
-//===----------------------------------------------------------------------===//
-// DSGraph Implementation
-//===----------------------------------------------------------------------===//
-
-/// getFunctionNames - Return a space separated list of the name of the
-/// functions in this graph (if any)
-std::string DSGraph::getFunctionNames() const {
-  switch (getReturnNodes().size()) {
-  case 0: return "Globals graph";
-  case 1: return retnodes_begin()->first->getName();
-  default:
-    std::string Return;
-    for (DSGraph::retnodes_iterator I = retnodes_begin();
-         I != retnodes_end(); ++I)
-      Return += I->first->getNameStr() + " ";
-    Return.erase(Return.end()-1, Return.end());   // Remove last space character
-    return Return;
-  }
-}
-
-
-DSGraph::DSGraph(DSGraph* G, EquivalenceClasses<const GlobalValue*> &ECs,
-                 DSGraph* GG, unsigned CloneFlags)
-  : GlobalsGraph(GG), ScalarMap(ECs), TD(G->TD) {
-  UseAuxCalls = false;
-  cloneInto(G, CloneFlags);
-}
-
-DSGraph::~DSGraph() {
-  FunctionCalls.clear();
-  AuxFunctionCalls.clear();
-  ScalarMap.clear();
-  ReturnNodes.clear();
-
-  // 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();
-
-  // Free all of the nodes.
-  Nodes.clear();
-}
-
-// dump - Allow inspection of graph in a debugger.
-void DSGraph::dump() const { print(cerr); }
-
-
-/// remapLinks - Change all of the Links in the current node according to the
-/// specified mapping.
-///
-void DSNode::remapLinks(DSGraph::NodeMapTy &OldNodeMap) {
-  for (unsigned i = 0, e = Links.size(); i != e; ++i)
-    if (DSNode *N = Links[i].getNode()) {
-      DSGraph::NodeMapTy::const_iterator ONMI = OldNodeMap.find(N);
-      if (ONMI != OldNodeMap.end()) {
-        DSNode *ONMIN = ONMI->second.getNode();
-        Links[i].setTo(ONMIN, Links[i].getOffset()+ONMI->second.getOffset());
-      }
-    }
-}
-
-void DSGraph::removeFunctionCalls(Function& F) {
-  for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
-         E = FunctionCalls.end(); I != E; ++I)
-    if (I->isDirectCall() && I->getCalleeFunc() == &F) {
-      FunctionCalls.erase(I);
-      break;
-    }
-
-  for (std::list<DSCallSite>::iterator I = AuxFunctionCalls.begin(),
-         E = AuxFunctionCalls.end(); I != E; ++I)
-    if (I->isDirectCall() && I->getCalleeFunc() == &F) {
-      AuxFunctionCalls.erase(I);
-      break;
-    }
-}
-
-/// addObjectToGraph - This method can be used to add global, stack, and heap
-/// objects to the graph.  This can be used when updating DSGraphs due to the
-/// introduction of new temporary objects.  The new object is not pointed to
-/// and does not point to any other objects in the graph.
-DSNode *DSGraph::addObjectToGraph(Value *Ptr, bool UseDeclaredType) {
-  assert(isa<PointerType>(Ptr->getType()) && "Ptr is not a pointer!");
-  const Type *Ty = cast<PointerType>(Ptr->getType())->getElementType();
-  DSNode *N = new DSNode(UseDeclaredType ? Ty : 0, this);
-  assert(ScalarMap[Ptr].isNull() && "Object already in this graph!");
-  ScalarMap[Ptr] = N;
-
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(Ptr)) {
-    N->addGlobal(GV);
-  } else if (isa<MallocInst>(Ptr)) {
-   N->NodeType.setHeapNode();
-  } else if (isa<AllocaInst>(Ptr)) {
-    N->NodeType.setAllocaNode();
-  } else {
-    assert(0 && "Illegal memory object input!");
-  }
-  return N;
-}
-
-
-/// cloneInto - Clone the specified DSGraph into the current graph.  The
-/// translated ScalarMap for the old function is filled into the ScalarMap
-/// for the graph, and the translated ReturnNodes map is returned into
-/// ReturnNodes.
-///
-/// The CloneFlags member controls various aspects of the cloning process.
-///
-void DSGraph::cloneInto( DSGraph* G, unsigned CloneFlags) {
-  assert(G != this && "Cannot clone graph into itself!");
-
-  NodeMapTy OldNodeMap;
-
-  // Remove alloca or mod/ref bits as specified...
-  unsigned BitsToClear = ((CloneFlags & StripAllocaBit)? DSFlags::AllocaNode : 0)
-    | ((CloneFlags & StripModRefBits)? (DSFlags::ModifiedNode | DSFlags::ReadNode) : 0)
-    | ((CloneFlags & StripIncompleteBit)? DSFlags::IncompleteNode : 0);
-  BitsToClear |= DSFlags::DeadNode;  // Clear dead flag...
-
-  for (node_const_iterator I = G->node_begin(), E = G->node_end(); I != E; ++I) {
-    assert(!I->isForwarding() &&
-           "Forward nodes shouldn't be in node list!");
-    DSNode *New = new DSNode(*I, this);
-    New->NodeType.maskFlags(~BitsToClear);
-    OldNodeMap[I] = New;
-  }
-
-  // Rewrite the links in the new nodes to point into the current graph now.
-  // Note that we don't loop over the node's list to do this.  The problem is
-  // that remaping links can cause recursive merging to happen, which means
-  // that node_iterator's can get easily invalidated!  Because of this, we
-  // loop over the OldNodeMap, which contains all of the new nodes as the
-  // .second element of the map elements.  Also note that if we remap a node
-  // more than once, we won't break anything.
-  for (NodeMapTy::iterator I = OldNodeMap.begin(), E = OldNodeMap.end();
-       I != E; ++I)
-    I->second.getNode()->remapLinks(OldNodeMap);
-
-  // Copy the scalar map... merging all of the global nodes...
-  for (DSScalarMap::const_iterator I = G->ScalarMap.begin(),
-         E = G->ScalarMap.end(); I != E; ++I) {
-    DSNodeHandle &MappedNode = OldNodeMap[I->second.getNode()];
-    DSNodeHandle &H = ScalarMap.getRawEntryRef(I->first);
-    DSNode *MappedNodeN = MappedNode.getNode();
-    H.mergeWith(DSNodeHandle(MappedNodeN,
-                             I->second.getOffset()+MappedNode.getOffset()));
-  }
-
-  if (!(CloneFlags & DontCloneCallNodes)) {
-    // Copy the function calls list.
-    for (fc_iterator I = G->fc_begin(), E = G->fc_end(); I != E; ++I)
-      FunctionCalls.push_back(DSCallSite(*I, OldNodeMap));
-  }
-
-  if (!(CloneFlags & DontCloneAuxCallNodes)) {
-    // Copy the auxiliary function calls list.
-    for (afc_iterator I = G->afc_begin(), E = G->afc_end(); I != E; ++I)
-      AuxFunctionCalls.push_back(DSCallSite(*I, OldNodeMap));
-  }
-
-  // Map the return node pointers over...
-  for (retnodes_iterator I = G->retnodes_begin(),
-         E = G->retnodes_end(); I != E; ++I) {
-    const DSNodeHandle &Ret = I->second;
-    DSNodeHandle &MappedRet = OldNodeMap[Ret.getNode()];
-    DSNode *MappedRetN = MappedRet.getNode();
-    ReturnNodes.insert(std::make_pair(I->first,
-                                      DSNodeHandle(MappedRetN,
-                                     MappedRet.getOffset()+Ret.getOffset())));
-  }
-}
-
-/// spliceFrom - Logically perform the operation of cloning the RHS graph into
-/// this graph, then clearing the RHS graph.  Instead of performing this as
-/// two seperate operations, do it as a single, much faster, one.
-///
-void DSGraph::spliceFrom(DSGraph* RHS) {
-  assert(this != RHS && "Splicing self");
-  // Change all of the nodes in RHS to think we are their parent.
-  for (NodeListTy::iterator I = RHS->Nodes.begin(), E = RHS->Nodes.end();
-       I != E; ++I)
-    I->setParentGraph(this);
-  // Take all of the nodes.
-  Nodes.splice(Nodes.end(), RHS->Nodes);
-
-  // Take all of the calls.
-  FunctionCalls.splice(FunctionCalls.end(), RHS->FunctionCalls);
-  AuxFunctionCalls.splice(AuxFunctionCalls.end(), RHS->AuxFunctionCalls);
-
-  // Take all of the return nodes.
-  if (ReturnNodes.empty()) {
-    ReturnNodes.swap(RHS->ReturnNodes);
-  } else {
-    ReturnNodes.insert(RHS->ReturnNodes.begin(), RHS->ReturnNodes.end());
-    RHS->ReturnNodes.clear();
-  }
-
- // Merge the scalar map in.
-  ScalarMap.spliceFrom(RHS->ScalarMap);
-}
-
-/// spliceFrom - Copy all entries from RHS, then clear RHS.
-///
-void DSScalarMap::spliceFrom(DSScalarMap &RHS) {
-  // Special case if this is empty.
-  if (ValueMap.empty()) {
-    ValueMap.swap(RHS.ValueMap);
-    GlobalSet.swap(RHS.GlobalSet);
-  } else {
-    GlobalSet.insert(RHS.GlobalSet.begin(), RHS.GlobalSet.end());
-    for (ValueMapTy::iterator I = RHS.ValueMap.begin(), E = RHS.ValueMap.end();
-         I != E; ++I)
-      ValueMap[I->first].mergeWith(I->second);
-    RHS.ValueMap.clear();
-  }
-}
-
-
-/// getFunctionArgumentsForCall - Given a function that is currently in this
-/// graph, return the DSNodeHandles that correspond to the pointer-compatible
-/// 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(const Function *F,
-                                       std::vector<DSNodeHandle> &Args) const {
-  Args.push_back(getReturnNodeFor(*F));
-  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));
-      assert(!Args.back().isNull() && "Pointer argument w/o scalarmap entry!?");
-    }
-}
-
-namespace {
-  // HackedGraphSCCFinder - This is used to find nodes that have a path from the
-  // node to a node cloned by the ReachabilityCloner object contained.  To be
-  // extra obnoxious it ignores edges from nodes that are globals, and truncates
-  // search at RC marked nodes.  This is designed as an object so that
-  // intermediate results can be memoized across invocations of
-  // PathExistsToClonedNode.
-  struct HackedGraphSCCFinder {
-    ReachabilityCloner &RC;
-    unsigned CurNodeId;
-    std::vector<const DSNode*> SCCStack;
-    std::map<const DSNode*, std::pair<unsigned, bool> > NodeInfo;
-
-    HackedGraphSCCFinder(ReachabilityCloner &rc) : RC(rc), CurNodeId(1) {
-      // Remove null pointer as a special case.
-      NodeInfo[0] = std::make_pair(0, false);
-    }
-
-    std::pair<unsigned, bool> &VisitForSCCs(const DSNode *N);
-
-    bool PathExistsToClonedNode(const DSNode *N) {
-      return VisitForSCCs(N).second;
-    }
-
-    bool PathExistsToClonedNode(const DSCallSite &CS) {
-      if (PathExistsToClonedNode(CS.getRetVal().getNode()))
-        return true;
-      if (CS.isDirectCall() || PathExistsToClonedNode(CS.getCalleeNode()))
-        return true;
-      for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i)
-        if (PathExistsToClonedNode(CS.getPtrArg(i).getNode()))
-          return true;
-      return false;
-    }
-  };
-}
-
-std::pair<unsigned, bool> &HackedGraphSCCFinder::
-VisitForSCCs(const DSNode *N) {
-  std::map<const DSNode*, std::pair<unsigned, bool> >::iterator
-    NodeInfoIt = NodeInfo.lower_bound(N);
-  if (NodeInfoIt != NodeInfo.end() && NodeInfoIt->first == N)
-    return NodeInfoIt->second;
-
-  unsigned Min = CurNodeId++;
-  unsigned MyId = Min;
-  std::pair<unsigned, bool> &ThisNodeInfo =
-    NodeInfo.insert(NodeInfoIt,
-                    std::make_pair(N, std::make_pair(MyId, false)))->second;
-
-  // Base case: if we find a global, this doesn't reach the cloned graph
-  // portion.
-  if (N->NodeType.isGlobalNode()) {
-    ThisNodeInfo.second = false;
-    return ThisNodeInfo;
-  }
-
-  // Base case: if this does reach the cloned graph portion... it does. :)
-  if (RC.hasClonedNode(N)) {
-    ThisNodeInfo.second = true;
-    return ThisNodeInfo;
-  }
-
-  SCCStack.push_back(N);
-
-  // Otherwise, check all successors.
-  bool AnyDirectSuccessorsReachClonedNodes = false;
-  for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
-       EI != EE; ++EI)
-    if (DSNode *Succ = EI->getNode()) {
-      std::pair<unsigned, bool> &SuccInfo = VisitForSCCs(Succ);
-      if (SuccInfo.first < Min) Min = SuccInfo.first;
-      AnyDirectSuccessorsReachClonedNodes |= SuccInfo.second;
-    }
-
-  if (Min != MyId)
-    return ThisNodeInfo;  // Part of a large SCC.  Leave self on stack.
-
-  if (SCCStack.back() == N) {  // Special case single node SCC.
-    SCCStack.pop_back();
-    ThisNodeInfo.second = AnyDirectSuccessorsReachClonedNodes;
-    return ThisNodeInfo;
-  }
-
-  // Find out if any direct successors of any node reach cloned nodes.
-  if (!AnyDirectSuccessorsReachClonedNodes)
-    for (unsigned i = SCCStack.size()-1; SCCStack[i] != N; --i)
-      for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
-           EI != EE; ++EI)
-        if (DSNode *N = EI->getNode())
-          if (NodeInfo[N].second) {
-            AnyDirectSuccessorsReachClonedNodes = true;
-            goto OutOfLoop;
-          }
-OutOfLoop:
-  // If any successor reaches a cloned node, mark all nodes in this SCC as
-  // reaching the cloned node.
-  if (AnyDirectSuccessorsReachClonedNodes)
-    while (SCCStack.back() != N) {
-      NodeInfo[SCCStack.back()].second = true;
-      SCCStack.pop_back();
-    }
-  SCCStack.pop_back();
-  ThisNodeInfo.second = true;
-  return ThisNodeInfo;
-}
-
-/// mergeInCallFromOtherGraph - This graph merges in the minimal number of
-/// nodes from G2 into 'this' graph, merging the bindings specified by the
-/// call site (in this graph) with the bindings specified by the vector in G2.
-/// The two DSGraphs must be different.
-///
-void DSGraph::mergeInGraph(const DSCallSite &CS,
-                           std::vector<DSNodeHandle> &Args,
-                           const DSGraph &Graph, unsigned CloneFlags) {
-  assert((CloneFlags & DontCloneCallNodes) &&
-         "Doesn't support copying of call nodes!");
-
-  // If this is not a recursive call, clone the graph into this graph...
-  if (&Graph == this) {
-    // Merge the return value with the return value of the context.
-    Args[0].mergeWith(CS.getRetVal());
-
-    // Resolve all of the function arguments.
-    for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) {
-      if (i == Args.size()-1)
-        break;
-
-      // Add the link from the argument scalar to the provided value.
-      Args[i+1].mergeWith(CS.getPtrArg(i));
-    }
-    return;
-  }
-
-  // Clone the callee's graph into the current graph, keeping track of where
-  // scalars in the old graph _used_ to point, and of the new nodes matching
-  // nodes of the old graph.
-  ReachabilityCloner RC(this, &Graph, CloneFlags);
-
-  // Map the return node pointer over.
-  if (!CS.getRetVal().isNull())
-    RC.merge(CS.getRetVal(), Args[0]);
-
-  // Map over all of the arguments.
-  for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) {
-    if (i == Args.size()-1)
-      break;
-
-    // Add the link from the argument scalar to the provided value.
-    RC.merge(CS.getPtrArg(i), Args[i+1]);
-  }
-
-  // We generally don't want to copy global nodes or aux calls from the callee
-  // graph to the caller graph.  However, we have to copy them if there is a
-  // path from the node to a node we have already copied which does not go
-  // 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<const GlobalValue*> GlobalsToCopy;
-
-  // NodesReachCopiedNodes - Memoize results for efficiency.  Contains a
-  // true/false value for every visited node that reaches a copied node without
-  // going through a global.
-  HackedGraphSCCFinder SCCFinder(RC);
-
-  if (!(CloneFlags & DontCloneAuxCallNodes))
-    for (afc_const_iterator I = Graph.afc_begin(), E = Graph.afc_end(); I!=E; ++I)
-      if (SCCFinder.PathExistsToClonedNode(*I))
-        AuxCallToCopy.push_back(&*I);
-//       else if (I->isIndirectCall()){
-//  	//If the call node doesn't have any callees, clone it
-//  	std::vector< Function *> List;
-//  	I->getCalleeNode()->addFullFunctionList(List);
-//  	if (!List.size())
-//  	  AuxCallToCopy.push_back(&*I);
-//        }
-
-  const DSScalarMap &GSM = Graph.getScalarMap();
-  for (DSScalarMap::global_iterator GI = GSM.global_begin(),
-         E = GSM.global_end(); GI != E; ++GI) {
-    DSNode *GlobalNode = Graph.getNodeForValue(*GI).getNode();
-    for (DSNode::edge_iterator EI = GlobalNode->edge_begin(),
-           EE = GlobalNode->edge_end(); EI != EE; ++EI)
-      if (SCCFinder.PathExistsToClonedNode(EI->getNode())) {
-        GlobalsToCopy.push_back(*GI);
-        break;
-      }
-  }
-
-  // Copy aux calls that are needed.
-  for (unsigned i = 0, e = AuxCallToCopy.size(); i != e; ++i)
-    AuxFunctionCalls.push_back(DSCallSite(*AuxCallToCopy[i], RC));
-
-  // Copy globals that are needed.
-  for (unsigned i = 0, e = GlobalsToCopy.size(); i != e; ++i)
-    RC.getClonedNH(Graph.getNodeForValue(GlobalsToCopy[i]));
-}
-
-
-
-/// mergeInGraph - The method is used for merging graphs together.  If the
-/// argument graph is not *this, it makes a clone of the specified graph, then
-/// merges the nodes specified in the call site with the formal arguments in the
-/// graph.
-///
-void DSGraph::mergeInGraph(const DSCallSite &CS, const Function &F,
-                           const DSGraph &Graph, unsigned CloneFlags) {
-  // Set up argument bindings.
-  std::vector<DSNodeHandle> Args;
-  Graph.getFunctionArgumentsForCall(&F, Args);
-
-  mergeInGraph(CS, Args, Graph, CloneFlags);
-}
-
-/// getCallSiteForArguments - Get the arguments and return value bindings for
-/// the specified function in the current graph.
-///
-DSCallSite DSGraph::getCallSiteForArguments(const Function &F) const {
-  std::vector<DSNodeHandle> Args;
-
-  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));
-
-  return DSCallSite(CallSite(), getReturnNodeFor(F), &F, Args);
-}
-
-/// getDSCallSiteForCallSite - Given an LLVM CallSite object that is live in
-/// the context of this graph, return the DSCallSite for it.
-DSCallSite DSGraph::getDSCallSiteForCallSite(CallSite CS) const {
-  DSNodeHandle RetVal;
-  Instruction *I = CS.getInstruction();
-  if (isa<PointerType>(I->getType()))
-    RetVal = getNodeForValue(I);
-
-  std::vector<DSNodeHandle> Args;
-  Args.reserve(CS.arg_end()-CS.arg_begin());
-
-  // Calculate the arguments vector...
-  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
-    if (isa<PointerType>((*I)->getType())) {
-      if (isa<ConstantPointerNull>(*I))
-        Args.push_back(DSNodeHandle());
-      else
-        Args.push_back(getNodeForValue(*I));
-    }
-
-  // Add a new function call entry...
-  if (Function *F = CS.getCalledFunction())
-    return DSCallSite(CS, RetVal, F, Args);
-  else
-    return DSCallSite(CS, RetVal,
-                      getNodeForValue(CS.getCalledValue()).getNode(), Args);
-}
-
-
-
-// markIncompleteNodes - Mark the specified node as having contents that are not
-// known with the current analysis we have performed.  Because a node makes all
-// of the nodes it can reach incomplete if the node itself is incomplete, we
-// must recursively traverse the data structure graph, marking all reachable
-// nodes as incomplete.
-//
-static void markIncompleteNode(DSNode *N) {
-  // Stop recursion if no node, or if node already marked...
-  if (N == 0 || N->NodeType.isIncompleteNode()) return;
-
-  // Actually mark the node
-  N->NodeType.setIncompleteNode();
-
-  // Recursively process children...
-  for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
-    if (DSNode *DSN = I->getNode())
-      markIncompleteNode(DSN);
-}
-
-static void markIncomplete(DSCallSite &Call) {
-  // Then the return value is certainly incomplete!
-  markIncompleteNode(Call.getRetVal().getNode());
-
-  // All objects pointed to by function arguments are incomplete!
-  for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
-    markIncompleteNode(Call.getPtrArg(i).getNode());
-}
-
-// markIncompleteNodes - Traverse the graph, identifying nodes that may be
-// modified by other functions that have not been resolved yet.  This marks
-// nodes that are reachable through three sources of "unknownness":
-//
-//  Global Variables, Function Calls, and Incoming Arguments
-//
-// For any node that may have unknown components (because something outside the
-// scope of current analysis may have modified it), the 'Incomplete' flag is
-// added to the NodeType.
-//
-void DSGraph::markIncompleteNodes(unsigned Flags) {
-  // Mark any incoming arguments as incomplete.
-  if (Flags & DSGraph::MarkFormalArgs)
-    for (ReturnNodesTy::iterator FI = ReturnNodes.begin(), E =ReturnNodes.end();
-         FI != E; ++FI) {
-      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());
-      markIncompleteNode(FI->second.getNode());
-    }
-
-  // Mark stuff passed into functions calls as being incomplete.
-  if (!shouldUseAuxCalls())
-    for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
-           E = FunctionCalls.end(); I != E; ++I)
-      markIncomplete(*I);
-  else
-    for (std::list<DSCallSite>::iterator I = AuxFunctionCalls.begin(),
-           E = AuxFunctionCalls.end(); I != E; ++I)
-      markIncomplete(*I);
-
-#if 0
-  // Mark stuff passed into external functions as being incomplete.
-  // External functions may not appear in Aux during td, so process
-  // them specially
-  for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
-         E = FunctionCalls.end(); I != E; ++I)
-    if(I->isDirectCall() && I->getCalleeFunc()->isDeclaration())
-      markIncomplete(*I);
-#endif
-
-  // Mark all global nodes as incomplete.
-  for (DSScalarMap::global_iterator I = ScalarMap.global_begin(),
-         E = ScalarMap.global_end(); I != E; ++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());
-
-  // Mark any node with the VAStart flag as incomplete.
-  if (Flags & DSGraph::MarkVAStart) {
-    for (node_iterator i=node_begin(); i != node_end(); ++i) {
-      markIncompleteNode(i);
-    }
-  }
-}
-
-static inline void killIfUselessEdge(DSNodeHandle &Edge) {
-  if (DSNode *N = Edge.getNode())  // Is there an edge?
-    if (N->getNumReferrers() == 1)  // Does it point to a lonely node?
-      // No interesting info?
-      if ((N->getNodeFlags() & ~DSFlags::IncompleteNode) == 0 &&
-          N->getType() == Type::getVoidTy(getGlobalContext()) && !N->isNodeCompletelyFolded())
-        Edge.setTo(0, 0);  // Kill the edge!
-}
-
-static void removeIdenticalCalls(std::list<DSCallSite> &Calls) {
-  // Remove trivially identical function calls
-  Calls.sort();  // Sort by callee as primary key!
-
-  // Scan the call list cleaning it up as necessary...
-  DSNodeHandle LastCalleeNode;
-#if 0
-  Function *LastCalleeFunc = 0;
-  unsigned NumDuplicateCalls = 0;
-#endif
-  bool LastCalleeContainsExternalFunction = false;
-
-  unsigned NumDeleted = 0;
-  for (std::list<DSCallSite>::iterator I = Calls.begin(), E = Calls.end();
-       I != E;) {
-    DSCallSite &CS = *I;
-    std::list<DSCallSite>::iterator OldIt = I++;
-
-    if (!CS.isIndirectCall()) {
-      LastCalleeNode = 0;
-    } else {
-      DSNode *Callee = CS.getCalleeNode();
-
-      // If the Callee is a useless edge, this must be an unreachable call site,
-      // eliminate it.
-      if (Callee->getNumReferrers() == 1 && Callee->NodeType.isCompleteNode() &&
-          Callee->isEmptyGlobals()) {  // No useful info?
-        //errs() << "WARNING: Useless call site found.\n";
-        Calls.erase(OldIt);
-        ++NumDeleted;
-        continue;
-      }
-
-      // If the last call site in the list has the same callee as this one, and
-      // if the callee contains an external function, it will never be
-      // resolvable, just merge the call sites.
-      if (!LastCalleeNode.isNull() && LastCalleeNode.getNode() == Callee) {
-        LastCalleeContainsExternalFunction = Callee->NodeType.isExternFunctionNode();
-
-        std::list<DSCallSite>::iterator PrevIt = OldIt;
-        --PrevIt;
-        PrevIt->mergeWith(CS);
-
-        // No need to keep this call anymore.
-        Calls.erase(OldIt);
-        ++NumDeleted;
-        continue;
-      } else {
-        LastCalleeNode = Callee;
-      }
-    }
-
-    // If the return value or any arguments point to a void node with no
-    // information at all in it, and the call node is the only node to point
-    // to it, remove the edge to the node (killing the node).
-    //
-    killIfUselessEdge(CS.getRetVal());
-    for (unsigned a = 0, e = CS.getNumPtrArgs(); a != e; ++a)
-      killIfUselessEdge(CS.getPtrArg(a));
-
-#if 0
-    // If this call site calls the same function as the last call site, and if
-    // the function pointer contains an external function, this node will
-    // never be resolved.  Merge the arguments of the call node because no
-    // information will be lost.
-    //
-    if ((CS.isDirectCall()   && CS.getCalleeFunc() == LastCalleeFunc) ||
-        (CS.isIndirectCall() && CS.getCalleeNode() == LastCalleeNode)) {
-      ++NumDuplicateCalls;
-      if (NumDuplicateCalls == 1) {
-        if (LastCalleeNode)
-          LastCalleeContainsExternalFunction = 
-	    LastCalleeNode->isExternFunctionNode();
-        else
-          LastCalleeContainsExternalFunction = LastCalleeFunc->isExternal();
-      }
-
-      // It is not clear why, but enabling this code makes DSA really
-      // sensitive to node forwarding.  Basically, with this enabled, DSA
-      // performs different number of inlinings based on which nodes are
-      // forwarding or not.  This is clearly a problem, so this code is
-      // disabled until this can be resolved.
-#if 1
-      if (LastCalleeContainsExternalFunction
-#if 0
-          ||
-          // This should be more than enough context sensitivity!
-          // FIXME: Evaluate how many times this is tripped!
-          NumDuplicateCalls > 20
-#endif
-          ) {
-
-        std::list<DSCallSite>::iterator PrevIt = OldIt;
-        --PrevIt;
-        PrevIt->mergeWith(CS);
-
-        // No need to keep this call anymore.
-        Calls.erase(OldIt);
-        ++NumDeleted;
-        continue;
-      }
-#endif
-    } else {
-      if (CS.isDirectCall()) {
-        LastCalleeFunc = CS.getCalleeFunc();
-        LastCalleeNode = 0;
-      } else {
-        LastCalleeNode = CS.getCalleeNode();
-        LastCalleeFunc = 0;
-      }
-      NumDuplicateCalls = 0;
-    }
-#endif
-
-    if (I != Calls.end() && CS == *I) {
-      LastCalleeNode = 0;
-      Calls.erase(OldIt);
-      ++NumDeleted;
-      continue;
-    }
-  }
-
-  // Resort now that we simplified things.
-  Calls.sort();
-
-  // Now that we are in sorted order, eliminate duplicates.
-  std::list<DSCallSite>::iterator CI = Calls.begin(), CE = Calls.end();
-  if (CI != CE)
-    while (1) {
-      std::list<DSCallSite>::iterator OldIt = CI++;
-      if (CI == CE) break;
-
-      // If this call site is now the same as the previous one, we can delete it
-      // as a duplicate.
-      if (*OldIt == *CI) {
-        Calls.erase(CI);
-        CI = OldIt;
-        ++NumDeleted;
-      }
-    }
-
-  //Calls.erase(std::unique(Calls.begin(), Calls.end()), Calls.end());
-
-  // Track the number of call nodes merged away...
-  NumCallNodesMerged += NumDeleted;
-
-}
-
-
-// removeTriviallyDeadNodes - After the graph has been constructed, this method
-// removes all unreachable nodes that are created because they got merged with
-// other nodes in the graph.  These nodes will all be trivially unreachable, so
-// we don't have to perform any non-trivial analysis here.
-//
-void DSGraph::removeTriviallyDeadNodes(bool updateForwarders) {
-
-  if (updateForwarders) {
-    /// NOTE: This code is disabled.  This slows down DSA on 177.mesa
-    /// substantially!
-    
-    // Loop over all of the nodes in the graph, calling getNode on each field.
-    // This will cause all nodes to update their forwarding edges, causing
-    // forwarded nodes to be delete-able.
-    for (node_iterator NI = node_begin(), E = node_end(); NI != E; ++NI) {
-      DSNode &N = *NI;
-      for (unsigned l = 0, e = N.getNumLinks(); l != e; ++l)
-	N.getLink(l).getNode();
-    }
-    
-    // NOTE: This code is disabled.  Though it should, in theory, allow us to
-    // remove more nodes down below, the scan of the scalar map is incredibly
-    // expensive for certain programs (with large SCCs).  In the future, if we can
-    // make the scalar map scan more efficient, then we can reenable this.
-      
-    // Likewise, forward any edges from the scalar nodes.  While we are at it,
-    // clean house a bit.
-    for (DSScalarMap::iterator I = ScalarMap.begin(),E = ScalarMap.end();I != E;){
-      I->second.getNode();
-      ++I;
-    }
-  }
-
-  bool isGlobalsGraph = !GlobalsGraph;
-
-  for (NodeListTy::iterator NI = Nodes.begin(), E = Nodes.end(); NI != E; ) {
-    DSNode &Node = *NI;
-
-    // Do not remove *any* global nodes in the globals graph.
-    // This is a special case because such nodes may not have I, M, R flags set.
-    if (Node.NodeType.isGlobalNode() && isGlobalsGraph) {
-      ++NI;
-      continue;
-    }
-
-    if (Node.NodeType.isCompleteNode() && !Node.NodeType.isModifiedNode() && !Node.NodeType.isReadNode()) {
-      // This is a useless node if it has no mod/ref info (checked above),
-      // outgoing edges (which it cannot, as it is not modified in this
-      // context), and it has no incoming edges.  If it is a global node it may
-      // have all of these properties and still have incoming edges, due to the
-      // scalar map, so we check those now.
-      //
-      if (Node.getNumReferrers() == Node.numGlobals()) {
-
-        // Loop through and make sure all of the globals are referring directly
-        // to the node...
-        for (DSNode::globals_iterator j = Node.globals_begin(), e = Node.globals_end();
-             j != e; ++j) {
-          DSNode *N = getNodeForValue(*j).getNode();
-          assert(N == &Node && "ScalarMap doesn't match globals list!");
-        }
-
-        // Make sure NumReferrers still agrees, if so, the node is truly dead.
-        if (Node.getNumReferrers() == Node.numGlobals()) {
-          for (DSNode::globals_iterator j = Node.globals_begin(), e = Node.globals_end();
-               j != e; ++j) 
-            ScalarMap.erase(*j);
-          Node.makeNodeDead();
-          ++NumTrivialGlobalDNE;
-        }
-      }
-    }
-
-    if ((Node.getNodeFlags() == 0 && Node.hasNoReferrers())
-        || (isGlobalsGraph && Node.hasNoReferrers() && !Node.NodeType.isGlobalNode())){
-      // This node is dead!
-      NI = Nodes.erase(NI);    // Erase & remove from node list.
-      ++NumTrivialDNE;
-    } else {
-      ++NI;
-    }
-  }
-
-  removeIdenticalCalls(FunctionCalls);
-  removeIdenticalCalls(AuxFunctionCalls);
-}
-
-
-/// markReachableNodes - This method recursively traverses the specified
-/// DSNodes, marking any nodes which are reachable.  All reachable nodes it adds
-/// to the set, which allows it to only traverse visited nodes once.
-///
-void DSNode::markReachableNodes(hash_set<const DSNode*> &ReachableNodes) const {
-  if (this == 0) return;
-  assert(getForwardNode() == 0 && "Cannot mark a forwarded node!");
-  if (ReachableNodes.insert(this).second)        // Is newly reachable?
-    for (DSNode::const_edge_iterator I = edge_begin(), E = edge_end();
-         I != E; ++I)
-      I->getNode()->markReachableNodes(ReachableNodes);
-}
-
-void DSCallSite::markReachableNodes(hash_set<const DSNode*> &Nodes) const {
-  getRetVal().getNode()->markReachableNodes(Nodes);
-  if (isIndirectCall()) getCalleeNode()->markReachableNodes(Nodes);
-
-  for (unsigned i = 0, e = getNumPtrArgs(); i != e; ++i)
-    getPtrArg(i).getNode()->markReachableNodes(Nodes);
-}
-
-// CanReachAliveNodes - Simple graph walker that recursively traverses the graph
-// looking for a node that is marked alive.  If an alive node is found, return
-// true, otherwise return false.  If an alive node is reachable, this node is
-// marked as alive...
-//
-static bool CanReachAliveNodes(DSNode *N, hash_set<const DSNode*> &Alive,
-                               hash_set<const DSNode*> &Visited,
-                               bool IgnoreGlobals) {
-  if (N == 0) return false;
-  assert(N->getForwardNode() == 0 && "Cannot mark a forwarded node!");
-
-  // If this is a global node, it will end up in the globals graph anyway, so we
-  // don't need to worry about it.
-  if (IgnoreGlobals && N->NodeType.isGlobalNode()) return false;
-
-  // If we know that this node is alive, return so!
-  if (Alive.count(N)) return true;
-
-  // Otherwise, we don't think the node is alive yet, check for infinite
-  // recursion.
-  if (Visited.count(N)) return false;  // Found a cycle
-  Visited.insert(N);   // No recursion, insert into Visited...
-
-  for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
-    if (CanReachAliveNodes(I->getNode(), Alive, Visited, IgnoreGlobals)) {
-      N->markReachableNodes(Alive);
-      return true;
-    }
-  return false;
-}
-
-// CallSiteUsesAliveArgs - Return true if the specified call site can reach any
-// alive nodes.
-//
-static bool CallSiteUsesAliveArgs(const DSCallSite &CS,
-                                  hash_set<const DSNode*> &Alive,
-                                  hash_set<const DSNode*> &Visited,
-                                  bool IgnoreGlobals) {
-  if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited,
-                         IgnoreGlobals))
-    return true;
-  if (CS.isIndirectCall() &&
-      CanReachAliveNodes(CS.getCalleeNode(), Alive, Visited, IgnoreGlobals))
-    return true;
-  for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i)
-    if (CanReachAliveNodes(CS.getPtrArg(i).getNode(), Alive, Visited,
-                           IgnoreGlobals))
-      return true;
-  return false;
-}
-
-// removeDeadNodes - Use a more powerful reachability analysis to eliminate
-// subgraphs that are unreachable.  This often occurs because the data
-// structure doesn't "escape" into it's caller, and thus should be eliminated
-// from the caller's graph entirely.  This is only appropriate to use when
-// inlining graphs.
-//
-void DSGraph::removeDeadNodes(unsigned Flags) {
-  DEBUG(AssertGraphOK(); if (GlobalsGraph) GlobalsGraph->AssertGraphOK());
-
-  // Reduce the amount of work we have to do... remove dummy nodes left over by
-  // merging...
-  removeTriviallyDeadNodes();
-
-  // FIXME: Merge non-trivially identical call nodes...
-
-  // Alive - a set that holds all nodes found to be reachable/alive.
-  hash_set<const DSNode*> Alive;
-  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).
-  //
-  // Strip all alloca bits since the current function is only for the BU pass.
-  // Strip all incomplete bits since they are short-lived properties and they
-  // will be correctly computed when rematerializing nodes into the functions.
-  //
-  ReachabilityCloner GGCloner(GlobalsGraph, this, DSGraph::StripAllocaBit |
-                              DSGraph::StripIncompleteBit);
-
-  // Mark all nodes reachable by (non-global) scalar nodes as alive...
-  for (DSScalarMap::iterator I = ScalarMap.begin(), E = ScalarMap.end();
-       I != E; ++I)
-    if (isa<GlobalValue>(I->first)) {             // Keep track of global nodes
-      assert(!I->second.isNull() && "Null global node?");
-      assert(I->second.getNode()->NodeType.isGlobalNode() && "Should be a global node!");
-      GlobalNodes.push_back(std::make_pair(I->first, I->second.getNode()));
-
-      // Make sure that all globals are cloned over as roots.
-      if (!(Flags & DSGraph::RemoveUnreachableGlobals) && GlobalsGraph) {
-        DSGraph::ScalarMapTy::iterator SMI =
-          GlobalsGraph->getScalarMap().find(I->first);
-        if (SMI != GlobalsGraph->getScalarMap().end())
-          GGCloner.merge(SMI->second, I->second);
-        else
-          GGCloner.getClonedNH(I->second);
-      }
-    } else {
-      I->second.getNode()->markReachableNodes(Alive);
-    }
-
-  // The return values are alive as well.
-  for (ReturnNodesTy::iterator I = ReturnNodes.begin(), E = ReturnNodes.end();
-       I != E; ++I)
-    I->second.getNode()->markReachableNodes(Alive);
-
-  // Mark any nodes reachable by primary calls as alive...
-  for (fc_iterator I = fc_begin(), E = fc_end(); I != E; ++I)
-    I->markReachableNodes(Alive);
-
-
-  // Now find globals and aux call nodes that are already live or reach a live
-  // value (which makes them live in turn), and continue till no more are found.
-  //
-  bool Iterate;
-  hash_set<const DSNode*> Visited;
-  hash_set<const DSCallSite*> AuxFCallsAlive;
-  do {
-    Visited.clear();
-    // If any global node points to a non-global that is "alive", the global is
-    // "alive" as well...  Remove it from the GlobalNodes list so we only have
-    // unreachable globals in the list.
-    //
-    Iterate = false;
-    if (!(Flags & DSGraph::RemoveUnreachableGlobals))
-      for (unsigned i = 0; i != GlobalNodes.size(); ++i)
-        if (CanReachAliveNodes(GlobalNodes[i].second, Alive, Visited,
-                               Flags & DSGraph::RemoveUnreachableGlobals)) {
-          std::swap(GlobalNodes[i--], GlobalNodes.back()); // Move to end to...
-          GlobalNodes.pop_back();                          // erase efficiently
-          Iterate = true;
-        }
-
-    // Mark only unresolvable call nodes for moving to the GlobalsGraph since
-    // call nodes that get resolved will be difficult to remove from that graph.
-    // The final unresolved call nodes must be handled specially at the end of
-    // the BU pass (i.e., in main or other roots of the call graph).
-    for (afc_iterator CI = afc_begin(), E = afc_end(); CI != E; ++CI)
-      if (!AuxFCallsAlive.count(&*CI) &&
-          (CI->isIndirectCall()
-           || CallSiteUsesAliveArgs(*CI, Alive, Visited,
-                                  Flags & DSGraph::RemoveUnreachableGlobals))) {
-        CI->markReachableNodes(Alive);
-        AuxFCallsAlive.insert(&*CI);
-        Iterate = true;
-      }
-  } while (Iterate);
-
-  // Move dead aux function calls to the end of the list
-  for (std::list<DSCallSite>::iterator CI = AuxFunctionCalls.begin(),
-         E = AuxFunctionCalls.end(); CI != E; )
-    if (AuxFCallsAlive.count(&*CI))
-      ++CI;
-    else {
-      // Copy and merge global nodes and dead aux call nodes into the
-      // GlobalsGraph, and all nodes reachable from those nodes.  Update their
-      // target pointers using the GGCloner.
-      //
-      if (!(Flags & DSGraph::RemoveUnreachableGlobals))
-        GlobalsGraph->AuxFunctionCalls.push_back(DSCallSite(*CI, GGCloner));
-
-      AuxFunctionCalls.erase(CI++);
-    }
-
-  // We are finally done with the GGCloner so we can destroy it.
-  GGCloner.destroy();
-
-  // At this point, any nodes which are visited, but not alive, are nodes
-  // which can be removed.  Loop over all nodes, eliminating completely
-  // unreachable nodes.
-  //
-  std::vector<DSNode*> DeadNodes;
-  DeadNodes.reserve(Nodes.size());
-  for (NodeListTy::iterator NI = Nodes.begin(), E = Nodes.end(); NI != E;) {
-    DSNode *N = NI++;
-    assert(!N->isForwarding() && "Forwarded node in nodes list?");
-
-    if (!Alive.count(N)) {
-      Nodes.remove(N);
-      assert(!N->isForwarding() && "Cannot remove a forwarding node!");
-      DeadNodes.push_back(N);
-      N->dropAllReferences();
-      ++NumDNE;
-    }
-  }
-
-  // Remove all unreachable globals from the ScalarMap.
-  // If flag RemoveUnreachableGlobals is set, GlobalNodes has only dead nodes.
-  // In either case, the dead nodes will not be in the set Alive.
-  for (unsigned i = 0, e = GlobalNodes.size(); i != e; ++i)
-    if (!Alive.count(GlobalNodes[i].second))
-      ScalarMap.erase(GlobalNodes[i].first);
-    else
-      assert((Flags & DSGraph::RemoveUnreachableGlobals) && "non-dead global");
-
-  // Delete all dead nodes now since their referrer counts are zero.
-  for (unsigned i = 0, e = DeadNodes.size(); i != e; ++i)
-    delete DeadNodes[i];
-
-  DEBUG(AssertGraphOK(); GlobalsGraph->AssertGraphOK());
-}
-
-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!");
-}
-
-void DSGraph::AssertCallSiteInGraph(const DSCallSite &CS) const {
-  if (CS.isIndirectCall()) {
-    AssertNodeInGraph(CS.getCalleeNode());
-#if 0
-    if (CS.getNumPtrArgs() && CS.getCalleeNode() == CS.getPtrArg(0).getNode() &&
-        CS.getCalleeNode() && CS.getCalleeNode()->getGlobals().empty())
-      DOUT << "WARNING: WEIRD CALL SITE FOUND!\n";
-#endif
-  }
-  AssertNodeInGraph(CS.getRetVal().getNode());
-  for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j)
-    AssertNodeInGraph(CS.getPtrArg(j).getNode());
-}
-
-void DSGraph::AssertCallNodesInGraph() const {
-  for (fc_iterator I = fc_begin(), E = fc_end(); I != E; ++I)
-    AssertCallSiteInGraph(*I);
-}
-void DSGraph::AssertAuxCallNodesInGraph() const {
-  for (afc_const_iterator I = afc_begin(), E = afc_end(); I != E; ++I)
-    AssertCallSiteInGraph(*I);
-}
-
-void DSGraph::AssertGraphOK() const {
-  for (node_const_iterator NI = node_begin(), E = node_end(); NI != E; ++NI)
-    NI->assertOK();
-
-  for (ScalarMapTy::const_iterator I = ScalarMap.begin(),
-         E = ScalarMap.end(); I != E; ++I) {
-    assert(!I->second.isNull() && "Null node in scalarmap!");
-    AssertNodeInGraph(I->second.getNode());
-    if (const GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
-      assert(I->second.getNode()->NodeType.isGlobalNode() &&
-             "Global points to node, but node isn't global?");
-      AssertNodeContainsGlobal(I->second.getNode(), GV);
-    }
-  }
-  AssertCallNodesInGraph();
-  AssertAuxCallNodesInGraph();
-
-  // Check that all pointer arguments to any functions in this graph have
-  // destinations.
-  for (ReturnNodesTy::const_iterator RI = ReturnNodes.begin(),
-         E = ReturnNodes.end();
-       RI != E; ++RI) {
-    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!");
-  }
-}
-
-/// computeNodeMapping - Given roots in two different DSGraphs, traverse the
-/// nodes reachable from the two graphs, computing the mapping of nodes from the
-/// first to the second graph.  This mapping may be many-to-one (i.e. the first
-/// graph may have multiple nodes representing one node in the second graph),
-/// but it will not work if there is a one-to-many or many-to-many mapping.
-///
-void DSGraph::computeNodeMapping(const DSNodeHandle &NH1,
-                                 const DSNodeHandle &NH2, NodeMapTy &NodeMap,
-                                 bool StrictChecking) {
-  DSNode *N1 = NH1.getNode(), *N2 = NH2.getNode();
-  if (N1 == 0 || N2 == 0) return;
-
-  DSNodeHandle &Entry = NodeMap[N1];
-  if (!Entry.isNull()) {
-    // Termination of recursion!
-    if (StrictChecking) {
-      assert(Entry.getNode() == N2 && "Inconsistent mapping detected!");
-      assert((Entry.getOffset() == (NH2.getOffset()-NH1.getOffset()) ||
-              Entry.getNode()->isNodeCompletelyFolded()) &&
-             "Inconsistent mapping detected!");
-    }
-    return;
-  }
-
-  Entry.setTo(N2, NH2.getOffset()-NH1.getOffset());
-
-  // Loop over all of the fields that N1 and N2 have in common, recursively
-  // mapping the edges together now.
-  int N2Idx = NH2.getOffset()-NH1.getOffset();
-  unsigned N2Size = N2->getSize();
-  if (N2Size == 0) return;   // No edges to map to.
-
-  for (unsigned i = 0, e = N1->getSize(); i < e; i += 1) {
-    const DSNodeHandle &N1NH = N1->getLink(i);
-    // Don't call N2->getLink if not needed (avoiding crash if N2Idx is not
-    // aligned right).
-    if (!N1NH.isNull()) {
-      if (unsigned(N2Idx)+i < N2Size)
-        computeNodeMapping(N1NH, N2->getLink(N2Idx+i), NodeMap);
-      else
-        computeNodeMapping(N1NH,
-                           N2->getLink(unsigned(N2Idx+i) % N2Size), NodeMap);
-    }
-  }
-}
-
-
-/// computeGToGGMapping - Compute the mapping of nodes in the global graph to
-/// nodes in this graph.
-void DSGraph::computeGToGGMapping(NodeMapTy &NodeMap) {
-  DSGraph &GG = *getGlobalsGraph();
-
-  DSScalarMap &SM = getScalarMap();
-  for (DSScalarMap::global_iterator I = SM.global_begin(),
-         E = SM.global_end(); I != E; ++I)
-    DSGraph::computeNodeMapping(SM[*I], GG.getNodeForValue(*I), NodeMap);
-}
-
-/// computeGGToGMapping - Compute the mapping of nodes in the global graph to
-/// nodes in this graph.  Note that any uses of this method are probably bugs,
-/// unless it is known that the globals graph has been merged into this graph!
-void DSGraph::computeGGToGMapping(InvNodeMapTy &InvNodeMap) {
-  NodeMapTy NodeMap;
-  computeGToGGMapping(NodeMap);
-
-  while (!NodeMap.empty()) {
-    InvNodeMap.insert(std::make_pair(NodeMap.begin()->second,
-                                     NodeMap.begin()->first));
-    NodeMap.erase(NodeMap.begin());
-  }
-}
-
-
-/// computeCalleeCallerMapping - Given a call from a function in the current
-/// graph to the 'Callee' function (which lives in 'CalleeGraph'), compute the
-/// mapping of nodes from the callee to nodes in the caller.
-void DSGraph::computeCalleeCallerMapping(DSCallSite CS, const Function &Callee,
-                                         DSGraph &CalleeGraph,
-                                         NodeMapTy &NodeMap) {
-
-  DSCallSite CalleeArgs =
-    CalleeGraph.getCallSiteForArguments(const_cast<Function&>(Callee));
-
-  computeNodeMapping(CalleeArgs.getRetVal(), CS.getRetVal(), NodeMap);
-
-  unsigned NumArgs = CS.getNumPtrArgs();
-  if (NumArgs > CalleeArgs.getNumPtrArgs())
-    NumArgs = CalleeArgs.getNumPtrArgs();
-
-  for (unsigned i = 0; i != NumArgs; ++i)
-    computeNodeMapping(CalleeArgs.getPtrArg(i), CS.getPtrArg(i), NodeMap);
-
-  // Map the nodes that are pointed to by globals.
-  DSScalarMap &CalleeSM = CalleeGraph.getScalarMap();
-  DSScalarMap &CallerSM = getScalarMap();
-
-  if (CalleeSM.global_size() >= CallerSM.global_size()) {
-    for (DSScalarMap::global_iterator GI = CallerSM.global_begin(),
-           E = CallerSM.global_end(); GI != E; ++GI)
-      if (CalleeSM.global_count(*GI))
-        computeNodeMapping(CalleeSM[*GI], CallerSM[*GI], NodeMap);
-  } else {
-    for (DSScalarMap::global_iterator GI = CalleeSM.global_begin(),
-           E = CalleeSM.global_end(); GI != E; ++GI)
-      if (CallerSM.global_count(*GI))
-        computeNodeMapping(CalleeSM[*GI], CallerSM[*GI], NodeMap);
-  }
-}
-
-/// updateFromGlobalGraph - This function rematerializes global nodes and
-/// nodes reachable from them from the globals graph into the current graph.
-///
-void DSGraph::updateFromGlobalGraph() {
-  ReachabilityCloner RC(this, GlobalsGraph, 0);
-
-  // Clone the non-up-to-date global nodes into this graph.
-  for (DSScalarMap::global_iterator I = getScalarMap().global_begin(),
-         E = getScalarMap().global_end(); I != E; ++I) {
-    DSScalarMap::iterator It = GlobalsGraph->ScalarMap.find(*I);
-    if (It != GlobalsGraph->ScalarMap.end())
-      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, GlobalsGraph, 0);
-    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)) {
-    getDSGraph(F)->getScalarMap().copyScalarIfExists(From, To);
-    return;
-  }
-  
-  cerr << *From;
-  cerr << *To;
-  assert(0 && "Do not know how to copy this yet!");
-  abort();
-}
-
-DSGraph* DataStructures::getOrFetchDSGraph(const 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, GlobalsGraph, 
-		      DSGraph::DontCloneAuxCallNodes);
-    } else {
-      G = new DSGraph(GlobalECs, GraphSource->getDataLayout(),
-		      GlobalsGraph);
-      G->spliceFrom(BaseGraph);
-      if (resetAuxCalls) 
-        G->getAuxFunctionCalls() = G->getFunctionCalls();
-    }
-    G->setUseAuxCalls();
-    
-    // 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;
-}
-
-
-/// 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(std::vector<const GlobalValue*> &ECGlobals,
-                           DSGraph* G) {
-  DSGraph::ScalarMapTy& SM = G->getScalarMap();
-  EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
-  for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end();
-       I != E; ++I) {
-    if (I->numGlobals() <= 1) continue;
-
-    // First, build up the equivalence set for this block of globals.
-    DSNode::globals_iterator i = I->globals_begin(); 
-    const GlobalValue *First = *i;
-    if (GlobalECs.findValue(*i) != GlobalECs.end())
-      First = GlobalECs.getLeaderValue(*i);
-    if (*i == First) ++i;
-    for( ; i != I->globals_end(); ++i) {
-      GlobalECs.unionSets(First, *i);
-      ECGlobals.push_back(*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);
-  }
-}
-
-/// 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::vector<const GlobalValue*> &ECGlobals) {
-  DSScalarMap &SM = G.getScalarMap();
-  EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
-
-  for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
-       GI != E; ) {
-    const GlobalValue *GV = *GI++;
-    if (!binary_search(ECGlobals.begin(), ECGlobals.end(), 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.
-    const 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);
-  }
-
-  DEBUG(G.AssertGraphOK());
-}
-
-void DataStructures::formGlobalECs() {
-  // Grow the equivalence classes for the globals to include anything that we
-  // now know to be aliased.
-  std::vector<const GlobalValue*> ECGlobals;
-  buildGlobalECs(ECGlobals, GlobalsGraph);
-  DEBUG(GlobalsGraph->AssertGraphOK());
-  if (!ECGlobals.empty()) {
-    std::sort(ECGlobals.begin(), ECGlobals.end());
-    std::vector<const GlobalValue*>::iterator erpoint =
-      std::unique(ECGlobals.begin(), ECGlobals.end());
-    ECGlobals.resize(erpoint - ECGlobals.begin());
-    DEBUG(errs() << "Eliminating " << ECGlobals.size() << " EC Globals!\n";);
-    for (DSInfoTy::iterator I = DSInfo.begin(),
-           E = DSInfo.end(); I != E; ++I)
-      eliminateUsesOfECGlobals(*I->second, ECGlobals);
-  }
-}
-
-void DataStructures::init(DataStructures* D, bool clone, bool useAuxCalls, 
-                          bool copyGlobalAuxCalls, bool resetAux) {
-  assert (!GraphSource && "Already init");
-  GraphSource = D;
-  Clone = clone;
-  resetAuxCalls = resetAux;
-  TD = D->TD;
-  callee = D->callee;
-  GlobalECs = D->getGlobalECs();
-  GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs, 0,
-                             copyGlobalAuxCalls?0:DSGraph::DontCloneAuxCallNodes);
-  if (useAuxCalls) GlobalsGraph->setUseAuxCalls();
-
-  //
-  // Tell the other DSA pass if we're stealing its graph.
-  //
-  if (!clone) D->DSGraphsStolen = true;
-}
-
-void DataStructures::init(DataLayout* T) {
-  assert (!TD && "Already init");
-  GraphSource = 0;
-  Clone = false;
-  TD = T;
-  GlobalsGraph = new DSGraph(GlobalECs, *T, 0);
-}
-
-void DataStructures::releaseMemory() {
-  //
-  // If the DSGraphs were stolen by another pass, free nothing.
-  //
-  if (DSGraphsStolen) return;
-
-  hash_set<DSGraph*> toDelete;
-  for (DSInfoTy::iterator I = DSInfo.begin(), E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().clear();
-    toDelete.insert(I->second);
-  }
-  for (hash_set<DSGraph*>::iterator I = toDelete.begin(), E = toDelete.end(); I != E; ++I)
-    delete *I;
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  callee.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
diff --git a/poolalloc/lib/rDSA/DataStructureAA.cpp b/poolalloc/lib/rDSA/DataStructureAA.cpp
deleted file mode 100644
index 994475f..0000000
--- a/poolalloc/lib/rDSA/DataStructureAA.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-//===- DataStructureAA.cpp - Data Structure Based Alias Analysis ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass uses the top-down data structure graphs to implement a simple
-// context sensitive alias analysis.
-//
-//===----------------------------------------------------------------------===//
-
-
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/Passes.h"
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-using namespace llvm;
-
-namespace {
-  class DSAA : public ModulePass, public AliasAnalysis {
-    TDDataStructures *TD;
-    BUDataStructures *BU;
-
-    // These members are used to cache mod/ref information to make us return
-    // results faster, particularly for aa-eval.  On the first request of
-    // mod/ref information for a particular call site, we compute and store the
-    // calculated nodemap for the call site.  Any time DSA info is updated we
-    // free this information, and when we move onto a new call site, this
-    // information is also freed.
-    CallSite MapCS;
-    std::multimap<DSNode*, const DSNode*> CallerCalleeMap;
-  public:
-    static char ID;
-    DSAA() : ModulePass((intptr_t)&ID), TD(0) {}
-    ~DSAA() {
-      InvalidateCache();
-    }
-
-    void InvalidateCache() {
-      MapCS = CallSite();
-      CallerCalleeMap.clear();
-    }
-
-    //------------------------------------------------
-    // Implement the Pass API
-    //
-
-    // run - Build up the result graph, representing the pointer graph for the
-    // program.
-    //
-    bool runOnModule(Module &M) {
-      InitializeAliasAnalysis(this);
-      TD = &getAnalysis<TDDataStructures>();
-      BU = &getAnalysis<BUDataStructures>();
-      return false;
-    }
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AliasAnalysis::getAnalysisUsage(AU);
-      AU.setPreservesAll();                         // Does not transform code
-      AU.addRequiredTransitive<TDDataStructures>(); // Uses TD Datastructures
-      AU.addRequiredTransitive<BUDataStructures>(); // Uses BU Datastructures
-    }
-
-    //------------------------------------------------
-    // Implement the AliasAnalysis API
-    //
-
-    AliasResult alias(const Value *V1, unsigned V1Size,
-                      const Value *V2, unsigned V2Size);
-
-    ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
-    ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
-      return AliasAnalysis::getModRefInfo(CS1,CS2);
-    }
-
-    virtual void deleteValue(Value *V) {
-      InvalidateCache();
-      BU->deleteValue(V);
-      TD->deleteValue(V);
-    }
-
-    virtual void copyValue(Value *From, Value *To) {
-      if (From == To) return;
-      InvalidateCache();
-      BU->copyValue(From, To);
-      TD->copyValue(From, To);
-    }
-
-  private:
-    DSGraph *getGraphForValue(const Value *V);
-  };
-
-  // Register the pass...
-  RegisterPass<DSAA> X("ds-aa", "Data Structure Graph Based Alias Analysis");
-
-  // Register as an implementation of AliasAnalysis
-  RegisterAnalysisGroup<AliasAnalysis> Y(X);
-}
-
-char DSAA::ID;
-
-ModulePass *llvm::createDSAAPass() { return new DSAA(); }
-
-// getGraphForValue - Return the DSGraph to use for queries about the specified
-// value...
-//
-DSGraph *DSAA::getGraphForValue(const Value *V) {
-  if (const Instruction *I = dyn_cast<Instruction>(V))
-    return TD->getDSGraph(I->getParent()->getParent());
-  else if (const Argument *A = dyn_cast<Argument>(V))
-    return TD->getDSGraph(A->getParent());
-  else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
-    return TD->getDSGraph(BB->getParent());
-  return 0;
-}
-
-AliasAnalysis::AliasResult DSAA::alias(const Value *V1, unsigned V1Size,
-                                       const Value *V2, unsigned V2Size) {
-  if (V1 == V2) return MustAlias;
-
-  DSGraph *G1 = getGraphForValue(V1);
-  DSGraph *G2 = getGraphForValue(V2);
-  assert((!G1 || !G2 || G1 == G2) && "Alias query for 2 different functions?");
-
-  // Get the graph to use...
-  DSGraph* G = G1 ? G1 : (G2 ? G2 : TD->getGlobalsGraph());
-
-  const DSGraph::ScalarMapTy &GSM = G->getScalarMap();
-  DSGraph::ScalarMapTy::const_iterator I = GSM.find((Value*)V1);
-  if (I == GSM.end()) return NoAlias;
-
-  DSGraph::ScalarMapTy::const_iterator J = GSM.find((Value*)V2);
-  if (J == GSM.end()) return NoAlias;
-
-  DSNode  *N1 = I->second.getNode(),  *N2 = J->second.getNode();
-  unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset();
-  if (N1 == 0 || N2 == 0)
-    // Can't tell whether anything aliases null.
-    return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
-
-  // We can only make a judgment if one of the nodes is complete.
-  if (N1->NodeType.isCompleteNode() || N2->NodeType.isCompleteNode()) {
-    if (N1 != N2)
-      return NoAlias;   // Completely different nodes.
-
-    // See if they point to different offsets...  if so, we may be able to
-    // determine that they do not alias...
-    if (O1 != O2) {
-      if (O2 < O1) {    // Ensure that O1 <= O2
-        std::swap(V1, V2);
-        std::swap(O1, O2);
-        std::swap(V1Size, V2Size);
-      }
-
-      if (O1+V1Size <= O2)
-        return NoAlias;
-    }
-  }
-
-  // FIXME: we could improve on this by checking the globals graph for aliased
-  // global queries...
-  return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
-}
-
-/// getModRefInfo - does a callsite modify or reference a value?
-///
-AliasAnalysis::ModRefResult
-DSAA::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
-  DSNode *N = 0;
-  // First step, check our cache.
-  if (CS.getInstruction() == MapCS.getInstruction()) {
-    {
-      const Function *Caller = CS.getInstruction()->getParent()->getParent();
-      DSGraph* CallerTDGraph = TD->getDSGraph(Caller);
-
-      // Figure out which node in the TD graph this pointer corresponds to.
-      DSScalarMap &CallerSM = CallerTDGraph->getScalarMap();
-      DSScalarMap::iterator NI = CallerSM.find(P);
-      if (NI == CallerSM.end()) {
-        InvalidateCache();
-        return DSAA::getModRefInfo(CS, P, Size);
-      }
-      N = NI->second.getNode();
-    }
-
-  HaveMappingInfo:
-    assert(N && "Null pointer in scalar map??");
-
-    typedef std::multimap<DSNode*, const DSNode*>::iterator NodeMapIt;
-    std::pair<NodeMapIt, NodeMapIt> Range = CallerCalleeMap.equal_range(N);
-
-    // Loop over all of the nodes in the callee that correspond to "N", keeping
-    // track of aggregate mod/ref info.
-    bool NeverReads = true, NeverWrites = true;
-    for (; Range.first != Range.second; ++Range.first) {
-      if (Range.first->second->NodeType.isModifiedNode())
-        NeverWrites = false;
-      if (Range.first->second->NodeType.isReadNode())
-        NeverReads = false;
-      if (NeverReads == false && NeverWrites == false)
-        return AliasAnalysis::getModRefInfo(CS, P, Size);
-    }
-
-    ModRefResult Result = ModRef;
-    if (NeverWrites)      // We proved it was not modified.
-      Result = ModRefResult(Result & ~Mod);
-    if (NeverReads)       // We proved it was not read.
-      Result = ModRefResult(Result & ~Ref);
-
-    return ModRefResult(Result & AliasAnalysis::getModRefInfo(CS, P, Size));
-  }
-
-  // Any cached info we have is for the wrong function.
-  InvalidateCache();
-
-  Function *F = CS.getCalledFunction();
-
-  if (!F) return AliasAnalysis::getModRefInfo(CS, P, Size);
-
-  if (F->isDeclaration()) {
-    // If we are calling an external function, and if this global doesn't escape
-    // the portion of the program we have analyzed, we can draw conclusions
-    // based on whether the global escapes the program.
-    Function *Caller = CS.getInstruction()->getParent()->getParent();
-    DSGraph *G = TD->getDSGraph(Caller);
-    DSScalarMap::iterator NI = G->getScalarMap().find(P);
-    if (NI == G->getScalarMap().end()) {
-      // If it wasn't in the local function graph, check the global graph.  This
-      // can occur for globals who are locally reference but hoisted out to the
-      // globals graph despite that.
-      G = G->getGlobalsGraph();
-      NI = G->getScalarMap().find(P);
-      if (NI == G->getScalarMap().end())
-        return AliasAnalysis::getModRefInfo(CS, P, Size);
-    }
-
-    // If we found a node and it's complete, it cannot be passed out to the
-    // called function.
-    if (NI->second.getNode()->NodeType.isCompleteNode())
-      return NoModRef;
-    return AliasAnalysis::getModRefInfo(CS, P, Size);
-  }
-
-  // Get the graphs for the callee and caller.  Note that we want the BU graph
-  // for the callee because we don't want all caller's effects incorporated!
-  const Function *Caller = CS.getInstruction()->getParent()->getParent();
-  DSGraph* CallerTDGraph = TD->getDSGraph(Caller);
-  DSGraph* CalleeBUGraph = BU->getDSGraph(F);
-
-  // Figure out which node in the TD graph this pointer corresponds to.
-  DSScalarMap &CallerSM = CallerTDGraph->getScalarMap();
-  DSScalarMap::iterator NI = CallerSM.find(P);
-  if (NI == CallerSM.end()) {
-    ModRefResult Result = ModRef;
-    if (isa<ConstantPointerNull>(P) || isa<UndefValue>(P))
-      return NoModRef;                 // null is never modified :)
-    else {
-      assert(isa<GlobalVariable>(P) &&
-    cast<GlobalVariable>(P)->getType()->getElementType()->isFirstClassType() &&
-             "This isn't a global that DSA inconsiderately dropped "
-             "from the graph?");
-
-      DSGraph* GG = CallerTDGraph->getGlobalsGraph();
-      DSScalarMap::iterator NI = GG->getScalarMap().find(P);
-      if (NI != GG->getScalarMap().end() && !NI->second.isNull()) {
-        // Otherwise, if the node is only M or R, return this.  This can be
-        // useful for globals that should be marked const but are not.
-        DSNode *N = NI->second.getNode();
-        if (!N->NodeType.isModifiedNode())
-          Result = (ModRefResult)(Result & ~Mod);
-        if (!N->NodeType.isReadNode())
-          Result = (ModRefResult)(Result & ~Ref);
-      }
-    }
-
-    if (Result == NoModRef) return Result;
-    return ModRefResult(Result & AliasAnalysis::getModRefInfo(CS, P, Size));
-  }
-
-  // Compute the mapping from nodes in the callee graph to the nodes in the
-  // caller graph for this call site.
-  DSGraph::NodeMapTy CalleeCallerMap;
-  DSCallSite DSCS = CallerTDGraph->getDSCallSiteForCallSite(CS);
-  CallerTDGraph->computeCalleeCallerMapping(DSCS, *F, *CalleeBUGraph,
-                                            CalleeCallerMap);
-
-  // Remember the mapping and the call site for future queries.
-  MapCS = CS;
-
-  // Invert the mapping into CalleeCallerInvMap.
-  for (DSGraph::NodeMapTy::iterator I = CalleeCallerMap.begin(),
-         E = CalleeCallerMap.end(); I != E; ++I)
-    CallerCalleeMap.insert(std::make_pair(I->second.getNode(), I->first));
-
-  N = NI->second.getNode();
-  goto HaveMappingInfo;
-}
diff --git a/poolalloc/lib/rDSA/DataStructureOpt.cpp b/poolalloc/lib/rDSA/DataStructureOpt.cpp
deleted file mode 100644
index ecfa209..0000000
--- a/poolalloc/lib/rDSA/DataStructureOpt.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//===- DataStructureOpt.cpp - Data Structure Analysis Based Optimizations -===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass uses DSA to a series of simple optimizations, like marking
-// unwritten global variables 'constant'.
-//
-//===----------------------------------------------------------------------===//
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Module.h"
-#include "llvm/Constant.h"
-#include "llvm/Constants.h"
-#include "llvm/Type.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Debug.h"
-using namespace llvm;
-
-namespace {
-  STATISTIC (NumGlobalsConstanted, "Number of globals marked constant");
-  STATISTIC (NumGlobalsIsolated, "Number of globals with references dropped");
-
-  class DSOpt : public ModulePass {
-    TDDataStructures *TD;
-  public:
-    static char ID;
-    DSOpt() : ModulePass((intptr_t)&ID) {};
-
-    bool runOnModule(Module &M) {
-      TD = &getAnalysis<TDDataStructures>();
-      bool Changed = OptimizeGlobals(M);
-      return Changed;
-    }
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.addRequired<TDDataStructures>();      // Uses TD Datastructures
-      AU.addPreserved<LocalDataStructures>();  // Preserves local...
-      AU.addPreserved<TDDataStructures>();     // Preserves bu...
-      AU.addPreserved<BUDataStructures>();     // Preserves td...
-    }
-
-  private:
-    bool OptimizeGlobals(Module &M);
-  };
-
-  RegisterPass<DSOpt> X("ds-opt", "DSA-based simple optimizations");
-}
-
-char DSOpt::ID;
-
-ModulePass *llvm::createDSOptPass() { return new DSOpt(); }
-
-/// OptimizeGlobals - This method uses information taken from DSA to optimize
-/// global variables.
-///
-bool DSOpt::OptimizeGlobals(Module &M) {
-  DSGraph* GG = TD->getGlobalsGraph();
-  const DSGraph::ScalarMapTy &SM = GG->getScalarMap();
-  bool Changed = false;
-
-  for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
-    if (!I->isDeclaration()) { // Loop over all of the non-external globals...
-      // Look up the node corresponding to this global, if it exists.
-      DSNode *GNode = 0;
-      DSGraph::ScalarMapTy::const_iterator SMI = SM.find(I);
-      if (SMI != SM.end()) GNode = SMI->second.getNode();
-
-      if (GNode == 0 && I->hasInternalLinkage()) {
-        // If there is no entry in the scalar map for this global, it was never
-        // referenced in the program.  If it has internal linkage, that means we
-        // can delete it.  We don't ACTUALLY want to delete the global, just
-        // remove anything that references the global: later passes will take
-        // care of nuking it.
-        if (!I->use_empty()) {
-          I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
-          ++NumGlobalsIsolated;
-        }
-      } else if (GNode && GNode->NodeType.isCompleteNode()) {
-
-        // If the node has not been read or written, and it is not externally
-        // visible, kill any references to it so it can be DCE'd.
-        if (!GNode->NodeType.isModifiedNode() && !GNode->NodeType.isReadNode() &&I->hasInternalLinkage()){
-          if (!I->use_empty()) {
-            I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
-            ++NumGlobalsIsolated;
-          }
-        }
-
-        // We expect that there will almost always be a node for this global.
-        // If there is, and the node doesn't have the M bit set, we can set the
-        // 'constant' bit on the global.
-        if (!GNode->NodeType.isModifiedNode() && !I->isConstant()) {
-          I->setConstant(true);
-          ++NumGlobalsConstanted;
-          Changed = true;
-        }
-      }
-    }
-  return Changed;
-}
diff --git a/poolalloc/lib/rDSA/DataStructureStats.cpp b/poolalloc/lib/rDSA/DataStructureStats.cpp
deleted file mode 100644
index 3e9679b..0000000
--- a/poolalloc/lib/rDSA/DataStructureStats.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-//===- DataStructureStats.cpp - Various statistics for DS Graphs ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a little pass that prints out statistics for DS Graphs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FormattedStream.h"
-
-#include <ostream>
-using namespace llvm;
-
-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");
-
-  // 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),
-  // increment the appropriate counter.
-  STATISTIC (NumTypedMemAccesses,
-                                "Number of loads/stores which are fully typed");
-  STATISTIC (NumUntypedMemAccesses,
-                                "Number of loads/stores which are untyped");
-
-  class DSGraphStats : public FunctionPass, public InstVisitor<DSGraphStats> {
-    void countCallees(const Function* F);
-    const DSGraph *TDGraph;
-
-    DSNode *getNodeForValue(Value *V);
-    bool isNodeForValueCollapsed(Value *V);
-  public:
-    static char ID;
-    DSGraphStats() : FunctionPass((intptr_t)&ID) {}
-
-    /// Driver functions to compute the Load/Store Dep. Graph per function.
-    bool runOnFunction(Function& F);
-
-    /// getAnalysisUsage - This modify nothing, and uses the Top-Down Graph.
-    void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.setPreservesAll();
-      AU.addRequired<TDDataStructures>();
-    }
-
-    void visitLoad(LoadInst &LI);
-    void visitStore(StoreInst &SI);
-
-    /// Debugging support methods
-    void print(std::ostream &O, const Module* = 0) const { }
-  };
-
-  static RegisterPass<DSGraphStats> Z("dsstats", "DS Graph Statistics");
-}
-
-char DSGraphStats::ID;
-
-FunctionPass *llvm::createDataStructureStatsPass() { 
-  return new DSGraphStats();
-}
-
-
-static bool isIndirectCallee(Value *V) {
-  if (isa<Function>(V)) return false;
-
-  if (CastInst *CI = dyn_cast<CastInst>(V))
-    return isIndirectCallee(CI->getOperand(0));
-  return true;
-}
-
-
-void DSGraphStats::countCallees(const Function* F) {
-  unsigned numIndirectCalls = 0, totalNumCallees = 0;
-
-  for (DSGraph::fc_iterator I = TDGraph->fc_begin(), E = TDGraph->fc_end();
-       I != E; ++I)
-    if (isIndirectCallee(I->getCallSite().getCalledValue())) {
-      // This is an indirect function call
-      std::vector<const Function*> Callees;
-      I->getCalleeNode()->addFullFunctionList(Callees);
-
-      if (Callees.size() > 0) {
-        totalNumCallees  += Callees.size();
-        ++numIndirectCalls;
-      } else {
-        DEBUG(errs() << "WARNING: No callee in Function '" 
-	      << F->getNameStr() << "' at call: \n"
-	      << *I->getCallSite().getInstruction());
-      }
-    }
-
-  TotalNumCallees  += totalNumCallees;
-  NumIndirectCalls += numIndirectCalls;
-
-  if (numIndirectCalls) {
-    DEBUG(errs() << "  In function " << F->getName() << ":  "
-	  << (totalNumCallees / (double) numIndirectCalls)
-	  << " average callees per indirect call\n");
-  }
-}
-
-DSNode *DSGraphStats::getNodeForValue(Value *V) {
-  const DSGraph *G = TDGraph;
-  if (isa<Constant>(V))
-    G = TDGraph->getGlobalsGraph();
-
-  const DSGraph::ScalarMapTy &ScalarMap = G->getScalarMap();
-  DSGraph::ScalarMapTy::const_iterator I = ScalarMap.find(V);
-  if (I != ScalarMap.end())
-    return I->second.getNode();
-  return 0;
-}
-
-bool DSGraphStats::isNodeForValueCollapsed(Value *V) {
-  if (DSNode *N = getNodeForValue(V))
-    return N->isNodeCompletelyFolded() || N->NodeType.isIncompleteNode();
-  return false;
-}
-
-void DSGraphStats::visitLoad(LoadInst &LI) {
-  if (isNodeForValueCollapsed(LI.getOperand(0))) {
-    NumUntypedMemAccesses++;
-  } else {
-    NumTypedMemAccesses++;
-  }
-}
-
-void DSGraphStats::visitStore(StoreInst &SI) {
-  if (isNodeForValueCollapsed(SI.getOperand(1))) {
-    NumUntypedMemAccesses++;
-  } else {
-    NumTypedMemAccesses++;
-  }
-}
-
-
-
-bool DSGraphStats::runOnFunction(Function& F) {
-  TDGraph = getAnalysis<TDDataStructures>().getDSGraph(&F);
-  countCallees(&F);
-  visit(F);
-  return true;
-}
diff --git a/poolalloc/lib/rDSA/EquivClassGraphs.cpp b/poolalloc/lib/rDSA/EquivClassGraphs.cpp
deleted file mode 100644
index 5c02866..0000000
--- a/poolalloc/lib/rDSA/EquivClassGraphs.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===- EquivClassGraphs.cpp - Merge equiv-class graphs & inline bottom-up -===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass is the same as the complete bottom-up graphs, but
-// with functions partitioned into equivalence classes and a single merged
-// DS graph for all functions in an equivalence class.  After this merging,
-// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "ECGraphs"
-#include "rdsa/DataStructure.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/IR/CallSite.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/SCCIterator.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/EquivalenceClasses.h"
-#include "llvm/ADT/STLExtras.h"
-using namespace llvm;
-
-namespace {
-  RegisterPass<EquivBUDataStructures> X("dsa-eq",
-                    "Equivalence-class Bottom-up Data Structure Analysis");
-}
-
-char EquivBUDataStructures::ID = 0;
-
-// runOnModule - Calculate the bottom up data structure graphs for each function
-// in the program.
-//
-bool EquivBUDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<CompleteBUDataStructures>(), false, true, false, true);
-
-  //update the EQ class from indirect calls
-  buildIndirectFunctionSets(M);
-
-  mergeGraphsByGlobalECs();
-
-  return runOnModuleInternal(M);
-}
-
-
-// Merge all graphs that are in the same equivalence class
-// the ensures things like poolalloc only deal with one graph for a 
-// call site
-void EquivBUDataStructures::mergeGraphsByGlobalECs() {
-  // Merge the graphs for each equivalence class.
-  //
-  for (EquivalenceClasses<const GlobalValue*>::iterator EQSI = GlobalECs.begin(), 
-         EQSE = GlobalECs.end(); EQSI != EQSE; ++EQSI) {
-    if (!EQSI->isLeader()) continue;
-    DSGraph* BaseGraph = 0;
-    std::vector<DSNodeHandle> Args;
-    for (EquivalenceClasses<const GlobalValue*>::member_iterator MI = GlobalECs.member_begin(EQSI);
-         MI != GlobalECs.member_end(); ++MI) {
-      if (const Function* F = dyn_cast<Function>(*MI)) {
-        if (!BaseGraph) {
-          BaseGraph = getOrFetchDSGraph(F);
-          BaseGraph->getFunctionArgumentsForCall(F, Args);
-        } else if (BaseGraph->containsFunction(F)) {
-          //already merged
-        } else {
-          std::vector<DSNodeHandle> NextArgs;
-          BaseGraph->cloneInto(getOrFetchDSGraph(F));
-          BaseGraph->getFunctionArgumentsForCall(F, 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]);
-          setDSGraph(F, BaseGraph);
-        }       
-      }
-    }
-  }
-}
-
diff --git a/poolalloc/lib/rDSA/GraphChecker.cpp b/poolalloc/lib/rDSA/GraphChecker.cpp
deleted file mode 100644
index 89d2618..0000000
--- a/poolalloc/lib/rDSA/GraphChecker.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-//===- GraphChecker.cpp - Assert that various graph properties hold -------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass is used to test DSA with regression tests.  It can be used to check
-// that certain graph properties hold, such as two nodes being disjoint, whether
-// or not a node is collapsed, etc.  These are the command line arguments that
-// it supports:
-//
-//   --dsgc-dspass={local,bu,td}      - Specify what flavor of graph to check
-//   --dsgc-abort-if-any-collapsed    - Abort if any collapsed nodes are found
-//   --dsgc-abort-if-collapsed=<list> - Abort if a node pointed to by an SSA
-//                                      value with name in <list> is collapsed
-//   --dsgc-check-flags=<list>        - Abort if the specified nodes have flags
-//                                      that are not specified.
-//   --dsgc-abort-if-merged=<list>    - Abort if any of the named SSA values
-//                                      point to the same node.
-//
-//===----------------------------------------------------------------------===//
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/Value.h"
-#include <set>
-using namespace llvm;
-
-namespace {
-  enum DSPass { local, bu, td };
-  cl::opt<DSPass>
-  DSPass("dsgc-dspass", cl::Hidden,
-       cl::desc("Specify which DSA pass the -datastructure-gc pass should use"),
-         cl::values(clEnumVal(local, "Local pass"),
-                    clEnumVal(bu,    "Bottom-up pass"),
-                    clEnumVal(td,    "Top-down pass"),
-                    clEnumValEnd), cl::init(local));
-
-  cl::opt<bool>
-  AbortIfAnyCollapsed("dsgc-abort-if-any-collapsed", cl::Hidden,
-                      cl::desc("Abort if any collapsed nodes are found"));
-  cl::list<std::string>
-  AbortIfCollapsed("dsgc-abort-if-collapsed", cl::Hidden, cl::CommaSeparated,
-                   cl::desc("Abort if any of the named symbols is collapsed"));
-  cl::list<std::string>
-  CheckFlags("dsgc-check-flags", cl::Hidden, cl::CommaSeparated,
-             cl::desc("Check that flags are specified for nodes"));
-  cl::list<std::string>
-  AbortIfMerged("dsgc-abort-if-merged", cl::Hidden, cl::CommaSeparated,
-             cl::desc("Abort if any of the named symbols are merged together"));
-
-  struct DSGC : public FunctionPass {
-    static char ID;
-    DSGC();
-    bool doFinalization(Module &M);
-    bool runOnFunction(Function &F);
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      switch (DSPass) {
-      case local: AU.addRequired<LocalDataStructures>(); break;
-      case bu:    AU.addRequired<BUDataStructures>(); break;
-      case td:    AU.addRequired<TDDataStructures>(); break;
-      }
-      AU.setPreservesAll();
-    }
-    void print(std::ostream &O, const Module *M) const {}
-
-  private:
-    void verify(const DSGraph* G);
-  };
-
-  RegisterPass<DSGC> X("datastructure-gc", "DSA Graph Checking Pass");
-}
-
-char DSGC::ID;
-
-FunctionPass *llvm::createDataStructureGraphCheckerPass() {
-  return new DSGC();
-}
-
-
-DSGC::DSGC() : FunctionPass((intptr_t)&ID) {
-  if (!AbortIfAnyCollapsed && AbortIfCollapsed.empty() &&
-      CheckFlags.empty() && AbortIfMerged.empty()) {
-    cerr << "The -datastructure-gc is useless if you don't specify any"
-         << " -dsgc-* options.  See the -help-hidden output for a list.\n";
-    abort();
-  }
-}
-
-
-/// doFinalization - Verify that the globals graph is in good shape...
-///
-bool DSGC::doFinalization(Module &M) {
-  switch (DSPass) {
-  case local:verify(getAnalysis<LocalDataStructures>().getGlobalsGraph());break;
-  case bu:   verify(getAnalysis<BUDataStructures>().getGlobalsGraph()); break;
-  case td:   verify(getAnalysis<TDDataStructures>().getGlobalsGraph()); break;
-  }
-  return false;
-}
-
-/// runOnFunction - Get the DSGraph for this function and verify that it is ok.
-///
-bool DSGC::runOnFunction(Function &F) {
-  switch (DSPass) {
-  case local: verify(getAnalysis<LocalDataStructures>().getDSGraph(&F)); break;
-  case bu:    verify(getAnalysis<BUDataStructures>().getDSGraph(&F)); break;
-  case td:    verify(getAnalysis<TDDataStructures>().getDSGraph(&F)); break;
-  }
-
-  return false;
-}
-
-/// verify - This is the function which checks to make sure that all of the
-/// invariants established on the command line are true.
-///
-void DSGC::verify(const DSGraph* G) {
-  // Loop over all of the nodes, checking to see if any are collapsed...
-  if (AbortIfAnyCollapsed) {
-    for (DSGraph::node_const_iterator I = G->node_begin(), E = G->node_end();
-         I != E; ++I)
-      if (I->isNodeCompletelyFolded()) {
-        cerr << "Node is collapsed: ";
-        I->print(cerr, G);
-        abort();
-      }
-  }
-
-  if (!AbortIfCollapsed.empty() || !CheckFlags.empty() ||
-      !AbortIfMerged.empty()) {
-    // Convert from a list to a set, because we don't have cl::set's yet.  FIXME
-    std::set<std::string> AbortIfCollapsedS(AbortIfCollapsed.begin(),
-                                            AbortIfCollapsed.end());
-    std::set<std::string> AbortIfMergedS(AbortIfMerged.begin(),
-                                         AbortIfMerged.end());
-    std::map<std::string, unsigned> CheckFlagsM;
-
-    for (cl::list<std::string>::iterator I = CheckFlags.begin(),
-           E = CheckFlags.end(); I != E; ++I) {
-      std::string::size_type ColonPos = I->rfind(':');
-      if (ColonPos == std::string::npos) {
-        cerr << "Error: '" << *I
-             << "' is an invalid value for the --dsgc-check-flags option!\n";
-        abort();
-      }
-
-      unsigned Flags = 0;
-      for (unsigned C = ColonPos+1; C != I->size(); ++C)
-        switch ((*I)[C]) {
-        case 'S': Flags |= DSFlags::AllocaNode;      break;
-        case 'H': Flags |= DSFlags::HeapNode;        break;
-        case 'G': Flags |= DSFlags::GlobalNode;      break;
-        case 'U': Flags |= DSFlags::UnknownNode;     break;
-        case 'I': Flags |= DSFlags::IncompleteNode;  break;
-        case 'M': Flags |= DSFlags::ModifiedNode;    break;
-        case 'R': Flags |= DSFlags::ReadNode;        break;
-        case 'A': Flags |= DSFlags::ArrayNode;       break;
-        default: cerr << "Invalid DSNode flag!\n"; abort();
-        }
-      CheckFlagsM[std::string(I->begin(), I->begin()+ColonPos)] = Flags;
-    }
-
-    // Now we loop over all of the scalars, checking to see if any are collapsed
-    // that are not supposed to be, or if any are merged together.
-    const DSGraph::ScalarMapTy &SM = G->getScalarMap();
-    std::map<DSNode*, std::string> AbortIfMergedNodes;
-
-    for (DSGraph::ScalarMapTy::const_iterator I = SM.begin(), E = SM.end();
-         I != E; ++I)
-      if (I->first->hasName() && I->second.getNode()) {
-        const std::string &Name = I->first->getName();
-        DSNode *N = I->second.getNode();
-
-        // Verify it is not collapsed if it is not supposed to be...
-        if (N->isNodeCompletelyFolded() && AbortIfCollapsedS.count(Name)) {
-          cerr << "Node for value '%" << Name << "' is collapsed: ";
-          N->print(cerr, G);
-          abort();
-        }
-
-        if (CheckFlagsM.count(Name) && CheckFlagsM[Name] != N->getNodeFlags()) {
-          cerr << "Node flags are not as expected for node: " << Name 
-               << " (" << CheckFlagsM[Name] << ":" <<N->getNodeFlags()
-               << ")\n";
-          N->print(cerr, G);
-          abort();
-        }
-
-        // Verify that it is not merged if it is not supposed to be...
-        if (AbortIfMergedS.count(Name)) {
-          if (AbortIfMergedNodes.count(N)) {
-            cerr << "Nodes for values '%" << Name << "' and '%"
-                 << AbortIfMergedNodes[N] << "' is merged: ";
-            N->print(cerr, G);
-            abort();
-          }
-          AbortIfMergedNodes[N] = Name;
-        }
-      }
-  }
-}
diff --git a/poolalloc/lib/rDSA/Local.cpp b/poolalloc/lib/rDSA/Local.cpp
deleted file mode 100644
index 1d71d60..0000000
--- a/poolalloc/lib/rDSA/Local.cpp
+++ /dev/null
@@ -1,992 +0,0 @@
-//===- Local.cpp - Compute a local data structure graph for a function ----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Compute the local version of the data structure graph for a function.  The
-// external interface to this file is the DSGraph constructor.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "dsa-local"
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/DataLayout.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/ADT/Statistic.h"
-
-using namespace llvm;
-
-static RegisterPass<LocalDataStructures>
-X("dsa-local", "Local Data Structure Analysis");
-
-namespace {
-
-  //===--------------------------------------------------------------------===//
-  //  GraphBuilderBase Class
-  //===--------------------------------------------------------------------===//
-  //
-  /// This class contains the common graph building coe.
-  ///
-  class GraphBuilderBase {
-    DSGraph* G;
-  protected:
-    /// createNode - Create a new DSNode, ensuring that it is properly added to
-    /// the graph.
-    ///
-    DSNode* createNode(const Type *Ty = 0) {   
-      return new DSNode(Ty, G);
-    }
-    DSNode* createNode(const Type *Ty, GlobalVariable* GV) {   
-      DSNode* N = new DSNode(Ty, G);
-      N->addGlobal(GV);
-      return N;
-    }
-    DSNode* createNode(const Type *Ty, GlobalAlias* GA) {   
-      DSNode* N = new DSNode(Ty, G);
-      N->addGlobal(GA);
-      return N;
-    }
-    DSNode* createNode(const Type *Ty, Function* FV) {   
-      DSNode* N = new DSNode(Ty, G);
-      N->addFunction(FV);
-      return N;
-    }
-
-    DSNodeHandle& getNodeForValue(const Value *V) { 
-      return G->getScalarMap()[V];
-    }
-
-    bool hasNodeForValue(const Value* V) const {
-      return G->hasNodeForValue(V);
-    }
-    void eraseNodeForValue(const Value* V) {
-      G->eraseNodeForValue(V);
-    }
-
-    void addDSCallSite(const DSCallSite& DSCS) {
-      G->getFunctionCalls().push_back(DSCS);
-    }
-
-    /// getValueDest - Return the DSNode that the actual value points to.
-    ///
-    DSNodeHandle getValueDest(Value &V);
-    DSNodeHandle getValueDest(GlobalVariable &V);
-    DSNodeHandle getValueDest(GlobalAlias &V);
-    DSNodeHandle getValueDest(Function &V);
-
-    /// setDestTo - Set the ScalarMap entry for the specified value to point to
-    /// the specified destination.  If the Value already points to a node, make
-    /// sure to merge the two destinations together.
-    ///
-    void setDestTo(Value &V, const DSNodeHandle &NH);
-
-    void visitGetElementPtrInst(User &GEP);
-
-    GraphBuilderBase(DSGraph* _G) :G(_G) {}
-
-  };
-
-  //===--------------------------------------------------------------------===//
-  //  GraphBuilderGlobal Class
-  //===--------------------------------------------------------------------===//
-  //
-  /// This class is the builder class that constructs the local data structure
-  /// graph by performing a single pass over the function in question.
-  ///
-  class GraphBuilderGlobal : GraphBuilderBase {
-
-    void MergeConstantInitIntoNode(DSNodeHandle &NH, const Type* Ty, Constant *C);
-
-  public:
-    // GraphBuilderGlobal ctor for working on the globals graph
-    explicit GraphBuilderGlobal(DSGraph* g)
-      :GraphBuilderBase(g)
-    {}
-
-    void mergeGlobal(GlobalVariable *GV);
-    void mergeAlias(GlobalAlias *GV);
-    void mergeFunction(Function* F);
-
-  };
-
- 
-  //===--------------------------------------------------------------------===//
-  //  GraphBuilderLocal Class
-  //===--------------------------------------------------------------------===//
-  //
-  /// This class is the builder class that constructs the local data structure
-  /// graph by performing a single pass over the function in question.
-  ///
-  class GraphBuilderLocal : GraphBuilderBase, InstVisitor<GraphBuilderLocal> {
-    DataStructures* DS;
-    DSNodeHandle&  RetNode;
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Helper functions used to implement the visitation functions...
-
-    /// getLink - This method is used to return the specified link in the
-    /// specified node if one exists.  If a link does not already exist (it's
-    /// null), then we create a new node, link it, then return it.
-    ///
-    DSNodeHandle &getLink(const DSNodeHandle &Node, unsigned Link = 0);
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Visitor functions, used to handle each instruction type we encounter...
-    friend class InstVisitor<GraphBuilderLocal>;
-
-    //the simple ones
-    void visitMallocInst(MallocInst &MI);
-    void visitAllocaInst(AllocaInst &AI);
-    void visitFreeInst(FreeInst &FI);
-    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);
-    void visitCmpInst(CmpInst &I);
-
-    void visitExtractValueInst(ExtractValueInst &I);
-    void visitInsertValueInst(InsertValueInst &I);
-
-    //the nasty ones
-    void visitCallInst(CallInst &CI);
-    void visitInvokeInst(InvokeInst &II);
-    void visitInstruction(Instruction &I);
-    void visitGetElementPtrInst(User &GEP) { 
-      GraphBuilderBase::visitGetElementPtrInst(GEP);
-    }
-
-    bool visitIntrinsic(CallSite CS, Function* F);
-    void visitCallSite(CallSite CS);
-
-  public:
-    GraphBuilderLocal(Function& f, DSNodeHandle& retnode, DSGraph* g, 
-                      DataStructures& DSi);
-  };
-}
-
-GraphBuilderLocal::GraphBuilderLocal(Function& f, DSNodeHandle& retnode, DSGraph* g, DataStructures& DSi)
-  : GraphBuilderBase(g), DS(&DSi), RetNode(retnode) {
-
-  // 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->NodeType.setEscapedNode();
-      
-    }
-  }
-  
-  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 (const 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);
-}
-
-//===----------------------------------------------------------------------===//
-// Helper method implementations...
-//
-
-
-///
-/// getValueDest - Return the DSNode that the actual value points to.
-///
-DSNodeHandle GraphBuilderBase::getValueDest(Value &Val) {
-  Value *V = &Val;
-  if (isa<Constant>(V) && cast<Constant>(V)->isNullValue()) 
-    return 0;  // Null doesn't point to anything, don't add to ScalarMap!
-
-  DSNodeHandle &NH = getNodeForValue(V);
-  if (!NH.isNull())
-    return NH;     // Already have a node?  Just return it...
-
-  // Otherwise we need to create a new node to point to.
-
-  if (GlobalVariable* GV = dyn_cast<GlobalVariable>(V))
-    // Create a new global node for this global variable.
-    return NH.setTo(createNode(GV->getType()->getElementType(), GV), 0);
-
-  if (Function* FV = dyn_cast<Function>(V))
-    // Create a new global node for this global variable.
-    return NH.setTo(createNode(0, FV), 0);
-
-  if (GlobalAlias* GA = dyn_cast<GlobalAlias>(V))
-    return NH.setTo(createNode(GA->getType()->getElementType(), GA), 0);
-
-  if (isa<UndefValue>(V)) {
-    eraseNodeForValue(V);
-    return 0;
-  }
-
-  // Check first for constant expressions that must be traversed to
-  // extract the actual value.
-  DSNode* N;
-  if (Constant *C = dyn_cast<Constant>(V)) {
-    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
-      if (CE->isCast()) {
-        if (isa<PointerType>(CE->getOperand(0)->getType()))
-          NH = getValueDest(*CE->getOperand(0));
-        else {
-          NH = createNode();
-          NH.getNode()->NodeType.setUnknownNode();
-        }
-      } else if (CE->getOpcode() == Instruction::GetElementPtr) {
-        visitGetElementPtrInst(*CE);
-        assert(hasNodeForValue(CE) && "GEP didn't get processed right?");
-        NH = getNodeForValue(CE);
-      } else {
-        // This returns a conservative unknown node for any unhandled ConstExpr
-        NH = createNode();
-        NH.getNode()->NodeType.setUnknownNode();
-        return NH;
-      }
-      if (NH.isNull()) {  // (getelementptr null, X) returns null
-        eraseNodeForValue(V);
-        return 0;
-      }
-      return NH;
-    } else {
-      DEBUG(errs() << "Unknown constant: " << *C << "\n");
-      assert(0 && "Unknown constant type!");
-    }
-    N = createNode(); // just create a shadow node
-  } else {
-    // Otherwise just create a shadow node
-    N = createNode();
-  }
-
-  return NH.setTo(N, 0);      // Remember that we are pointing to it...
-}
-
-//Save some type casts and conditionals on programs with many many globals
-DSNodeHandle GraphBuilderBase::getValueDest(GlobalVariable &Val) {
-  GlobalVariable *V = &Val;
-  DSNodeHandle &NH = getNodeForValue(V);
-  if (!NH.isNull())
-    return NH;     // Already have a node?  Just return it...
-
-  // Otherwise we need to create a new node to point to.
-  // Create a new global node for this global variable.
-  return NH.setTo(createNode(V->getType()->getElementType(), V), 0);
-}
-DSNodeHandle GraphBuilderBase::getValueDest(GlobalAlias &Val) {
-  GlobalAlias *V = &Val;
-  DSNodeHandle &NH = getNodeForValue(V);
-  if (!NH.isNull())
-    return NH;     // Already have a node?  Just return it...
-
-  // Otherwise we need to create a new node to point to.
-  // Create a new global node for this global variable.
-  return NH.setTo(createNode(V->getType()->getElementType(), V), 0);
-}
-DSNodeHandle GraphBuilderBase::getValueDest(Function &Val) {
-  Function *V = &Val;
-  DSNodeHandle &NH = getNodeForValue(V);
-  if (!NH.isNull())
-    return NH;     // Already have a node?  Just return it...
-
-  // Otherwise we need to create a new node to point to.
-  // Create a new global node for this global variable.
-  return NH.setTo(createNode(0, V), 0);
-}
-
-
-/// getLink - This method is used to return the specified link in the
-/// specified node if one exists.  If a link does not already exist (it's
-/// null), then we create a new node, link it, then return it.  We must
-/// specify the type of the Node field we are accessing so that we know what
-/// type should be linked to if we need to create a new node.
-///
-DSNodeHandle &GraphBuilderLocal::getLink(const DSNodeHandle &node, unsigned LinkNo) {
-  DSNodeHandle &Node = const_cast<DSNodeHandle&>(node);
-  DSNodeHandle &Link = Node.getLink(LinkNo);
-  if (Link.isNull()) {
-    // If the link hasn't been created yet, make and return a new shadow node
-    Link = createNode();
-  }
-  return Link;
-}
-
-
-/// setDestTo - Set the ScalarMap entry for the specified value to point to the
-/// specified destination.  If the Value already points to a node, make sure to
-/// merge the two destinations together.
-///
-void GraphBuilderBase::setDestTo(Value &V, const DSNodeHandle &NH) {
-  getNodeForValue(&V).mergeWith(NH);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Specific instruction type handler implementations...
-//
-void GraphBuilderLocal::visitMallocInst(MallocInst &MI) {
-  DSNode* N = createNode();
-  N->NodeType.setHeapNode();
-  setDestTo(MI, N);
-}
-
-void GraphBuilderLocal::visitAllocaInst(AllocaInst &AI) {
-  DSNode* N = createNode();
-  N->NodeType.setAllocaNode();
-  setDestTo(AI, N);
-}
-
-void GraphBuilderLocal::visitFreeInst(FreeInst &FI) {
-  if (DSNode *N = getValueDest(*FI.getOperand(0)).getNode())
-    N->NodeType.setHeapNode();
-}
-
-// 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 GraphBuilderLocal::visitPHINode(PHINode &PN) {
-  if (!isa<PointerType>(PN.getType())) return; // Only pointer PHIs
-
-  DSNodeHandle &PNDest = getNodeForValue(&PN);
-  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
-    PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
-}
-
-void GraphBuilderLocal::visitSelectInst(SelectInst &SI) {
-  if (!isa<PointerType>(SI.getType()))
-    return; // Only pointer Selects
-
-  DSNodeHandle &Dest = getNodeForValue(&SI);
-  DSNodeHandle S1 = getValueDest(*SI.getOperand(1));
-  DSNodeHandle S2 = getValueDest(*SI.getOperand(2));
-  Dest.mergeWith(S1);
-  Dest.mergeWith(S2);
-}
-
-void GraphBuilderLocal::visitLoadInst(LoadInst &LI) {
-  DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
-
-  if (Ptr.isNull()) return; // Load from null
-
-  // Make that the node is read from...
-  Ptr.getNode()->NodeType.setReadNode();
-
-  // Ensure a typerecord exists...
-  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
-
-  if (isa<PointerType>(LI.getType()))
-    setDestTo(LI, getLink(Ptr));
-}
-
-void GraphBuilderLocal::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()->NodeType.setModifiedNode();
-
-  // 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 GraphBuilderLocal::visitReturnInst(ReturnInst &RI) {
-  if (RI.getNumOperands() && isa<PointerType>(RI.getOperand(0)->getType()))
-    RetNode.mergeWith(getValueDest(*RI.getOperand(0)));
-}
-
-void GraphBuilderLocal::visitVAArgInst(VAArgInst &I) {
-  //FIXME: also updates the argument
-  DSNodeHandle Ptr = getValueDest(*I.getOperand(0));
-  if (Ptr.isNull()) return;
-
-  // Make that the node is read and written
-  Ptr.getNode()->NodeType.setReadNode();
-  Ptr.getNode()->NodeType.setModifiedNode();
-
-  // 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 GraphBuilderLocal::visitIntToPtrInst(IntToPtrInst &I) {
-//  std::cerr << "cast in " << I.getParent()->getParent()->getName() << "\n";
-//  I.dump();
-  DSNode* N = createNode();
-  N->NodeType.setUnknownNode();
-  N->NodeType.setIntToPtrNode();
-  setDestTo(I, N);
-}
-
-void GraphBuilderLocal::visitPtrToIntInst(PtrToIntInst& I) {
-  if (DSNode* N = getValueDest(*I.getOperand(0)).getNode())
-    N->NodeType.setPtrToIntNode();
-}
-
-
-void GraphBuilderLocal::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 GraphBuilderLocal::visitCmpInst(CmpInst &I) {
-  // TODO: must merge pointers
-}
-
-void GraphBuilderBase::visitGetElementPtrInst(User &GEP) {
-  DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
-  if (Value.isNull())
-    Value = createNode();
-
-  // As a special case, if all of the index operands of GEP are constant zeros,
-  // handle this just like we handle casts (ie, don't do much).
-  bool AllZeros = true;
-  for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i) {
-    if (ConstantInt * CI = dyn_cast<ConstantInt>(GEP.getOperand(i)))
-      if (CI->isZero()) {
-        continue;
-      }
-    AllZeros = false;
-    break;
-  }
-
-  // If all of the indices are zero, the result points to the operand without
-  // applying the type.
-  if (AllZeros || (!Value.isNull() &&
-                   Value.getNode()->isNodeCompletelyFolded())) {
-    setDestTo(GEP, Value);
-    return;
-  }
-
-
-  const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
-  const Type *CurTy = PTy->getElementType();
-
-  if (Value.getNode()->mergeTypeInfo(CurTy, Value.getOffset())) {
-    // If the node had to be folded... exit quickly
-    setDestTo(GEP, Value);  // GEP result points to folded node
-
-    return;
-  }
-
-  const DataLayout &TD = Value.getNode()->getDataLayout();
-
-#if 0
-  // Handle the pointer index specially...
-  if (GEP.getNumOperands() > 1 &&
-      (!isa<Constant>(GEP.getOperand(1)) ||
-       !cast<Constant>(GEP.getOperand(1))->isNullValue())) {
-
-    // If we already know this is an array being accessed, don't do anything...
-    if (!TopTypeRec.isArray) {
-      TopTypeRec.isArray = true;
-
-      // If we are treating some inner field pointer as an array, fold the node
-      // up because we cannot handle it right.  This can come because of
-      // something like this:  &((&Pt->X)[1]) == &Pt->Y
-      //
-      if (Value.getOffset()) {
-        // Value is now the pointer we want to GEP to be...
-        Value.getNode()->foldNodeCompletely();
-        setDestTo(GEP, Value);  // GEP result points to folded node
-        return;
-      } else {
-        // This is a pointer to the first byte of the node.  Make sure that we
-        // are pointing to the outter most type in the node.
-        // FIXME: We need to check one more case here...
-      }
-    }
-  }
-#endif
-
-  // All of these subscripts are indexing INTO the elements we have...
-  unsigned Offset = 0;
-  for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP);
-       I != E; ++I)
-    if (const StructType *STy = dyn_cast<StructType>(*I)) {
-      const ConstantInt* CUI = cast<ConstantInt>(I.getOperand());
-#if 0
-      unsigned FieldNo = 
-        CUI->getType()->isSigned() ? CUI->getSExtValue() : CUI->getZExtValue();
-#else
-      int FieldNo = CUI->getSExtValue();
-#endif
-      Offset += (unsigned)TD.getStructLayout(STy)->getElementOffset(FieldNo);
-    } else if (isa<PointerType>(*I)) {
-      if (!isa<Constant>(I.getOperand()) ||
-          !cast<Constant>(I.getOperand())->isNullValue())
-        Value.getNode()->NodeType.setArrayNode();
-    }
-
-
-#if 0
-    if (const SequentialType *STy = cast<SequentialType>(*I)) {
-      CurTy = STy->getElementType();
-      if (ConstantInt *CS = dyn_cast<ConstantInt>(GEP.getOperand(i))) {
-        Offset += 
-          (CS->getType()->isSigned() ? CS->getSExtValue() : CS->getZExtValue())
-          * TD.getTypeAllocSize(CurTy);
-      } else {
-        // Variable index into a node.  We must merge all of the elements of the
-        // sequential type here.
-        if (isa<PointerType>(STy)) {
-          DEBUG(errs() << "Pointer indexing not handled yet!\n");
-	} else {
-          const ArrayType *ATy = cast<ArrayType>(STy);
-          unsigned ElSize = TD.getTypeAllocSize(CurTy);
-          DSNode *N = Value.getNode();
-          assert(N && "Value must have a node!");
-          unsigned RawOffset = Offset+Value.getOffset();
-
-          // Loop over all of the elements of the array, merging them into the
-          // zeroth element.
-          for (unsigned i = 1, e = ATy->getNumElements(); i != e; ++i)
-            // Merge all of the byte components of this array element
-            for (unsigned j = 0; j != ElSize; ++j)
-              N->mergeIndexes(RawOffset+j, RawOffset+i*ElSize+j);
-        }
-      }
-    }
-#endif
-
-  // Add in the offset calculated...
-  Value.setOffset(Value.getOffset()+Offset);
-
-  // Check the offset
-  DSNode *N = Value.getNode();
-  if (N &&
-      !N->isNodeCompletelyFolded() &&
-      (N->getSize() != 0 || Offset != 0) &&
-      !N->isForwarding()) {
-    if ((Offset >= N->getSize()) || int(Offset) < 0) {
-      // Accessing offsets out of node size range
-      // This is seen in the "magic" struct in named (from bind), where the
-      // fourth field is an array of length 0, presumably used to create struct
-      // instances of different sizes
-
-      // Collapse the node since its size is now variable
-      N->foldNodeCompletely();
-    }
-  }
-
-  // Value is now the pointer we want to GEP to be...  
-  setDestTo(GEP, Value);
-#if 0
-  if (debug && (isa<Instruction>(GEP))) {
-    Instruction * IGEP = (Instruction *)(&GEP);
-    DSNode * N = Value.getNode();
-    if (IGEP->getParent()->getParent()->getName() == "alloc_vfsmnt")
-    {
-      if (G.getPoolDescriptorsMap().count(N) != 0)
-        if (G.getPoolDescriptorsMap()[N]) {
-	  DEBUG(errs() << "LLVA: GEP[" << 0 << "]: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[N]->getName() << "\n");
-	}
-    }
-  }
-#endif
-
-}
-
-
-void GraphBuilderLocal::visitCallInst(CallInst &CI) {
-  visitCallSite(&CI);
-}
-
-void GraphBuilderLocal::visitInvokeInst(InvokeInst &II) {
-  visitCallSite(&II);
-}
-
-/// returns true if the intrinsic is handled
-bool GraphBuilderLocal::visitIntrinsic(CallSite CS, Function *F) {
-  switch (F->getIntrinsicID()) {
-  case Intrinsic::vastart: {
-    // Mark the memory written by the vastart intrinsic as incomplete
-    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
-    if (DSNode *N = RetNH.getNode()) {
-      N->NodeType.setModifiedNode();
-      N->NodeType.setAllocaNode();
-      N->NodeType.setIncompleteNode();
-      N->NodeType.setUnknownNode();
-      N->foldNodeCompletely();
-    }
-
-    if (RetNH.hasLink(0)) {
-      DSNodeHandle Link = RetNH.getLink(0);
-      if (DSNode *N = Link.getNode()) {
-        N->NodeType.setModifiedNode();
-        N->NodeType.setAllocaNode();
-        N->NodeType.setIncompleteNode();
-        N->NodeType.setUnknownNode();
-        N->foldNodeCompletely();
-      }
-    } else {
-      //
-      // Sometimes the argument to the vastart is casted and has no DSNode.
-      // Peer past the cast.
-      //
-      Value * Operand = CS.getInstruction()->getOperand(1);
-      if (CastInst * CI = dyn_cast<CastInst>(Operand))
-        Operand = CI->getOperand (0);
-      RetNH = getValueDest(*Operand);
-      if (DSNode *N = RetNH.getNode()) {
-        N->NodeType.setModifiedNode();
-        N->NodeType.setAllocaNode();
-        N->NodeType.setIncompleteNode();
-        N->NodeType.setUnknownNode();
-        N->foldNodeCompletely();
-      }
-    }
-
-    return true;
-  }
-  case Intrinsic::vacopy:
-    getValueDest(*CS.getInstruction()).
-      mergeWith(getValueDest(**(CS.arg_begin())));
-    return true;
-  case Intrinsic::stacksave: {
-    DSNode * Node = createNode();
-    Node->NodeType.setAllocaNode();
-    Node->NodeType.setIncompleteNode();
-    Node->NodeType.setUnknownNode();
-    Node->foldNodeCompletely();
-    setDestTo (*(CS.getInstruction()), Node);
-    return true;
-  }
-  case Intrinsic::stackrestore: {
-    DSNode* Node = getValueDest(*CS.getInstruction()).getNode();
-    Node->NodeType.setAllocaNode();
-    Node->NodeType.setIncompleteNode();
-    Node->NodeType.setUnknownNode();
-    Node->foldNodeCompletely();
-    return true;
-  }
-  case Intrinsic::vaend:
-  case Intrinsic::dbg_func_start:
-  case Intrinsic::dbg_region_end:
-  case Intrinsic::dbg_stoppoint:
-  case Intrinsic::dbg_region_start:
-  case Intrinsic::dbg_declare:
-    return true;  // noop
-  case Intrinsic::memcpy: 
-  case Intrinsic::memmove: {
-    // Merge the first & second arguments, and mark the memory read and
-    // modified.
-    DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
-    RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
-    if (DSNode *N = RetNH.getNode()) {
-      N->NodeType.setModifiedNode();
-      N->NodeType.setReadNode();
-    }
-    return true;
-  }
-  case Intrinsic::memset:
-    // Mark the memory modified.
-    if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
-      N->NodeType.setModifiedNode();
-    return true;
-
-  case Intrinsic::eh_exception: {
-    DSNode * Node = createNode();
-    Node->NodeType.setIncompleteNode();
-    Node->foldNodeCompletely();
-    setDestTo (*(CS.getInstruction()), Node);
-    return true;
-  }
-
-  case Intrinsic::atomic_cmp_swap: {
-    DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
-    Ptr.getNode()->NodeType.setReadNode();
-    Ptr.getNode()->NodeType.setModifiedNode();
-    if (isa<PointerType>(F->getReturnType())) {
-      setDestTo(*(CS.getInstruction()), getValueDest(**(CS.arg_begin() + 1)));
-      getValueDest(**(CS.arg_begin() + 1))
-        .mergeWith(getValueDest(**(CS.arg_begin() + 2)));
-    }
-  }
-  case Intrinsic::atomic_swap:
-  case Intrinsic::atomic_load_add:
-  case Intrinsic::atomic_load_sub:
-  case Intrinsic::atomic_load_and:
-  case Intrinsic::atomic_load_nand:
-  case Intrinsic::atomic_load_or:
-  case Intrinsic::atomic_load_xor:
-  case Intrinsic::atomic_load_max:
-  case Intrinsic::atomic_load_min:
-  case Intrinsic::atomic_load_umax:
-  case Intrinsic::atomic_load_umin:
-    {
-      DSNodeHandle Ptr = getValueDest(**CS.arg_begin());
-      Ptr.getNode()->NodeType.setReadNode();
-      Ptr.getNode()->NodeType.setModifiedNode();
-      if (isa<PointerType>(F->getReturnType()))
-        setDestTo(*(CS.getInstruction()), getValueDest(**(CS.arg_begin() + 1)));
-    }
-   
-              
-
-  case Intrinsic::eh_selector_i32:
-  case Intrinsic::eh_selector_i64:
-  case Intrinsic::eh_typeid_for_i32:
-  case Intrinsic::eh_typeid_for_i64:
-  case Intrinsic::prefetch:
-    return true;
-
-  //
-  // The return address aliases with the stack, is type-unknown, and should
-  // have the unknown flag set since we don't know where it goes.
-  //
-  case Intrinsic::returnaddress: {
-    DSNode * Node = createNode();
-    Node->NodeType.setAllocaNode();
-    Node->NodeType.setIncompleteNode();
-    Node->NodeType.setUnknownNode();
-    Node->foldNodeCompletely();
-    setDestTo (*(CS.getInstruction()), Node);
-    return true;
-  }
-
-  default: {
-    //ignore pointer free intrinsics
-    if (!isa<PointerType>(F->getReturnType())) {
-      bool hasPtr = false;
-      for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
-           I != E && !hasPtr; ++I)
-        if (isa<PointerType>(I->getType()))
-          hasPtr = true;
-      if (!hasPtr)
-        return true;
-    }
-
-    DEBUG(errs() << "[dsa:local] Unhandled intrinsic: " << F->getName() << "\n");
-    assert(0 && "Unhandled intrinsic");
-    return false;
-  }
-  }
-}
-
-void GraphBuilderLocal::visitCallSite(CallSite CS) {
-  Value *Callee = CS.getCalledValue();
-
-  // Special case handling of certain libc allocation functions here.
-  if (Function *F = dyn_cast<Function>(Callee))
-    if (F->isDeclaration())
-      if (F->isIntrinsic() && visitIntrinsic(CS, F))
-        return;
-
-  // Set up the return value...
-  DSNodeHandle RetVal;
-  Instruction *I = CS.getInstruction();
-  if (isa<PointerType>(I->getType()))
-    RetVal = getValueDest(*I);
-
-  if (!isa<Function>(Callee))
-    if (ConstantExpr* EX = dyn_cast<ConstantExpr>(Callee))
-      if (EX->isCast() && isa<Function>(EX->getOperand(0)))
-        Callee = cast<Function>(EX->getOperand(0));
-
-  DSNode *CalleeNode = 0;
-  if (!isa<Function>(Callee)) {
-    CalleeNode = getValueDest(*Callee).getNode();
-    if (CalleeNode == 0) {
-      DEBUG(errs() << "WARNING: Program is calling through a null pointer?\n" << *I);
-      return;  // Calling a null pointer?
-    }
-  }
-
-  std::vector<DSNodeHandle> Args;
-  Args.reserve(CS.arg_end()-CS.arg_begin());
-
-  // Calculate the arguments vector...
-  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
-    if (isa<PointerType>((*I)->getType()))
-      Args.push_back(getValueDest(**I));
-    else
-      Args.push_back(0);
-
-  // Add a new function call entry...
-  if (CalleeNode) {
-    addDSCallSite(DSCallSite(CS, RetVal, CalleeNode, Args));
-  } else
-    addDSCallSite(DSCallSite(CS, RetVal, cast<Function>(Callee), Args));
-}
-
-// 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 GraphBuilderLocal::visitInstruction(Instruction &Inst) {
-  DSNodeHandle CurNode;
-  if (isa<PointerType>(Inst.getType()))
-    CurNode = getValueDest(Inst);
-  for (User::op_iterator I = Inst.op_begin(), E = Inst.op_end(); I != E; ++I)
-    if (isa<PointerType>((*I)->getType()))
-      CurNode.mergeWith(getValueDest(**I));
-
-  if (DSNode *N = CurNode.getNode())
-    N->NodeType.setUnknownNode();
-}
-
-void GraphBuilderLocal::visitExtractValueInst(ExtractValueInst &I) {
-  assert(!isa<PointerType>(I.getType()) && "ExtractValue not supported");
-}
-
-void GraphBuilderLocal::visitInsertValueInst(InsertValueInst &I) {
-  assert(!isa<PointerType>((*(I.op_begin()))->getType()) && "InsertValue not supported");
-}
-
-
-//===----------------------------------------------------------------------===//
-// LocalDataStructures Implementation
-//===----------------------------------------------------------------------===//
-
-// MergeConstantInitIntoNode - Merge the specified constant into the node
-// pointed to by NH.
-void GraphBuilderGlobal::MergeConstantInitIntoNode(DSNodeHandle &NH, const Type* Ty, Constant *C) {
-  // Ensure a type-record exists...
-  DSNode *NHN = NH.getNode();
-  NHN->mergeTypeInfo(Ty, NH.getOffset());
-
-  if (isa<PointerType>(Ty)) {
-    // Avoid adding edges from null, or processing non-"pointer" stores
-    NH.addEdgeTo(getValueDest(*C));
-    return;
-  }
-
-  if (Ty->isIntOrIntVector() || Ty->isFPOrFPVector()) return;
-
-  const DataLayout &TD = NH.getNode()->getDataLayout();
-
-  if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
-    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
-      // We don't currently do any indexing for arrays...
-      MergeConstantInitIntoNode(NH, cast<ArrayType>(Ty)->getElementType(), cast<Constant>(CA->getOperand(i)));
-  } else if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
-    const StructLayout *SL = TD.getStructLayout(cast<StructType>(Ty));
-    for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
-      DSNode *NHN = NH.getNode();
-      //Some programmers think ending a structure with a [0 x sbyte] is cute
-      if (SL->getElementOffset(i) < SL->getSizeInBytes()) {
-        DSNodeHandle NewNH(NHN, NH.getOffset()+(unsigned)SL->getElementOffset(i));
-        MergeConstantInitIntoNode(NewNH, cast<StructType>(Ty)->getElementType(i), cast<Constant>(CS->getOperand(i)));
-      } else if (SL->getElementOffset(i) == SL->getSizeInBytes()) {
-        DOUT << "Zero size element at end of struct\n";
-        NHN->foldNodeCompletely();
-      } else {
-        assert(0 && "type was smaller than offsets of of struct layout indicate");
-      }
-    }
-  } else if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) {
-    // Noop
-  } else {
-    assert(0 && "Unknown constant type!");
-  }
-}
-
-void GraphBuilderGlobal::mergeGlobal(GlobalVariable *GV) {
-  assert(!GV->isDeclaration() && "Cannot merge in external global!");
-  // Get a node handle to the global node and merge the initializer into it.
-  DSNodeHandle NH = getValueDest(*GV);
-  MergeConstantInitIntoNode(NH, GV->getType()->getElementType(), GV->getInitializer());
-}
-void GraphBuilderGlobal::mergeAlias(GlobalAlias *GV) {
-  assert(!GV->isDeclaration() && "Cannot merge in external alias!");
-  // Get a node handle to the global node and merge the initializer into it.
-  DSNodeHandle NH = getValueDest(*GV);
-  DSNodeHandle NHT = getValueDest(*GV->getAliasee());
-  NH.mergeWith(NHT);
-}
-void GraphBuilderGlobal::mergeFunction(Function* F) {
-  assert(!F->isDeclaration() && "Cannot merge in external global!");
-  DSNodeHandle NH = getValueDest(*F);
-}
-
-
-char LocalDataStructures::ID;
-
-bool LocalDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<DataLayoutPass>().getDataLayout());
-
-  // First step, build the globals graph.
-  {
-    GraphBuilderGlobal GGB(GlobalsGraph);
-
-    // Add initializers for all of the globals to the globals graph.
-    for (Module::global_iterator I = M.global_begin(), E = M.global_end();
-         I != E; ++I)
-      if (!I->isDeclaration())
-        GGB.mergeGlobal(I);
-    for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
-         I != E; ++I)
-      if (!I->isDeclaration())
-        GGB.mergeAlias(I);
-    // Add Functions to the globals graph.
-    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-      if (!I->isDeclaration())
-        GGB.mergeFunction(I);
-  }
-
-  // Next step, iterate through the nodes in the globals graph, unioning
-  // together the globals into equivalence classes.
-  formGlobalECs();
-
-  // Calculate all of the graphs...
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration()) {
-      DSGraph* G = new DSGraph(GlobalECs, getDataLayout(), GlobalsGraph);
-      GraphBuilderLocal GGB(*I, G->getOrCreateReturnNodeFor(*I), G, *this);
-      G->getAuxFunctionCalls() = G->getFunctionCalls();
-      setDSGraph(I, G);
-    }
-
-  GlobalsGraph->removeTriviallyDeadNodes();
-  GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
-
-  // Now that we've computed all of the graphs, and merged all of the info into
-  // 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.
-  formGlobalECs();
-
-  return false;
-}
-
diff --git a/poolalloc/lib/rDSA/Makefile b/poolalloc/lib/rDSA/Makefile
deleted file mode 100644
index 3aada71..0000000
--- a/poolalloc/lib/rDSA/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- lib/DSA/Makefile ------------------------------------*- Makefile -*-===##
-# 
-#                     The LLVM Compiler Infrastructure
-#
-# This file was developed by the LLVM research group and is distributed under
-# the University of Illinois Open Source License. See LICENSE.TXT for details.
-# 
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LOADABLE_MODULE=1
-BUILD_ARCHIVE = 1
-LIBRARYNAME = librDSA
-
-include $(LEVEL)/Makefile.common
-
-CFlags += -Wno-deprecated
diff --git a/poolalloc/lib/rDSA/Printer.cpp b/poolalloc/lib/rDSA/Printer.cpp
deleted file mode 100644
index 727f051..0000000
--- a/poolalloc/lib/rDSA/Printer.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-//===- Printer.cpp - Code for printing data structure graphs nicely -------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the 'dot' graph printer.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "dsgraph-printer"
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "rdsa/DSGraphTraits.h"
-#include "llvm/Module.h"
-#include "llvm/Constants.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/GraphWriter.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Config/config.h"
-#include "llvm/Support/FormattedStream.h"
-#include <ostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-using namespace llvm;
-
-// OnlyPrintMain - The DataStructure printer exposes this option to allow
-// printing of only the graph for "main".
-//
-namespace {
-  cl::opt<bool> OnlyPrintMain("only-print-main-ds", cl::ReallyHidden);
-  cl::opt<bool> DontPrintAnything("dont-print-ds", cl::ReallyHidden);
-  cl::opt<bool> LimitPrint("dsa-limit-print", cl::Hidden);
-  STATISTIC (MaxGraphSize   , "Maximum graph size");
-  STATISTIC (NumFoldedNodes , "Number of folded nodes (in final graph)");
-}
-
-void DSNode::dump() const { print(cerr, 0); }
-
-static std::string getCaption(const DSNode *N, const DSGraph *G) {
-  std::string empty;
-  raw_string_ostream OS(empty);
-  const Module *M = 0;
-
-  if (!G) G = N->getParentGraph();
-
-  // Get the module from ONE of the functions in the graph it is available.
-  if (G && G->retnodes_begin() != G->retnodes_end())
-    M = G->retnodes_begin()->first->getParent();
-  if (M == 0 && G) {
-    // If there is a global in the graph, we can use it to find the module.
-    const DSScalarMap &SM = G->getScalarMap();
-    if (SM.global_begin() != SM.global_end())
-      M = (*SM.global_begin())->getParent();
-  }
-
-  if (N->isNodeCompletelyFolded())
-    OS << "COLLAPSED";
-  else {
-    WriteTypeSymbolic(OS, N->getType(), M);
-    if (N->NodeType.isArrayNode())
-      OS << " array";
-  }
-  if (N->NodeType.getFlags()) {
-    OS << ": ";
-    std::string str;
-    N->NodeType.appendString(str);
-    OS << str << "\n";
-  }
-
-  EquivalenceClasses<const GlobalValue*> *GlobalECs = 0;
-  if (G) GlobalECs = &G->getGlobalECs();
-
-  for (DSNode::globals_iterator i = N->globals_begin(), e = N->globals_end(); 
-       i != e; ++i) {
-    WriteAsOperand(OS, *i, false, M);
-
-    // Figure out how many globals are equivalent to this one.
-    if (GlobalECs) {
-      EquivalenceClasses<const GlobalValue*>::iterator I =
-        GlobalECs->findValue(*i);
-      if (I != GlobalECs->end()) {
-        unsigned NumMembers =
-          std::distance(GlobalECs->member_begin(I), GlobalECs->member_end());
-        if (NumMembers != 1) OS << " + " << (NumMembers-1) << " EC";
-      }
-    }
-    OS << "\n";
-  }
-
-  return OS.str();
-}
-
-namespace llvm {
-template<>
-struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
-  static std::string getGraphName(const DSGraph *G) {
-    switch (G->getReturnNodes().size()) {
-    case 0: return G->getFunctionNames();
-    case 1: return "Function " + G->getFunctionNames();
-    default: return "Functions: " + G->getFunctionNames();
-    }
-  }
-
-  static std::string
-  getNodeLabel(const DSNode *Node, const DSGraph *Graph, bool ShortNames) {
-    return getCaption(Node, Graph);
-  }
-
-  static std::string getNodeAttributes(const DSNode *N, const DSGraph *Graph) {
-    return "shape=Mrecord";
-  }
-
-  static bool edgeTargetsEdgeSource(const void *Node,
-                                    DSNode::const_iterator I) {
-    unsigned O = I.getNode()->getLink(I.getOffset()).getOffset();
-    return O != 0;
-  }
-
-  static DSNode::const_iterator getEdgeTarget(const DSNode *Node,
-                                              DSNode::const_iterator I) {
-    unsigned O = I.getNode()->getLink(I.getOffset()).getOffset();
-    unsigned LinkNo = O;
-    const DSNode *N = *I;
-    DSNode::const_iterator R = N->begin();
-    for (; LinkNo; --LinkNo)
-      ++R;
-    return R;
-  }
-
-
-  /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
-  /// and the return node.
-  ///
-  static void addCustomGraphFeatures(const DSGraph *G,
-                                     GraphWriter<const DSGraph*> &GW) {
-    const Module *CurMod = 0;
-    if (G->retnodes_begin() != G->retnodes_end())
-      CurMod = G->retnodes_begin()->first->getParent();
-    else {
-      // If there is a global in the graph, we can use it to find the module.
-      const DSScalarMap &SM = G->getScalarMap();
-      if (SM.global_begin() != SM.global_end())
-        CurMod = (*SM.global_begin())->getParent();
-    }
-
-
-    if (!LimitPrint) {
-      // Add scalar nodes to the graph...
-      const DSGraph::ScalarMapTy &VM = G->getScalarMap();
-      for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
-        if (!isa<GlobalValue>(I->first)) {
-          std::stringstream OS;
-          WriteAsOperand(OS, I->first, false, CurMod);
-          GW.emitSimpleNode(I->first, "", OS.str());
-          
-          // Add edge from return node to real destination
-          DSNode *DestNode = I->second.getNode();
-          int EdgeDest = I->second.getOffset();
-          if (EdgeDest == 0) EdgeDest = -1;
-          GW.emitEdge(I->first, -1, DestNode,
-                      EdgeDest, "arrowtail=tee,color=gray63");
-        }
-    }
-
-
-    // Output the returned value pointer...
-    for (DSGraph::retnodes_iterator I = G->retnodes_begin(),
-           E = G->retnodes_end(); I != E; ++I)
-      if (I->second.getNode()) {
-        std::string Label;
-        if (G->getReturnNodes().size() == 1)
-          Label = "returning";
-        else
-          Label = I->first->getNameStr() + " ret node";
-        // Output the return node...
-        GW.emitSimpleNode((void*)I->first, "plaintext=circle", Label);
-
-        // Add edge from return node to real destination
-        DSNode *RetNode = I->second.getNode();
-        int RetEdgeDest = I->second.getOffset();
-        if (RetEdgeDest == 0) RetEdgeDest = -1;
-        GW.emitEdge((void*)I->first, -1, RetNode,
-                    RetEdgeDest, "arrowtail=tee,color=gray63");
-      }
-
-    // Output all of the call nodes...
-    const std::list<DSCallSite> &FCs =
-      G->shouldUseAuxCalls() ? G->getAuxFunctionCalls()
-      : G->getFunctionCalls();
-    for (std::list<DSCallSite>::const_iterator I = FCs.begin(), E = FCs.end();
-         I != E; ++I) {
-      const DSCallSite &Call = *I;
-      std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2);
-      EdgeSourceCaptions[0] = "r";
-      if (Call.isDirectCall())
-        EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName();
-      else
-        EdgeSourceCaptions[1] = "f";
-
-      GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2,
-                        &EdgeSourceCaptions);
-
-      if (DSNode *N = Call.getRetVal().getNode()) {
-        int EdgeDest = Call.getRetVal().getOffset();
-        if (EdgeDest == 0) EdgeDest = -1;
-        GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63,tailclip=false");
-      }
-
-      // Print out the callee...
-      if (Call.isIndirectCall()) {
-        DSNode *N = Call.getCalleeNode();
-        assert(N && "Null call site callee node!");
-        GW.emitEdge(&Call, 1, N, -1, "color=gray63,tailclip=false");
-      }
-
-      for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
-        if (DSNode *N = Call.getPtrArg(j).getNode()) {
-          int EdgeDest = Call.getPtrArg(j).getOffset();
-          if (EdgeDest == 0) EdgeDest = -1;
-          GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false");
-        }
-    }
-  }
-};
-}   // end namespace llvm
-
-void DSNode::print(std::ostream &O, const DSGraph *G) const {
-  GraphWriter<const DSGraph *> W(O, G, false);
-  W.writeNode(this);
-}
-
-void DSGraph::print(std::ostream &O) const {
-  WriteGraph(O, this, "DataStructures");
-}
-
-void DSGraph::writeGraphToFile(std::ostream &O,
-                               const std::string &GraphName) const {
-  std::string Filename = GraphName + ".dot";
-  O << "Writing '" << Filename << "'...";
-  std::ofstream F(Filename.c_str());
-
-  if (F.good()) {
-    print(F);
-    unsigned NumCalls = shouldUseAuxCalls() ?
-      getAuxFunctionCalls().size() : getFunctionCalls().size();
-    O << " [" << getGraphSize() << "+" << NumCalls << "]\n";
-  } else {
-    O << "  error opening file for writing!\n";
-  }
-}
-
-/// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
-/// then cleanup.  For use from the debugger.
-///
-void DSGraph::viewGraph() const {
-  ViewGraph(this, "ds.tempgraph", "DataStructures");
-}
-
-
-template <typename Collection>
-static void printCollection(const Collection &C, std::ostream &O,
-                            const Module *M, const std::string &Prefix) {
-  if (M == 0) {
-    O << "Null Module pointer, cannot continue!\n";
-    return;
-  }
-
-  unsigned TotalNumNodes = 0, TotalCallNodes = 0;
-  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
-    if (C.hasDSGraph(I)) {
-      DSGraph* Gr = C.getDSGraph(I);
-      unsigned NumCalls = Gr->shouldUseAuxCalls() ?
-        Gr->getAuxFunctionCalls().size() : Gr->getFunctionCalls().size();
-      bool IsDuplicateGraph = false;
-
-      if (I->getName() == "main" || !OnlyPrintMain) {
-        const Function *SCCFn = Gr->retnodes_begin()->first;
-        if (&*I == SCCFn) {
-          Gr->writeGraphToFile(O, Prefix+I->getNameStr());
-        } else {
-          IsDuplicateGraph = true; // Don't double count node/call nodes.
-          O << "Didn't write '" << Prefix+I->getNameStr()
-            << ".dot' - Graph already emitted to '" << Prefix+SCCFn->getNameStr()
-            << "\n";
-        }
-      } else {
-        const Function *SCCFn = Gr->retnodes_begin()->first;
-        if (&*I == SCCFn) {
-          O << "Skipped Writing '" << Prefix+I->getNameStr() << ".dot'... ["
-            << Gr->getGraphSize() << "+" << NumCalls << "]\n";
-        } else {
-          IsDuplicateGraph = true; // Don't double count node/call nodes.
-        }
-      }
-
-      if (!IsDuplicateGraph) {
-        unsigned GraphSize = Gr->getGraphSize();
-        if (MaxGraphSize < GraphSize) MaxGraphSize = GraphSize;
-
-        TotalNumNodes += Gr->getGraphSize();
-        TotalCallNodes += NumCalls;
-        for (DSGraph::node_iterator NI = Gr->node_begin(), E = Gr->node_end();
-             NI != E; ++NI)
-          if (NI->isNodeCompletelyFolded())
-            ++NumFoldedNodes;
-      }
-    }
-
-  DSGraph* GG = C.getGlobalsGraph();
-  TotalNumNodes  += GG->getGraphSize();
-  TotalCallNodes += GG->getFunctionCalls().size();
-  if (!OnlyPrintMain) {
-    GG->writeGraphToFile(O, Prefix+"GlobalsGraph");
-  } else {
-    O << "Skipped Writing '" << Prefix << "GlobalsGraph.dot'... ["
-      << GG->getGraphSize() << "+" << GG->getFunctionCalls().size() << "]\n";
-  }
-
-  O << "\nGraphs contain [" << TotalNumNodes << "+" << TotalCallNodes
-    << "] nodes total" << std::endl;
-}
-
-// print - Print out the analysis results...
-void DataStructures::print(std::ostream &O, const Module *M) const {
-  if (DontPrintAnything) return;
-  printCollection(*this, O, M, printname);
-}
diff --git a/poolalloc/lib/rDSA/StdLibPass.cpp b/poolalloc/lib/rDSA/StdLibPass.cpp
deleted file mode 100644
index 9e432b0..0000000
--- a/poolalloc/lib/rDSA/StdLibPass.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Recognize common standard c library functions and generate graphs for them
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/Statistic.h"
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
-#include "llvm/DataLayout.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Timer.h"
-#include <iostream>
-#include "llvm/Module.h"
-
-using namespace llvm;
-
-static RegisterPass<StdLibDataStructures>
-X("dsa-stdlib", "Standard Library Local Data Structure Analysis");
-
-char StdLibDataStructures::ID;
-
-#define numOps 10
-
-struct libAction {
-  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[] = {
-  {"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}},
-  {"fprintf",    {NRET_YARGS,  NRET_YNARGS, NRET_NARGS, false, false, false}},
-  {"puts",       {NRET_YARGS,  NRET_NARGS,  NRET_NARGS, false, false, false}},
-  {"putc",       {NRET_NARGS,  NRET_NARGS,  NRET_NARGS, false, false, false}},
-  {"putchar",    {NRET_NARGS,  NRET_NARGS,  NRET_NARGS, false, false, false}},
-  {"fputs",      {NRET_YARGS,  NRET_NYARGS, NRET_NARGS, false, false, false}},
-  {"fputc",      {NRET_YARGS,  NRET_NYARGS, 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}},
-
-  {"memcmp",     {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}},
-  {"strcat",     {YRET_YARGS, YRET_YARGS, NRET_NARGS,  true, true, true}},
-  {"strncat",    {YRET_YARGS, YRET_YARGS, NRET_NARGS,  true, true, true}},
-
-  {"strcpy",     {YRET_YARGS, YRET_YARGS, NRET_NARGS, true, true, true}},
-  {"wcscpy",     {YRET_YARGS, YRET_YARGS, NRET_NARGS, true, true, true}},
-  {"strcpy",     {YRET_YARGS, YRET_YARGS, NRET_NARGS, true, true, true}},
-  {"wcsncpy",    {YRET_YARGS, YRET_YARGS, NRET_NARGS, true, true, true}},
-
-
-  {"fwrite",     {NRET_YARGS, NRET_NYARGS, NRET_NARGS, false, false, false}},
-  {"fread",      {NRET_NYARGS, NRET_YARGS, NRET_NARGS, false, false, false}},
-  {"fflush",     {NRET_YARGS,  NRET_YARGS, NRET_NARGS, false, false, false}},
-  {"fclose",     {NRET_YARGS,  NRET_YARGS, NRET_NARGS, false, false, false}},
-  {"fopen",      {NRET_YARGS,  YRET_NARGS, YRET_NARGS, false, false, false}},
-  {"fileno",     {NRET_YARGS,  NRET_NARGS, NRET_NARGS, false, false, false}},
-  {"unlink",     {NRET_YARGS,  NRET_NARGS, NRET_NARGS, false, false, false}},
-
-  {"perror",     {NRET_YARGS,  NRET_NARGS, NRET_NARGS, false, false, false}},
-
-#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}},
-  {"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}},
-  // Terminate the list of special functions recognized by this pass
-  {0,            {NRET_NARGS, NRET_NARGS, NRET_NARGS, false, false, false}},
-};
-
-void StdLibDataStructures::eraseCallsTo(Function* F) {
-  for (Value::user_iterator ii = F->user_begin(), ee = F->user_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
-        DEBUG(errs() << "Removing " << F->getNameStr() << " from " 
-	      << CI->getParent()->getParent()->getNameStr() << "\n");
-        Graph->removeFunctionCalls(*F);
-      }
-}
-
-bool StdLibDataStructures::runOnModule(Module &M) {
-  init(&getAnalysis<LocalDataStructures>(), false, true, false, false);
-
-  //Clone Module
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
-    if (!I->isDeclaration())
-      getOrFetchDSGraph(I);
-
-  //Trust the readnone annotation
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
-    if (I->isDeclaration() && I->doesNotAccessMemory() && !isa<PointerType>(I->getReturnType()))
-      eraseCallsTo(I);
-
-  //Useless external
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
-    if (I->isDeclaration() && !I->isVarArg() && !isa<PointerType>(I->getReturnType())) {
-      bool hasPtr = false;
-      for (Function::arg_iterator ii = I->arg_begin(), ee = I->arg_end(); ii != ee; ++ii)
-        if (isa<PointerType>(ii->getType())) {
-          hasPtr = true;
-          break;
-        }
-      if (!hasPtr)
-        eraseCallsTo(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()) {
-        for (Value::user_iterator ii = F->user_begin(), ee = F->user_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.read[0])
-                Graph->getNodeForValue(CI).getNode()->NodeType.setReadNode();
-              if (recFuncs[x].action.write[0])
-                Graph->getNodeForValue(CI).getNode()->NodeType.setModifiedNode();
-              if (recFuncs[x].action.heap[0])
-                Graph->getNodeForValue(CI).getNode()->NodeType.setHeapNode();
-
-              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->NodeType.setReadNode();
-              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->NodeType.setModifiedNode();
-              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->NodeType.setHeapNode();
-
-              std::vector<DSNodeHandle> toMerge;
-              if (recFuncs[x].action.mergeWithRet)
-                toMerge.push_back(Graph->getNodeForValue(CI));
-              if (recFuncs[x].action.mergeAllArgs || recFuncs[x].action.mergeWithRet)
-                for (unsigned y = 1; y < CI->getNumOperands(); ++y)
-                  if (isa<PointerType>(CI->getOperand(y)->getType()))
-                    toMerge.push_back(Graph->getNodeForValue(CI->getOperand(y)));
-              for (unsigned y = 1; y < toMerge.size(); ++y)
-                toMerge[0].mergeWith(toMerge[y]);
-
-              if (recFuncs[x].action.collapse) {
-                if (isa<PointerType>(CI->getType()))
-                  Graph->getNodeForValue(CI).getNode()->foldNodeCompletely();
-                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();
-              }
-            }
-        eraseCallsTo(F);
-      }
-  
-  return false;
-}
diff --git a/poolalloc/lib/rDSA/Steensgaard.cpp b/poolalloc/lib/rDSA/Steensgaard.cpp
deleted file mode 100644
index dd07cad..0000000
--- a/poolalloc/lib/rDSA/Steensgaard.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-//===- Steensgaard.cpp - Context Insensitive Data Structure Analysis ------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass computes a context-insensitive data analysis graph.  It does this
-// by computing the local analysis graphs for all of the functions, then merging
-// them together into a single big graph without cloning.
-//
-//===----------------------------------------------------------------------===//
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Debug.h"
-#include <ostream>
-
-using namespace llvm;
-
-SteensgaardDataStructures::~SteensgaardDataStructures() { }
-
-void
-SteensgaardDataStructures::releaseMemory() {
-  delete ResultGraph; ResultGraph = 0;
-  DataStructures::releaseMemory();
-}
-
-// print - Implement the Pass::print method...
-void
-SteensgaardDataStructures::print(OStream O, const Module *M) const {
-  if (O.stream()) print(*O.stream(), M);
-}
-
-void
-SteensgaardDataStructures::print(std::ostream &O, const Module *M) const {
-  assert(ResultGraph && "Result graph has not yet been computed!");
-  ResultGraph->writeGraphToFile(O, "steensgaards");
-}
-
-/// run - Build up the result graph, representing the pointer graph for the
-/// program.
-///
-bool
-SteensgaardDataStructures::runOnModule(Module &M) {
-  DS = &getAnalysis<StdLibDataStructures>();
-  init(&getAnalysis<DataLayoutPass>().getDataLayout());
-  return runOnModuleInternal(M);
-}
-
-bool
-SteensgaardDataStructures::runOnModuleInternal(Module &M) {
-  assert(ResultGraph == 0 && "Result graph already allocated!");
-  
-  // Get a copy for the globals graph.
-  DSGraph * GG = DS->getGlobalsGraph();
-  GlobalsGraph = new DSGraph(GG, GG->getGlobalECs(), 0, 0);
-
-  // Create a new, empty, graph...
-  ResultGraph = new DSGraph(GG->getGlobalECs(), getDataLayout(), GlobalsGraph);
-  
-  // Loop over the rest of the module, merging graphs for non-external functions
-  // into this graph.
-  //
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
-    if (!I->isDeclaration()) {
-      ResultGraph->spliceFrom(DS->getDSGraph(I));
-    }
-  }
-
-  ResultGraph->removeTriviallyDeadNodes();
-
-  // FIXME: Must recalculate and use the Incomplete markers!!
-
-  // Now that we have all of the graphs inlined, we can go about eliminating
-  // call nodes...
-  //
-
-  // Start with a copy of the original call sites.
-  std::list<DSCallSite> & Calls = ResultGraph->getFunctionCalls();
-
-  for (std::list<DSCallSite>::iterator CI = Calls.begin(), E = Calls.end();
-       CI != E;) {
-    DSCallSite &CurCall = *CI++;
-
-    // Loop over the called functions, eliminating as many as possible...
-    std::vector<const Function*> CallTargets;
-    if (CurCall.isDirectCall())
-      CallTargets.push_back(CurCall.getCalleeFunc());
-    else
-      CurCall.getCalleeNode()->addFullFunctionList(CallTargets);
-
-    for (unsigned c = 0; c != CallTargets.size(); ) {
-      // If we can eliminate this function call, do so!
-      const Function *F = CallTargets[c];
-      if (!F->isDeclaration()) {
-        ResolveFunctionCall(F, CurCall, ResultGraph->getReturnNodes()[F]);
-        CallTargets[c] = CallTargets.back();
-        CallTargets.pop_back();
-      } else
-        ++c;  // Cannot eliminate this call, skip over it...
-    }
-
-    if (CallTargets.empty()) {        // Eliminated all calls?
-      std::list<DSCallSite>::iterator I = CI;
-      Calls.erase(--I);               // Remove entry
-    }
-  }
-
-  // Remove our knowledge of what the return values of the functions are, except
-  // for functions that are externally visible from this module (e.g. main).  We
-  // keep these functions so that their arguments are marked incomplete.
-  for (DSGraph::ReturnNodesTy::iterator I =
-         ResultGraph->getReturnNodes().begin(),
-         E = ResultGraph->getReturnNodes().end(); I != E; )
-    if (I->first->hasInternalLinkage())
-      ResultGraph->getReturnNodes().erase(I++);
-    else
-      ++I;
-
-  // Update the "incomplete" markers on the nodes, ignoring unknownness due to
-  // incoming arguments...
-  ResultGraph->maskIncompleteMarkers();
-
-  ResultGraph->markIncompleteNodes(DSGraph::MarkFormalArgs | DSGraph::IgnoreGlobals);
-
-  // Remove any nodes that are dead after all of the merging we have done...
-
-  ResultGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-  GlobalsGraph->removeTriviallyDeadNodes(true);
-  GlobalsGraph->maskIncompleteMarkers();
-
-  // Mark external globals incomplete.
-  GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
-
-  formGlobalECs();
-
-  // Clone the global nodes into this graph.
-  ReachabilityCloner RC(ResultGraph, GlobalsGraph,
-      DSGraph::DontCloneCallNodes |
-      DSGraph::DontCloneAuxCallNodes);
-  for (DSScalarMap::global_iterator I = GlobalsGraph->getScalarMap().global_begin(),
-      E = GlobalsGraph->getScalarMap().global_end(); I != E; ++I)
-    if (isa<GlobalVariable>(*I))
-      RC.getClonedNH(GlobalsGraph->getNodeForValue(*I));
-   
-
-  print(DOUT, &M);
-  return false;
-}
-
-/// ResolveFunctionCall - Resolve the actual arguments of a call to function F
-/// with the specified call site descriptor.  This function links the arguments
-/// and the return value for the call site context-insensitively.
-///
-void
-SteensgaardDataStructures::ResolveFunctionCall(const Function *F, 
-                                                const DSCallSite &Call,
-                                                DSNodeHandle &RetVal) {
-
-  assert(ResultGraph != 0 && "Result graph not allocated!");
-  DSGraph::ScalarMapTy &ValMap = ResultGraph->getScalarMap();
-
-  // Handle the return value of the function...
-  if (Call.getRetVal().getNode() && RetVal.getNode())
-    RetVal.mergeWith(Call.getRetVal());
-
-  // Loop over all pointer arguments, resolving them to their provided pointers
-  unsigned PtrArgIdx = 0;
-  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...
-      I->second.mergeWith(Call.getPtrArg(PtrArgIdx++));
-  }
-}
-
-char SteensgaardDataStructures::ID = 0;
-
-// Register the pass...
-static RegisterPass<SteensgaardDataStructures> X
-("dsa-steens",
- "Context-insensitive Data Structure Analysis");
diff --git a/poolalloc/lib/rDSA/SteensgaardAA.cpp b/poolalloc/lib/rDSA/SteensgaardAA.cpp
deleted file mode 100644
index 1f5cfb8..0000000
--- a/poolalloc/lib/rDSA/SteensgaardAA.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-//===- Steensgaard.cpp - Context Insensitive Alias Analysis ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass uses the data structure graphs to implement a simple context
-// insensitive alias analysis.  It does this by computing the local analysis
-// graphs for all of the functions, then merging them together into a single big
-// graph without cloning.
-//
-//===----------------------------------------------------------------------===//
-
-#include "rdsa/DataStructure.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Debug.h"
-#include <ostream>
-using namespace llvm;
-
-namespace {
-  class Steens : public ModulePass, public AliasAnalysis {
-    DSGraph * ResultGraph;
-  public:
-    static char ID;
-    Steens() : ModulePass((intptr_t)&ID), ResultGraph(NULL) {}
-    ~Steens() {    }
-
-    //------------------------------------------------
-    // Implement the Pass API
-    //
-
-    // run - Build up the result graph, representing the pointer graph for the
-    // program.
-    //
-    bool runOnModule(Module &M);
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AliasAnalysis::getAnalysisUsage(AU);
-      AU.setPreservesAll();                    // Does not transform code...
-      AU.addRequired<SteensgaardDataStructures>();   // Uses steensgaard dsgraph
-    }
-
-    //------------------------------------------------
-    // Implement the AliasAnalysis API
-    //
-
-    AliasResult alias(const Value *V1, unsigned V1Size,
-                      const Value *V2, unsigned V2Size);
-
-    virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
-    virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
-
-  };
-
-  // Register the pass...
-  RegisterPass<Steens> X("steens-aa",
-                         "Steensgaard's alias analysis (DSGraph based)");
-
-  // Register as an implementation of AliasAnalysis
-  RegisterAnalysisGroup<AliasAnalysis> Y(X);
-}
-
-char Steens::ID;
-
-ModulePass *llvm::createSteensgaardPass() { return new Steens(); }
-
-/// run - Build up the result graph, representing the pointer graph for the
-/// program.
-///
-bool Steens::runOnModule(Module &M) {
-  InitializeAliasAnalysis(this);
-  ResultGraph = getAnalysis<SteensgaardDataStructures>().getResultGraph();
-  return false;
-}
-
-AliasAnalysis::AliasResult Steens::alias(const Value *V1, unsigned V1Size,
-                                         const Value *V2, unsigned V2Size) {
-  assert(ResultGraph && "Result graph has not been computed yet!");
-
-  DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap();
-
-  DSGraph::ScalarMapTy::iterator I = GSM.find(const_cast<Value*>(V1));
-  DSGraph::ScalarMapTy::iterator J = GSM.find(const_cast<Value*>(V2));
-  if (I != GSM.end() && !I->second.isNull() &&
-      J != GSM.end() && !J->second.isNull()) {
-    DSNodeHandle &V1H = I->second;
-    DSNodeHandle &V2H = J->second;
-
-    // If at least one of the nodes is complete, we can say something about
-    // this.  If one is complete and the other isn't, then they are obviously
-    // different nodes.  If they are both complete, we can't say anything
-    // useful.
-    if (I->second.getNode()->NodeType.isCompleteNode() ||
-        J->second.getNode()->NodeType.isCompleteNode()) {
-      // If the two pointers point to different data structure graph nodes, they
-      // cannot alias!
-      if (V1H.getNode() != V2H.getNode())
-        return NoAlias;
-
-      // See if they point to different offsets...  if so, we may be able to
-      // determine that they do not alias...
-      unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset();
-      if (O1 != O2) {
-        if (O2 < O1) {    // Ensure that O1 <= O2
-          std::swap(V1, V2);
-          std::swap(O1, O2);
-          std::swap(V1Size, V2Size);
-        }
-
-        if (O1+V1Size <= O2)
-          return NoAlias;
-      }
-    }
-  }
-
-  // If we cannot determine alias properties based on our graph, fall back on
-  // some other AA implementation.
-  //
-  return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
-}
-
-AliasAnalysis::ModRefResult
-Steens::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
-  AliasAnalysis::ModRefResult Result = ModRef;
-
-  // Find the node in question.
-  DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap();
-  DSGraph::ScalarMapTy::iterator I = GSM.find(P);
-
-  if (I != GSM.end() && !I->second.isNull()) {
-    DSNode *N = I->second.getNode();
-    if (N->NodeType.isCompleteNode()) {
-      // If this is a direct call to an external function, and if the pointer
-      // points to a complete node, the external function cannot modify or read
-      // the value (we know it's not passed out of the program!).
-      if (Function *F = CS.getCalledFunction())
-        if (F->isDeclaration())
-          return NoModRef;
-
-      // Otherwise, if the node is complete, but it is only M or R, return this.
-      // This can be useful for globals that should be marked const but are not.
-      if (!N->NodeType.isModifiedNode())
-        Result = (ModRefResult)(Result & ~Mod);
-      if (!N->NodeType.isReadNode())
-        Result = (ModRefResult)(Result & ~Ref);
-    }
-  }
-
-  return (ModRefResult)(Result & AliasAnalysis::getModRefInfo(CS, P, Size));
-}
-
-AliasAnalysis::ModRefResult 
-Steens::getModRefInfo(CallSite CS1, CallSite CS2)
-{
-  return AliasAnalysis::getModRefInfo(CS1,CS2);
-}
diff --git a/poolalloc/lib/rDSA/TopDownClosure.cpp b/poolalloc/lib/rDSA/TopDownClosure.cpp
deleted file mode 100644
index dafeac3..0000000
--- a/poolalloc/lib/rDSA/TopDownClosure.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-//===- TopDownClosure.cpp - Compute the top-down interprocedure closure ---===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the TDDataStructures class, which represents the
-// Top-down Interprocedural closure of the data structure graph over the
-// program.  This is useful (but not strictly necessary?) for applications
-// like pointer analysis.
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "td_dsa"
-
-#include "rdsa/DataStructure.h"
-#include "llvm/Module.h"
-#include "llvm/DerivedTypes.h"
-#include "rdsa/DSGraph.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/ADT/Statistic.h"
-using namespace llvm;
-
-#if 0
-#define TIME_REGION(VARNAME, DESC) \
-   NamedRegionTimer VARNAME(DESC)
-#else
-#define TIME_REGION(VARNAME, DESC)
-#endif
-
-namespace {
-  RegisterPass<TDDataStructures>   // Register the pass
-  Y("dsa-td", "Top-down Data Structure Analysis");
-
-  RegisterPass<EQTDDataStructures>   // Register the pass
-  Z("dsa-eqtd", "EQ Top-down Data Structure Analysis");
-
-  STATISTIC (NumTDInlines, "Number of graphs inlined");
-}
-
-char TDDataStructures::ID;
-char EQTDDataStructures::ID;
-
-void TDDataStructures::markReachableFunctionsExternallyAccessible(DSNode *N,
-                                                   hash_set<DSNode*> &Visited) {
-  if (!N || Visited.count(N)) return;
-  Visited.insert(N);
-
-  for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
-    DSNodeHandle &NH = N->getLink(i);
-    if (DSNode *NN = NH.getNode()) {
-      std::vector<const Function*> Functions;
-      NN->addFullFunctionList(Functions);
-      ArgsRemainIncomplete.insert(Functions.begin(), Functions.end());
-      markReachableFunctionsExternallyAccessible(NN, Visited);
-    }
-  }
-}
-
-
-// run - Calculate the top down data structure graphs for each function in the
-// program.
-//
-bool TDDataStructures::runOnModule(Module &M) {
-  
-  init(useEQBU ? &getAnalysis<EquivBUDataStructures>()
-       : &getAnalysis<BUDataStructures>(), 
-       true, true, true, false);
-
-  // Figure out which functions must not mark their arguments complete because
-  // they are accessible outside this compilation unit.  Currently, these
-  // arguments are functions which are reachable by global variables in the
-  // globals graph.
-  const DSScalarMap &GGSM = GlobalsGraph->getScalarMap();
-  hash_set<DSNode*> Visited;
-  for (DSScalarMap::global_iterator I=GGSM.global_begin(), E=GGSM.global_end();
-       I != E; ++I) {
-    DSNode *N = GGSM.find(*I)->second.getNode();
-    if (N->NodeType.isIncompleteNode())
-      markReachableFunctionsExternallyAccessible(N, Visited);
-  }
-
-  // Loop over unresolved call nodes.  Any functions passed into (but not
-  // returned!) from unresolvable call nodes may be invoked outside of the
-  // current module.
-  for (DSGraph::afc_iterator I = GlobalsGraph->afc_begin(),
-         E = GlobalsGraph->afc_end(); I != E; ++I)
-    for (unsigned arg = 0, e = I->getNumPtrArgs(); arg != e; ++arg)
-      markReachableFunctionsExternallyAccessible(I->getPtrArg(arg).getNode(),
-                                                 Visited);
-  Visited.clear();
-
-  // Clear Aux of Globals Graph to be refilled in later by post-TD unresolved 
-  // functions
-  GlobalsGraph->getAuxFunctionCalls().clear();
-
-  // Functions without internal linkage also have unknown incoming arguments!
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration() && !I->hasInternalLinkage())
-      ArgsRemainIncomplete.insert(I);
-
-  // We want to traverse the call graph in reverse post-order.  To do this, we
-  // calculate a post-order traversal, then reverse it.
-  hash_set<DSGraph*> VisitedGraph;
-  std::vector<DSGraph*> PostOrder;
-
-{TIME_REGION(XXX, "td:Compute postorder");
-
-  // Calculate top-down from main...
-  if (Function *F = M.getFunction("main"))
-    ComputePostOrder(F, VisitedGraph, PostOrder);
-
-  // Next calculate the graphs for each unreachable function...
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration())
-      ComputePostOrder(I, VisitedGraph, PostOrder);
-
-  VisitedGraph.clear();   // Release memory!
-}
-
-{TIME_REGION(XXX, "td:Inline stuff");
-
-  // Visit each of the graphs in reverse post-order now!
-  while (!PostOrder.empty()) {
-    InlineCallersIntoGraph(PostOrder.back());
-    PostOrder.pop_back();
-  }
-}
-
-  // Free the IndCallMap.
-  while (!IndCallMap.empty()) {
-    delete IndCallMap.begin()->second;
-    IndCallMap.erase(IndCallMap.begin());
-  }
-
-  formGlobalECs();
-
-  ArgsRemainIncomplete.clear();
-  GlobalsGraph->removeTriviallyDeadNodes();
-
-  return false;
-}
-
-
-void TDDataStructures::ComputePostOrder(const Function* F,
-                                        hash_set<DSGraph*> &Visited,
-                                        std::vector<DSGraph*> &PostOrder) {
-  if (F->isDeclaration()) return;
-  DSGraph* G = getOrFetchDSGraph(F);
-  if (Visited.count(G)) return;
-  Visited.insert(G);
-
-  // 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 (calleeTy::iterator I = callee.begin(CallI),
-           E = callee.end(CallI); I != E; ++I)
-      ComputePostOrder(*I, Visited, PostOrder);
-  }
-
-  PostOrder.push_back(G);
-}
-
-/// 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) {
-  // Inline caller graphs into this graph.  First step, get the list of call
-  // sites that call into this graph.
-  std::vector<CallerCallEdge> EdgesFromCaller;
-  std::map<DSGraph*, std::vector<CallerCallEdge> >::iterator
-    CEI = CallerEdges.find(DSG);
-  if (CEI != CallerEdges.end()) {
-    std::swap(CEI->second, EdgesFromCaller);
-    CallerEdges.erase(CEI);
-  }
-
-  // Sort the caller sites to provide a by-caller-graph ordering.
-  std::sort(EdgesFromCaller.begin(), EdgesFromCaller.end());
-
-
-  // Merge information from the globals graph into this graph.  FIXME: This is
-  // stupid.  Instead of us cloning information from the GG into this graph,
-  // then having RemoveDeadNodes clone it back, we should do all of this as a
-  // post-pass over all of the graphs.  We need to take cloning out of
-  // removeDeadNodes and gut removeDeadNodes at the same time first though. :(
-  {
-    DSGraph* GG = DSG->getGlobalsGraph();
-    ReachabilityCloner RC(DSG, GG,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-    for (DSScalarMap::global_iterator
-           GI = DSG->getScalarMap().global_begin(),
-           E = DSG->getScalarMap().global_end(); GI != E; ++GI)
-      RC.getClonedNH(GG->getNodeForValue(*GI));
-  }
-
-  DEBUG(errs() << "[TD] Inlining callers into '" 
-	<< DSG->getFunctionNames() << "'\n");
-
-  // Iteratively inline caller graphs into this graph.
-  while (!EdgesFromCaller.empty()) {
-    DSGraph* CallerGraph = EdgesFromCaller.back().CallerGraph;
-
-    // Iterate through all of the call sites of this graph, cloning and merging
-    // any nodes required by the call.
-    ReachabilityCloner RC(DSG, CallerGraph,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-
-    // Inline all call sites from this caller graph.
-    do {
-      const DSCallSite &CS = *EdgesFromCaller.back().CS;
-      const Function &CF = *EdgesFromCaller.back().CalledFunction;
-      DEBUG(errs() << "   [TD] Inlining graph into Fn '" 
-	    << CF.getNameStr() << "' from ");
-      if (CallerGraph->getReturnNodes().empty()) {
-        DEBUG(errs() << "SYNTHESIZED INDIRECT GRAPH");
-      } else {
-        DEBUG(errs() << "Fn '" << CS.getCallSite().getInstruction()->
-	      getParent()->getParent()->getNameStr() << "'");
-      }
-      DEBUG(errs() << ": " << CF.getFunctionType()->getNumParams() 
-	    << " args\n");
-
-      // Get the formal argument and return nodes for the called function and
-      // merge them with the cloned subgraph.
-      DSCallSite T1 = DSG->getCallSiteForArguments(CF);
-      RC.mergeCallSite(T1, CS);
-      ++NumTDInlines;
-
-      EdgesFromCaller.pop_back();
-    } while (!EdgesFromCaller.empty() &&
-             EdgesFromCaller.back().CallerGraph == CallerGraph);
-  }
-
-
-  {
-    DSGraph* GG = DSG->getGlobalsGraph();
-    ReachabilityCloner RC(GG, DSG,
-                          DSGraph::DontCloneCallNodes |
-                          DSGraph::DontCloneAuxCallNodes);
-    for (DSScalarMap::global_iterator
-           GI = DSG->getScalarMap().global_begin(),
-           E = DSG->getScalarMap().global_end(); GI != E; ++GI)
-      RC.getClonedNH(DSG->getNodeForValue(*GI));
-  }
-
-  // Next, now that this graph is finalized, we need to recompute the
-  // incompleteness markers for this graph and remove unreachable nodes.
-  DSG->maskIncompleteMarkers();
-
-  // If any of the functions has incomplete incoming arguments, don't mark any
-  // of them as complete.
-  bool HasIncompleteArgs = false;
-  for (DSGraph::retnodes_iterator I = DSG->retnodes_begin(),
-         E = DSG->retnodes_end(); I != E; ++I)
-    if (ArgsRemainIncomplete.count(I->first)) {
-      HasIncompleteArgs = true;
-      break;
-    }
-
-  // Recompute the Incomplete markers.  Depends on whether args are complete
-  unsigned Flags
-    = HasIncompleteArgs ? DSGraph::MarkFormalArgs : DSGraph::IgnoreFormalArgs;
-  Flags |= DSGraph::IgnoreGlobals | DSGraph::MarkVAStart;
-  DSG->markIncompleteNodes(Flags);
-
-  // Delete dead nodes.  Treat globals that are unreachable as dead also.
-  DSG->removeDeadNodes(DSGraph::RemoveUnreachableGlobals);
-
-  // We are done with computing the current TD Graph!  Finally, before we can
-  // finish processing this function, we figure out which functions it calls and
-  // records these call graph edges, so that we have them when we process the
-  // callee graphs.
-  if (DSG->fc_begin() == DSG->fc_end()) return;
-
-  // Loop over all the call sites and all the callees at each call site, and add
-  // edges to the CallerEdges structure for each callee.
-  for (DSGraph::fc_iterator CI = DSG->fc_begin(), E = DSG->fc_end();
-       CI != E; ++CI) {
-
-    // Handle direct calls efficiently.
-    if (CI->isDirectCall()) {
-      if (!CI->getCalleeFunc()->isDeclaration() &&
-          !DSG->getReturnNodes().count(CI->getCalleeFunc()))
-        CallerEdges[getOrFetchDSGraph(CI->getCalleeFunc())]
-          .push_back(CallerCallEdge(DSG, &*CI, CI->getCalleeFunc()));
-      continue;
-    }
-
-    Instruction *CallI = CI->getCallSite().getInstruction();
-    // For each function in the invoked function list at this call site...
-    calleeTy::iterator IPI =
-      callee.begin(CallI), IPE = callee.end(CallI);
-
-    // Skip over all calls to this graph (SCC calls).
-    while (IPI != IPE && getDSGraph(*IPI) == DSG)
-      ++IPI;
-
-    // All SCC calls?
-    if (IPI == IPE) continue;
-
-    const Function *FirstCallee = *IPI;
-    ++IPI;
-
-    // Skip over more SCC calls.
-    while (IPI != IPE && getDSGraph(*IPI) == DSG)
-      ++IPI;
-
-    // If there is exactly one callee from this call site, remember the edge in
-    // CallerEdges.
-    if (IPI == IPE) {
-      if (!FirstCallee->isDeclaration())
-        CallerEdges[getOrFetchDSGraph(FirstCallee)]
-          .push_back(CallerCallEdge(DSG, &*CI, FirstCallee));
-      continue;
-    }
-
-    // Otherwise, there are multiple callees from this call site, so it must be
-    // an indirect call.  Chances are that there will be other call sites with
-    // 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<const Function*> Callees;
-    for (calleeTy::iterator I = callee.begin(CallI), E = callee.end(CallI);
-         I != E; ++I)
-      if (!(*I)->isDeclaration())
-        Callees.push_back(*I);
-    std::sort(Callees.begin(), Callees.end());
-
-    std::map<std::vector<const Function*>, DSGraph*>::iterator IndCallRecI =
-      IndCallMap.lower_bound(Callees);
-
-    DSGraph *IndCallGraph;
-
-    // If we already have this graph, recycle it.
-    if (IndCallRecI != IndCallMap.end() && IndCallRecI->first == Callees) {
-      DEBUG(errs() << "  [TD] *** Reuse of indcall graph for " << Callees.size()
-	    << " callees!\n");
-      IndCallGraph = IndCallRecI->second;
-    } else {
-      // Otherwise, create a new DSGraph to represent this.
-      IndCallGraph = new DSGraph(DSG->getGlobalECs(), DSG->getDataLayout(), GlobalsGraph);
-      // Make a nullary dummy call site, which will eventually get some content
-      // merged into it.  The actual callee function doesn't matter here, so we
-      // just pass it something to keep the ctor happy.
-      std::vector<DSNodeHandle> ArgDummyVec;
-      DSCallSite DummyCS(CI->getCallSite(), DSNodeHandle(), Callees[0]/*dummy*/,
-                         ArgDummyVec);
-      IndCallGraph->getFunctionCalls().push_back(DummyCS);
-
-      IndCallRecI = IndCallMap.insert(IndCallRecI,
-                                      std::make_pair(Callees, IndCallGraph));
-
-      // Additionally, make sure that each of the callees inlines this graph
-      // exactly once.
-      DSCallSite *NCS = &IndCallGraph->getFunctionCalls().front();
-      for (unsigned i = 0, e = Callees.size(); i != e; ++i) {
-        DSGraph* CalleeGraph = getDSGraph(Callees[i]);
-        if (CalleeGraph != DSG)
-          CallerEdges[CalleeGraph].push_back(CallerCallEdge(IndCallGraph, NCS,
-                                                            Callees[i]));
-      }
-    }
-
-    // Now that we know which graph to use for this, merge the caller
-    // information into the graph, based on information from the call site.
-    ReachabilityCloner RC(IndCallGraph, DSG, 0);
-    RC.mergeCallSite(IndCallGraph->getFunctionCalls().front(), *CI);
-  }
-}
