This commit was manufactured by cvs2svn to create branch 'poolalloc'.

llvm-svn: 7751
diff --git a/poolalloc/include/dsa/DSGraph.h b/poolalloc/include/dsa/DSGraph.h
deleted file mode 100644
index 10dca09..0000000
--- a/poolalloc/include/dsa/DSGraph.h
+++ /dev/null
@@ -1,308 +0,0 @@
-//===- DSGraph.h - Represent a collection of data structures ----*- C++ -*-===//
-//
-// This header defines the data structure graph.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DSGRAPH_H
-#define LLVM_ANALYSIS_DSGRAPH_H
-
-#include "llvm/Analysis/DSNode.h"
-class GlobalValue;
-
-//===----------------------------------------------------------------------===//
-/// DSGraph - The graph that represents a function.
-///
-struct DSGraph {
-  // Public data-type declarations...
-  typedef hash_map<Value*, DSNodeHandle> ScalarMapTy;
-  typedef hash_map<Function*, DSNodeHandle> ReturnNodesTy;
-  typedef hash_set<const GlobalValue*> GlobalSetTy;
-
-  /// NodeMapTy - This data type is used when cloning one graph into another to
-  /// keep track of the correspondence between the nodes in the old and new
-  /// graphs.
-  typedef hash_map<const DSNode*, DSNodeHandle> NodeMapTy;
-private:
-  DSGraph *GlobalsGraph;   // Pointer to the common graph of global objects
-  bool PrintAuxCalls;      // Should this graph print the Aux calls vector?
-
-  std::vector<DSNode*> Nodes;
-  ScalarMapTy ScalarMap;
-
-  // ReturnNodes - A return value for every function merged into this graph.
-  // Each DSGraph may have multiple functions merged into it at any time, which
-  // is used for representing SCCs.
-  //
-  ReturnNodesTy ReturnNodes;
-
-  // FunctionCalls - This vector maintains a single entry for each call
-  // instruction in the current graph.  The first entry in the vector is the
-  // scalar that holds the return value for the call, the second is the function
-  // scalar being invoked, and the rest are pointer arguments to the function.
-  // This vector is built by the Local graph and is never modified after that.
-  //
-  std::vector<DSCallSite> FunctionCalls;
-
-  // AuxFunctionCalls - This vector contains call sites that have been processed
-  // by some mechanism.  In pratice, the BU Analysis uses this vector to hold
-  // the _unresolved_ call sites, because it cannot modify FunctionCalls.
-  //
-  std::vector<DSCallSite> AuxFunctionCalls;
-
-  // InlinedGlobals - This set records which globals have been inlined from
-  // other graphs (callers or callees, depending on the pass) into this one.
-  // 
-  GlobalSetTy InlinedGlobals;
-
-  void operator=(const DSGraph &); // DO NOT IMPLEMENT
-
-public:
-  // Create a new, empty, DSGraph.
-  DSGraph() : GlobalsGraph(0), PrintAuxCalls(false) {}
-  DSGraph(Function &F, DSGraph *GlobalsGraph); // Compute the local DSGraph
-
-  // Copy ctor - If you want to capture the node mapping between the source and
-  // destination graph, you may optionally do this by specifying a map to record
-  // this into.
-  //
-  // Note that a copied graph does not retain the GlobalsGraph pointer of the
-  // source.  You need to set a new GlobalsGraph with the setGlobalsGraph
-  // method.
-  //
-  DSGraph(const DSGraph &DSG);
-  DSGraph(const DSGraph &DSG, NodeMapTy &NodeMap);
-  ~DSGraph();
-
-  DSGraph *getGlobalsGraph() const { return GlobalsGraph; }
-  void setGlobalsGraph(DSGraph *G) { GlobalsGraph = G; }
-
-  // setPrintAuxCalls - If you call this method, the auxillary call vector will
-  // be printed instead of the standard call vector to the dot file.
-  //
-  void setPrintAuxCalls() { PrintAuxCalls = true; }
-  bool shouldPrintAuxCalls() const { return PrintAuxCalls; }
-
-  /// getNodes - Get a vector of all the nodes in the graph
-  /// 
-  const std::vector<DSNode*> &getNodes() const { return Nodes; }
-        std::vector<DSNode*> &getNodes()       { return Nodes; }
-
-  /// getFunctionNames - Return a space separated list of the name of the
-  /// functions in this graph (if any)
-  std::string getFunctionNames() const;
-
-  /// addNode - Add a new node to the graph.
-  ///
-  void addNode(DSNode *N) { Nodes.push_back(N); }
-
-  /// getScalarMap - Get a map that describes what the nodes the scalars in this
-  /// function point to...
-  ///
-  ScalarMapTy &getScalarMap() { return ScalarMap; }
-  const ScalarMapTy &getScalarMap() const {return ScalarMap;}
-
-  /// getFunctionCalls - Return the list of call sites in the original local
-  /// graph...
-  ///
-  const std::vector<DSCallSite> &getFunctionCalls() const {
-    return FunctionCalls;
-  }
-
-  /// getAuxFunctionCalls - Get the call sites as modified by whatever passes
-  /// have been run.
-  ///
-  std::vector<DSCallSite> &getAuxFunctionCalls() {
-    return AuxFunctionCalls;
-  }
-  const std::vector<DSCallSite> &getAuxFunctionCalls() const {
-    return AuxFunctionCalls;
-  }
-
-  /// getInlinedGlobals - Get the set of globals that are have been inlined
-  /// (from callees in BU or from callers in TD) into the current graph.
-  ///
-  GlobalSetTy& getInlinedGlobals() {
-    return InlinedGlobals;
-  }
-
-  /// getNodeForValue - Given a value that is used or defined in the body of the
-  /// current function, return the DSNode that it points to.
-  ///
-  DSNodeHandle &getNodeForValue(Value *V) { return ScalarMap[V]; }
-
-  const DSNodeHandle &getNodeForValue(Value *V) const {
-    ScalarMapTy::const_iterator I = ScalarMap.find(V);
-    assert(I != ScalarMap.end() &&
-           "Use non-const lookup function if node may not be in the map");
-    return I->second;
-  }
-
-  /// getReturnNodes - Return the mapping of functions to their return nodes for
-  /// this graph.
-  const ReturnNodesTy &getReturnNodes() const { return ReturnNodes; }
-        ReturnNodesTy &getReturnNodes()       { return ReturnNodes; }
-
-  /// getReturnNodeFor - Return the return node for the specified function.
-  ///
-  DSNodeHandle &getReturnNodeFor(Function &F) {
-    ReturnNodesTy::iterator I = ReturnNodes.find(&F);
-    assert(I != ReturnNodes.end() && "F not in this DSGraph!");
-    return I->second;
-  }
-
-  const DSNodeHandle &getReturnNodeFor(Function &F) const {
-    ReturnNodesTy::const_iterator I = ReturnNodes.find(&F);
-    assert(I != ReturnNodes.end() && "F not in this DSGraph!");
-    return I->second;
-  }
-
-  /// getGraphSize - Return the number of nodes in this graph.
-  ///
-  unsigned getGraphSize() const {
-    return Nodes.size();
-  }
-
-  /// print - Print a dot graph to the specified ostream...
-  ///
-  void print(std::ostream &O) const;
-
-  /// dump - call print(std::cerr), for use from the debugger...
-  ///
-  void dump() const;
-
-  /// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
-  /// then cleanup.  For use from the debugger.
-  void viewGraph() const;
-
-  void writeGraphToFile(std::ostream &O, const std::string &GraphName) const;
-
-  /// maskNodeTypes - Apply a mask to all of the node types in the graph.  This
-  /// is useful for clearing out markers like Incomplete.
-  ///
-  void maskNodeTypes(unsigned Mask) {
-    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-      Nodes[i]->maskNodeTypes(Mask);
-  }
-  void maskIncompleteMarkers() { maskNodeTypes(~DSNode::Incomplete); }
-
-  // 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.
-  //
-  enum MarkIncompleteFlags {
-    MarkFormalArgs = 1, IgnoreFormalArgs = 0,
-    IgnoreGlobals = 2, MarkGlobalsIncomplete = 0,
-  };
-  void markIncompleteNodes(unsigned Flags);
-
-  // removeDeadNodes - Use a 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.
-  //
-  enum RemoveDeadNodesFlags {
-    RemoveUnreachableGlobals = 1, KeepUnreachableGlobals = 0,
-  };
-  void removeDeadNodes(unsigned Flags);
-
-  /// CloneFlags enum - Bits that may be passed into the cloneInto method to
-  /// specify how to clone the function graph.
-  enum CloneFlags {
-    StripAllocaBit        = 1 << 0, KeepAllocaBit     = 0,
-    DontCloneCallNodes    = 1 << 1, CloneCallNodes    = 0,
-    DontCloneAuxCallNodes = 1 << 2, CloneAuxCallNodes = 0,
-    StripModRefBits       = 1 << 3, KeepModRefBits    = 0,
-    StripIncompleteBit    = 1 << 4, KeepIncompleteBit = 0,
-  };
-
-private:
-  void cloneReachableNodes(const DSNode*  Node,
-                           unsigned BitsToClear,
-                           NodeMapTy& OldNodeMap,
-                           NodeMapTy& CompletedNodeMap);
-
-public:
-  void updateFromGlobalGraph();
-
-  void cloneReachableSubgraph(const DSGraph& G,
-                              const hash_set<const DSNode*>& RootNodes,
-                              NodeMapTy& OldNodeMap,
-                              NodeMapTy& CompletedNodeMap,
-                              unsigned CloneFlags = 0);
-
-  /// cloneInto - Clone the specified DSGraph into the current graph.  The
-  /// translated ScalarMap for the old function is filled into the OldValMap
-  /// member, and the translated ReturnNodes map is returned into ReturnNodes.
-  ///
-  /// The CloneFlags member controls various aspects of the cloning process.
-  ///
-  void cloneInto(const DSGraph &G, ScalarMapTy &OldValMap,
-                 ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap,
-                 unsigned CloneFlags = 0);
-
-  /// 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.  If the StripAlloca's argument is 'StripAllocaBit' then Alloca
-  /// markers are removed from nodes.
-  ///
-  void mergeInGraph(const DSCallSite &CS, Function &F, const DSGraph &Graph,
-                    unsigned CloneFlags);
-
-
-  /// getCallSiteForArguments - Get the arguments and return value bindings for
-  /// the specified function in the current graph.
-  ///
-  DSCallSite getCallSiteForArguments(Function &F) const;
-
-  // Methods for checking to make sure graphs are well formed...
-  void AssertNodeInGraph(const DSNode *N) const {
-    assert((!N || find(Nodes.begin(), Nodes.end(), N) != Nodes.end()) &&
-           "AssertNodeInGraph: Node is not in graph!");
-  }
-  void AssertNodeContainsGlobal(const DSNode *N, GlobalValue *GV) const {
-    assert(std::find(N->getGlobals().begin(), N->getGlobals().end(), GV) !=
-           N->getGlobals().end() && "Global value not in node!");
-  }
-
-  void AssertCallSiteInGraph(const DSCallSite &CS) const {
-    if (CS.isIndirectCall())
-      AssertNodeInGraph(CS.getCalleeNode());
-    AssertNodeInGraph(CS.getRetVal().getNode());
-    for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j)
-      AssertNodeInGraph(CS.getPtrArg(j).getNode());
-  }
-
-  void AssertCallNodesInGraph() const {
-    for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i)
-      AssertCallSiteInGraph(FunctionCalls[i]);
-  }
-  void AssertAuxCallNodesInGraph() const {
-    for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i)
-      AssertCallSiteInGraph(AuxFunctionCalls[i]);
-  }
-
-  void AssertGraphOK() const;
-
-  /// mergeInGlobalsGraph - This method is useful for clients to incorporate the
-  /// globals graph into the DS, BU or TD graph for a function.  This code
-  /// retains all globals, i.e., does not delete unreachable globals after they
-  /// are inlined.
-  ///
-  void mergeInGlobalsGraph();
-
-  /// 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.  This is used as the first step of
-  /// removeDeadNodes.
-  ///
-  void removeTriviallyDeadNodes();
-};
-
-#endif
diff --git a/poolalloc/include/dsa/DSGraphTraits.h b/poolalloc/include/dsa/DSGraphTraits.h
deleted file mode 100644
index 7ea30c0..0000000
--- a/poolalloc/include/dsa/DSGraphTraits.h
+++ /dev/null
@@ -1,142 +0,0 @@
-//===- DSGraphTraits.h - Provide generic graph interface --------*- C++ -*-===//
-//
-// This file provides GraphTraits specializations for the DataStructure graph
-// nodes, allowing datastructure graphs to be processed by generic graph
-// algorithms.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DSGRAPHTRAITS_H
-#define LLVM_ANALYSIS_DSGRAPHTRAITS_H
-
-#include "llvm/Analysis/DSGraph.h"
-#include "Support/GraphTraits.h"
-#include "Support/iterator"
-#include "Support/STLExtras.h"
-
-template<typename NodeTy>
-class DSNodeIterator : public forward_iterator<const DSNode, ptrdiff_t> {
-  friend class DSNode;
-  NodeTy * const Node;
-  unsigned Offset;
-  
-  typedef DSNodeIterator<NodeTy> _Self;
-
-  DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {}   // begin iterator
-  DSNodeIterator(NodeTy *N, bool) : Node(N) {         // Create end iterator
-    Offset = N->getNumLinks() << DS::PointerShift;
-    if (Offset == 0 && Node->getForwardNode() &&
-        Node->isDeadNode())        // Model Forward link
-      Offset += DS::PointerSize;
-  }
-public:
-  DSNodeIterator(const DSNodeHandle &NH)
-    : Node(NH.getNode()), Offset(NH.getOffset()) {}
-
-  bool operator==(const _Self& x) const {
-    return Offset == x.Offset;
-  }
-  bool operator!=(const _Self& x) const { return !operator==(x); }
-
-  const _Self &operator=(const _Self &I) {
-    assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
-    Offset = I.Offset;
-    return *this;
-  }
-  
-  pointer operator*() const {
-    if (Node->isDeadNode())
-      return Node->getForwardNode();
-    else
-      return Node->getLink(Offset).getNode();
-  }
-  pointer operator->() const { return operator*(); }
-  
-  _Self& operator++() {                // Preincrement
-    Offset += (1 << DS::PointerShift);
-    return *this;
-  }
-  _Self operator++(int) { // Postincrement
-    _Self tmp = *this; ++*this; return tmp; 
-  }
-
-  unsigned getOffset() const { return Offset; }
-  const DSNode *getNode() const { return Node; }
-};
-
-// Provide iterators for DSNode...
-inline DSNode::iterator DSNode::begin() {
-  return DSNode::iterator(this);
-}
-inline DSNode::iterator DSNode::end() {
-  return DSNode::iterator(this, false);
-}
-inline DSNode::const_iterator DSNode::begin() const {
-  return DSNode::const_iterator(this);
-}
-inline DSNode::const_iterator DSNode::end() const {
-  return DSNode::const_iterator(this, false);
-}
-
-template <> struct GraphTraits<DSNode*> {
-  typedef DSNode NodeType;
-  typedef DSNode::iterator ChildIteratorType;
-
-  static NodeType *getEntryNode(NodeType *N) { return N; }
-  static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
-  static ChildIteratorType child_end(NodeType *N) { return N->end(); }
-};
-
-template <> struct GraphTraits<const DSNode*> {
-  typedef const DSNode NodeType;
-  typedef DSNode::const_iterator ChildIteratorType;
-
-  static NodeType *getEntryNode(NodeType *N) { return N; }
-  static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
-  static ChildIteratorType child_end(NodeType *N) { return N->end(); }
-};
-
-static       DSNode &dereference (      DSNode *N) { return *N; }
-static const DSNode &dereferenceC(const DSNode *N) { return *N; }
-
-template <> struct GraphTraits<DSGraph*> {
-  typedef DSNode NodeType;
-  typedef DSNode::iterator ChildIteratorType;
-
-  typedef std::pointer_to_unary_function<DSNode *, DSNode&> DerefFun;
-
-  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
-  typedef mapped_iterator<std::vector<DSNode*>::iterator,
-                          DerefFun> nodes_iterator;
-  static nodes_iterator nodes_begin(DSGraph *G) {
-    return map_iterator(G->getNodes().begin(), DerefFun(dereference));
-  }
-  static nodes_iterator nodes_end(DSGraph *G) {
-    return map_iterator(G->getNodes().end(), DerefFun(dereference));
-  }
-
-  static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
-  static ChildIteratorType child_end(NodeType *N) { return N->end(); }
-};
-
-template <> struct GraphTraits<const DSGraph*> {
-  typedef const DSNode NodeType;
-  typedef DSNode::const_iterator ChildIteratorType;
-
-  typedef std::pointer_to_unary_function<const DSNode *,const DSNode&> DerefFun;
-
-  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
-  typedef mapped_iterator<std::vector<DSNode*>::const_iterator,
-                          DerefFun> nodes_iterator;
-  static nodes_iterator nodes_begin(const DSGraph *G) {
-    return map_iterator(G->getNodes().begin(), DerefFun(dereferenceC));
-  }
-  static nodes_iterator nodes_end(const DSGraph *G) {
-    return map_iterator(G->getNodes().end(), DerefFun(dereferenceC));
-  }
-
-  static ChildIteratorType child_begin(const NodeType *N) { return N->begin(); }
-  static ChildIteratorType child_end(const NodeType *N) { return N->end(); }
-};
-
-#endif
diff --git a/poolalloc/include/dsa/DSNode.h b/poolalloc/include/dsa/DSNode.h
deleted file mode 100644
index ff1d7d6..0000000
--- a/poolalloc/include/dsa/DSNode.h
+++ /dev/null
@@ -1,372 +0,0 @@
-//===- DSNode.h - Node definition for datastructure graphs ------*- C++ -*-===//
-//
-// Data structure graph nodes and some implementation of DSNodeHandle.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DSNODE_H
-#define LLVM_ANALYSIS_DSNODE_H
-
-#include "llvm/Analysis/DSSupport.h"
-
-template<typename BaseType>
-class DSNodeIterator;          // Data structure graph traversal iterator
-
-//===----------------------------------------------------------------------===//
-/// DSNode - Data structure node class
-///
-/// This class represents an untyped memory object of Size bytes.  It keeps
-/// track of any pointers that have been stored into the object as well as the
-/// different types represented in this object.
-///
-class DSNode {
-  /// NumReferrers - The number of DSNodeHandles pointing to this node... if
-  /// this is a forwarding node, then this is the number of node handles which
-  /// are still forwarding over us.
-  ///
-  unsigned NumReferrers;
-
-  /// ForwardNH - This NodeHandle contain the node (and offset into the node)
-  /// that this node really is.  When nodes get folded together, the node to be
-  /// eliminated has these fields filled in, otherwise ForwardNH.getNode() is
-  /// null.
-  DSNodeHandle ForwardNH;
-
-  /// Size - The current size of the node.  This should be equal to the size of
-  /// the current type record.
-  ///
-  unsigned Size;
-
-  /// ParentGraph - The graph this node is currently embedded into.
-  ///
-  DSGraph *ParentGraph;
-
-  /// Ty - Keep track of the current outer most type of this object, in addition
-  /// to whether or not it has been indexed like an array or not.  If the
-  /// isArray bit is set, the node cannot grow.
-  ///
-  const Type *Ty;                 // The type itself...
-
-  /// Links - Contains one entry for every sizeof(void*) bytes in this memory
-  /// object.  Note that if the node is not a multiple of size(void*) bytes
-  /// large, that there is an extra entry for the "remainder" of the node as
-  /// well.  For this reason, nodes of 1 byte in size do have one link.
-  ///
-  std::vector<DSNodeHandle> Links;
-
-  /// Globals - The list of global values that are merged into this node.
-  ///
-  std::vector<GlobalValue*> Globals;
-
-  void operator=(const DSNode &); // DO NOT IMPLEMENT
-  DSNode(const DSNode &);         // DO NOT IMPLEMENT
-public:
-  enum NodeTy {
-    ShadowNode  = 0,        // Nothing is known about this node...
-    AllocaNode  = 1 << 0,   // This node was allocated with alloca
-    HeapNode    = 1 << 1,   // This node was allocated with malloc
-    GlobalNode  = 1 << 2,   // This node was allocated by a global var decl
-    UnknownNode = 1 << 3,   // This node points to unknown allocated memory 
-    Incomplete  = 1 << 4,   // This node may not be complete
-
-    Modified    = 1 << 5,   // This node is modified in this context
-    Read        = 1 << 6,   // This node is read in this context
-
-    Array       = 1 << 7,   // This node is treated like an array
-    //#ifndef NDEBUG
-    DEAD        = 1 << 8,   // This node is dead and should not be pointed to
-    //#endif
-
-    Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode,
-  };
-  
-  /// NodeType - A union of the above bits.  "Shadow" nodes do not add any flags
-  /// to the nodes in the data structure graph, so it is possible to have nodes
-  /// with a value of 0 for their NodeType.
-  ///
-private:
-  unsigned short NodeType;
-public:
-
-  DSNode(const Type *T, DSGraph *G);
-  DSNode(const DSNode &, DSGraph *G);
-
-  ~DSNode() {
-    dropAllReferences();
-    assert(hasNoReferrers() && "Referrers to dead node exist!");
-  }
-
-  // Iterator for graph interface... Defined in DSGraphTraits.h
-  typedef DSNodeIterator<DSNode> iterator;
-  typedef DSNodeIterator<const DSNode> const_iterator;
-  inline iterator begin();
-  inline iterator end();
-  inline const_iterator begin() const;
-  inline const_iterator end() const;
-
-  //===--------------------------------------------------
-  // Accessors
-
-  /// getSize - Return the maximum number of bytes occupied by this object...
-  ///
-  unsigned getSize() const { return Size; }
-
-  // getType - Return the node type of this object...
-  const Type *getType() const { return Ty; }
-  bool isArray() const { return NodeType & Array; }
-
-  /// hasNoReferrers - Return true if nothing is pointing to this node at all.
-  ///
-  bool hasNoReferrers() const { return getNumReferrers() == 0; }
-
-  /// getNumReferrers - This method returns the number of referrers to the
-  /// current node.  Note that if this node is a forwarding node, this will
-  /// return the number of nodes forwarding over the node!
-  unsigned getNumReferrers() const { return NumReferrers; }
-
-  DSGraph *getParentGraph() const { return ParentGraph; }
-  void setParentGraph(DSGraph *G) { ParentGraph = G; }
-
-  /// getForwardNode - This method returns the node that this node is forwarded
-  /// to, if any.
-  DSNode *getForwardNode() const { return ForwardNH.getNode(); }
-  void stopForwarding() {
-    assert(!ForwardNH.isNull() &&
-           "Node isn't forwarding, cannot stopForwarding!");
-    ForwardNH.setNode(0);
-  }
-
-  /// hasLink - Return true if this memory object has a link in slot #LinkNo
-  ///
-  bool hasLink(unsigned Offset) const {
-    assert((Offset & ((1 << DS::PointerShift)-1)) == 0 &&
-           "Pointer offset not aligned correctly!");
-    unsigned Index = Offset >> DS::PointerShift;
-    assert(Index < Links.size() && "Link index is out of range!");
-    return Links[Index].getNode();
-  }
-
-  /// getLink - Return the link at the specified offset.
-  DSNodeHandle &getLink(unsigned Offset) {
-    assert((Offset & ((1 << DS::PointerShift)-1)) == 0 &&
-           "Pointer offset not aligned correctly!");
-    unsigned Index = Offset >> DS::PointerShift;
-    assert(Index < Links.size() && "Link index is out of range!");
-    return Links[Index];
-  }
-  const DSNodeHandle &getLink(unsigned Offset) const {
-    assert((Offset & ((1 << DS::PointerShift)-1)) == 0 &&
-           "Pointer offset not aligned correctly!");
-    unsigned Index = Offset >> DS::PointerShift;
-    assert(Index < Links.size() && "Link index is out of range!");
-    return Links[Index];
-  }
-
-  /// getNumLinks - Return the number of links in a node...
-  ///
-  unsigned getNumLinks() const { return Links.size(); }
-
-  /// 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 mergeTypeInfo(const Type *Ty, unsigned Offset,
-                     bool FoldIfIncompatible = true);
-
-  /// 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" with isArray = true.
-  ///
-  void foldNodeCompletely();
-
-  /// 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 isNodeCompletelyFolded() const;
-
-  /// setLink - Set the link at the specified offset to the specified
-  /// NodeHandle, replacing what was there.  It is uncommon to use this method,
-  /// instead one of the higher level methods should be used, below.
-  ///
-  void setLink(unsigned Offset, const DSNodeHandle &NH) {
-    assert((Offset & ((1 << DS::PointerShift)-1)) == 0 &&
-           "Pointer offset not aligned correctly!");
-    unsigned Index = Offset >> DS::PointerShift;
-    assert(Index < Links.size() && "Link index is out of range!");
-    Links[Index] = NH;
-  }
-
-  /// getPointerSize - Return the size of a pointer for the current target.
-  ///
-  unsigned getPointerSize() const { return DS::PointerSize; }
-
-  /// addEdgeTo - Add an edge from the current node to the specified node.  This
-  /// can cause merging of nodes in the graph.
-  ///
-  void addEdgeTo(unsigned Offset, const DSNodeHandle &NH);
-
-  /// 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, nothing happens).
-  ///
-  void mergeWith(const DSNodeHandle &NH, unsigned Offset);
-
-  /// 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 addGlobal(GlobalValue *GV);
-  const std::vector<GlobalValue*> &getGlobals() const { return Globals; }
-
-  /// maskNodeTypes - Apply a mask to the node types bitfield.
-  ///
-  void maskNodeTypes(unsigned Mask) {
-    NodeType &= Mask;
-  }
-
-  /// getNodeFlags - Return all of the flags set on the node.  If the DEAD flag
-  /// is set, hide it from the caller.
-  unsigned getNodeFlags() const { return NodeType & ~DEAD; }
-
-  bool isAllocaNode()  const { return NodeType & AllocaNode; }
-  bool isHeapNode()    const { return NodeType & HeapNode; }
-  bool isGlobalNode()  const { return NodeType & GlobalNode; }
-  bool isUnknownNode() const { return NodeType & UnknownNode; }
-
-  bool isModified() const   { return NodeType & Modified; }
-  bool isRead() const       { return NodeType & Read; }
-
-  bool isIncomplete() const { return NodeType & Incomplete; }
-  bool isComplete() const   { return !isIncomplete(); }
-  bool isDeadNode() const   { return NodeType & DEAD; }
-
-  DSNode *setAllocaNodeMarker()  { NodeType |= AllocaNode;  return this; }
-  DSNode *setHeapNodeMarker()    { NodeType |= HeapNode;    return this; }
-  DSNode *setGlobalNodeMarker()  { NodeType |= GlobalNode;  return this; }
-  DSNode *setUnknownNodeMarker() { NodeType |= UnknownNode; return this; }
-
-  DSNode *setIncompleteMarker() { NodeType |= Incomplete; return this; }
-  DSNode *setModifiedMarker()   { NodeType |= Modified;   return this; }
-  DSNode *setReadMarker()       { NodeType |= Read;       return this; }
-
-  void makeNodeDead() {
-    Globals.clear();
-    assert(hasNoReferrers() && "Dead node shouldn't have refs!");
-    NodeType = DEAD;
-  }
-
-  /// forwardNode - Mark this node as being obsolete, and all references to it
-  /// should be forwarded to the specified node and offset.
-  ///
-  void forwardNode(DSNode *To, unsigned Offset);
-
-  void print(std::ostream &O, const DSGraph *G) const;
-  void dump() const;
-
-  void assertOK() const;
-
-  void dropAllReferences() {
-    Links.clear();
-    if (!ForwardNH.isNull())
-      ForwardNH.setNode(0);
-  }
-
-  /// remapLinks - Change all of the Links in the current node according to the
-  /// specified mapping.
-  void remapLinks(hash_map<const DSNode*, DSNodeHandle> &OldNodeMap);
-
-  /// 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 markReachableNodes(hash_set<DSNode*> &ReachableNodes);
-
-private:
-  friend class DSNodeHandle;
-
-  // static mergeNodes - Helper for mergeWith()
-  static void MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH);
-};
-
-
-//===----------------------------------------------------------------------===//
-// Define inline DSNodeHandle functions that depend on the definition of DSNode
-//
-inline DSNode *DSNodeHandle::getNode() const {
-  assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
-          !N->ForwardNH.isNull()) && "Node handle offset out of range!");
-  if (!N || N->ForwardNH.isNull())
-    return N;
-
-  return HandleForwarding();
-}
-
-inline void DSNodeHandle::setNode(DSNode *n) {
-  assert(!n || !n->getForwardNode() && "Cannot set node to a forwarded node!");
-  if (N) N->NumReferrers--;
-  N = n;
-  if (N) {
-    N->NumReferrers++;
-    if (Offset >= N->Size) {
-      assert((Offset == 0 || N->Size == 1) &&
-             "Pointer to non-collapsed node with invalid offset!");
-      Offset = 0;
-    }
-  }
-  assert(!N || ((N->NodeType & DSNode::DEAD) == 0));
-  assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
-          !N->ForwardNH.isNull()) && "Node handle offset out of range!");
-}
-
-inline bool DSNodeHandle::hasLink(unsigned Num) const {
-  assert(N && "DSNodeHandle does not point to a node yet!");
-  return getNode()->hasLink(Num+Offset);
-}
-
-
-/// getLink - Treat this current node pointer as a pointer to a structure of
-/// some sort.  This method will return the pointer a mem[this+Num]
-///
-inline const DSNodeHandle &DSNodeHandle::getLink(unsigned Off) const {
-  assert(N && "DSNodeHandle does not point to a node yet!");
-  return getNode()->getLink(Offset+Off);
-}
-inline DSNodeHandle &DSNodeHandle::getLink(unsigned Off) {
-  assert(N && "DSNodeHandle does not point to a node yet!");
-  return getNode()->getLink(Off+Offset);
-}
-
-inline void DSNodeHandle::setLink(unsigned Off, const DSNodeHandle &NH) {
-  assert(N && "DSNodeHandle does not point to a node yet!");
-  getNode()->setLink(Off+Offset, NH);
-}
-
-///  addEdgeTo - Add an edge from the current node to the specified node.  This
-/// can cause merging of nodes in the graph.
-///
-inline void DSNodeHandle::addEdgeTo(unsigned Off, const DSNodeHandle &Node) {
-  assert(N && "DSNodeHandle does not point to a node yet!");
-  getNode()->addEdgeTo(Off+Offset, Node);
-}
-
-/// mergeWith - Merge the logical node pointed to by 'this' with the node
-/// pointed to by 'N'.
-///
-inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
-  if (N != 0)
-    getNode()->mergeWith(Node, Offset);
-  else     // No node to merge with, so just point to Node
-    *this = Node;
-}
-
-#endif
diff --git a/poolalloc/include/dsa/DSSupport.h b/poolalloc/include/dsa/DSSupport.h
deleted file mode 100644
index aff7abc..0000000
--- a/poolalloc/include/dsa/DSSupport.h
+++ /dev/null
@@ -1,288 +0,0 @@
-//===- DSSupport.h - Support for datastructure graphs -----------*- C++ -*-===//
-//
-// Support for graph nodes, call sites, and types.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DSSUPPORT_H
-#define LLVM_ANALYSIS_DSSUPPORT_H
-
-#include <vector>
-#include <functional>
-#include <string>
-#include <cassert>
-#include "Support/hash_set"
-
-class Function;
-class CallInst;
-class Value;
-class GlobalValue;
-class Type;
-
-class DSNode;                  // Each node in the graph
-class DSGraph;                 // A graph for a function
-
-namespace DS { // FIXME: After the paper, this should get cleaned up
-  enum { PointerShift = 3,     // 64bit ptrs = 3, 32 bit ptrs = 2
-         PointerSize = 1 << PointerShift
-  };
-
-  // isPointerType - Return true if this first class type is big enough to hold
-  // a pointer.
-  //
-  bool isPointerType(const Type *Ty);
-};
-
-//===----------------------------------------------------------------------===//
-/// DSNodeHandle - Implement a "handle" to a data structure node that takes care
-/// of all of the add/un'refing of the node to prevent the backpointers in the
-/// graph from getting out of date.  This class represents a "pointer" in the
-/// graph, whose destination is an indexed offset into a node.
-///
-/// Note: some functions that are marked as inline in DSNodeHandle are actually
-/// defined in DSNode.h because they need knowledge of DSNode operation. Putting
-/// them in a CPP file wouldn't help making them inlined and keeping DSNode and
-/// DSNodeHandle (and friends) in one file complicates things.
-///
-class DSNodeHandle {
-  mutable DSNode *N;
-  mutable unsigned Offset;
-  void operator==(const DSNode *N);  // DISALLOW, use to promote N to nodehandle
-public:
-  // Allow construction, destruction, and assignment...
-  DSNodeHandle(DSNode *n = 0, unsigned offs = 0) : N(0), Offset(offs) {
-    setNode(n);
-  }
-  DSNodeHandle(const DSNodeHandle &H) : N(0), Offset(0) {
-    setNode(H.getNode());
-    Offset = H.Offset;      // Must read offset AFTER the getNode()
-  }
-  ~DSNodeHandle() { setNode((DSNode*)0); }
-  DSNodeHandle &operator=(const DSNodeHandle &H) {
-    if (&H == this) return *this;  // Don't set offset to 0 if self assigning.
-    Offset = 0; setNode(H.getNode()); Offset = H.Offset;
-    return *this;
-  }
-
-  bool operator<(const DSNodeHandle &H) const {  // Allow sorting
-    return getNode() < H.getNode() || (N == H.N && Offset < H.Offset);
-  }
-  bool operator>(const DSNodeHandle &H) const { return H < *this; }
-  bool operator==(const DSNodeHandle &H) const { // Allow comparison
-    return getNode() == H.getNode() && Offset == H.Offset;
-  }
-  bool operator!=(const DSNodeHandle &H) const { return !operator==(H); }
-
-  inline void swap(DSNodeHandle &NH) {
-    std::swap(Offset, NH.Offset);
-    std::swap(N, NH.N);
-  }
-
-  /// isNull - Check to see if getNode() == 0, without going through the trouble
-  /// of checking to see if we are forwarding...
-  bool isNull() const { return N == 0; }
-
-  // Allow explicit conversion to DSNode...
-  inline DSNode *getNode() const;  // Defined inline in DSNode.h
-  unsigned getOffset() const { return Offset; }
-
-  inline void setNode(DSNode *N);  // Defined inline in DSNode.h
-  void setOffset(unsigned O) {
-    //assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
-    //       !N->ForwardNH.isNull()) && "Node handle offset out of range!");
-    //assert((!N || O < N->Size || (N->Size == 0 && O == 0) ||
-    //       !N->ForwardNH.isNull()) && "Node handle offset out of range!");
-    Offset = O;
-  }
-
-  void addEdgeTo(unsigned LinkNo, const DSNodeHandle &N);
-  void addEdgeTo(const DSNodeHandle &N) { addEdgeTo(0, N); }
-
-  /// mergeWith - Merge the logical node pointed to by 'this' with the node
-  /// pointed to by 'N'.
-  ///
-  void mergeWith(const DSNodeHandle &N);
-
-  // hasLink - Return true if there is a link at the specified offset...
-  inline bool hasLink(unsigned Num) const;
-
-  /// getLink - Treat this current node pointer as a pointer to a structure of
-  /// some sort.  This method will return the pointer a mem[this+Num]
-  ///
-  inline const DSNodeHandle &getLink(unsigned Num) const;
-  inline DSNodeHandle &getLink(unsigned Num);
-
-  inline void setLink(unsigned Num, const DSNodeHandle &NH);
-private:
-  DSNode *HandleForwarding() const;
-};
-
-namespace std {
-  inline void swap(DSNodeHandle &NH1, DSNodeHandle &NH2) { NH1.swap(NH2); }
-}
-
-//===----------------------------------------------------------------------===//
-/// DSCallSite - Representation of a call site via its call instruction,
-/// the DSNode handle for the callee function (or function pointer), and
-/// the DSNode handles for the function arguments.
-/// 
-class DSCallSite {
-  CallInst    *Inst;                 // Actual call site
-  Function    *CalleeF;              // The function called (direct call)
-  DSNodeHandle CalleeN;              // The function node called (indirect call)
-  DSNodeHandle RetVal;               // Returned value
-  std::vector<DSNodeHandle> CallArgs;// The pointer arguments
-
-  static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src,
-                     const hash_map<const DSNode*, DSNode*> &NodeMap) {
-    if (DSNode *N = Src.getNode()) {
-      hash_map<const DSNode*, DSNode*>::const_iterator I = NodeMap.find(N);
-      assert(I != NodeMap.end() && "Not not in mapping!");
-
-      NH.setOffset(Src.getOffset());
-      NH.setNode(I->second);
-    }
-  }
-
-  static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src,
-                     const hash_map<const DSNode*, DSNodeHandle> &NodeMap) {
-    if (DSNode *N = Src.getNode()) {
-      hash_map<const DSNode*, DSNodeHandle>::const_iterator I = NodeMap.find(N);
-      assert(I != NodeMap.end() && "Not not in mapping!");
-
-      NH.setOffset(Src.getOffset()+I->second.getOffset());
-      NH.setNode(I->second.getNode());
-    }
-  }
-
-  DSCallSite();                         // DO NOT IMPLEMENT
-public:
-  /// Constructor.  Note - This ctor destroys the argument vector passed in.  On
-  /// exit, the argument vector is empty.
-  ///
-  DSCallSite(CallInst &inst, const DSNodeHandle &rv, DSNode *Callee,
-             std::vector<DSNodeHandle> &Args)
-    : Inst(&inst), CalleeF(0), CalleeN(Callee), RetVal(rv) {
-    assert(Callee && "Null callee node specified for call site!");
-    Args.swap(CallArgs);
-  }
-  DSCallSite(CallInst &inst, const DSNodeHandle &rv, Function *Callee,
-             std::vector<DSNodeHandle> &Args)
-    : Inst(&inst), CalleeF(Callee), RetVal(rv) {
-    assert(Callee && "Null callee function specified for call site!");
-    Args.swap(CallArgs);
-  }
-
-  DSCallSite(const DSCallSite &DSCS)   // Simple copy ctor
-    : Inst(DSCS.Inst), CalleeF(DSCS.CalleeF), CalleeN(DSCS.CalleeN),
-      RetVal(DSCS.RetVal), CallArgs(DSCS.CallArgs) {}
-
-  /// Mapping copy constructor - This constructor takes a preexisting call site
-  /// to copy plus a map that specifies how the links should be transformed.
-  /// This is useful when moving a call site from one graph to another.
-  ///
-  template<typename MapTy>
-  DSCallSite(const DSCallSite &FromCall, const MapTy &NodeMap) {
-    Inst = FromCall.Inst;
-    InitNH(RetVal, FromCall.RetVal, NodeMap);
-    InitNH(CalleeN, FromCall.CalleeN, NodeMap);
-    CalleeF = FromCall.CalleeF;
-
-    CallArgs.resize(FromCall.CallArgs.size());
-    for (unsigned i = 0, e = FromCall.CallArgs.size(); i != e; ++i)
-      InitNH(CallArgs[i], FromCall.CallArgs[i], NodeMap);
-  }
-
-  const DSCallSite &operator=(const DSCallSite &RHS) {
-    Inst     = RHS.Inst;
-    CalleeF  = RHS.CalleeF;
-    CalleeN  = RHS.CalleeN;
-    RetVal   = RHS.RetVal;
-    CallArgs = RHS.CallArgs;
-    return *this;
-  }
-
-  /// isDirectCall - Return true if this call site is a direct call of the
-  /// function specified by getCalleeFunc.  If not, it is an indirect call to
-  /// the node specified by getCalleeNode.
-  ///
-  bool isDirectCall() const { return CalleeF != 0; }
-  bool isIndirectCall() const { return !isDirectCall(); }
-
-
-  // Accessor functions...
-  Function           &getCaller()     const;
-  CallInst           &getCallInst()   const { return *Inst; }
-        DSNodeHandle &getRetVal()           { return RetVal; }
-  const DSNodeHandle &getRetVal()     const { return RetVal; }
-
-  DSNode *getCalleeNode() const {
-    assert(!CalleeF && CalleeN.getNode()); return CalleeN.getNode();
-  }
-  Function *getCalleeFunc() const {
-    assert(!CalleeN.getNode() && CalleeF); return CalleeF;
-  }
-
-  unsigned            getNumPtrArgs() const { return CallArgs.size(); }
-
-  DSNodeHandle &getPtrArg(unsigned i) {
-    assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
-    return CallArgs[i];
-  }
-  const DSNodeHandle &getPtrArg(unsigned i) const {
-    assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
-    return CallArgs[i];
-  }
-
-  void swap(DSCallSite &CS) {
-    if (this != &CS) {
-      std::swap(Inst, CS.Inst);
-      std::swap(RetVal, CS.RetVal);
-      std::swap(CalleeN, CS.CalleeN);
-      std::swap(CalleeF, CS.CalleeF);
-      std::swap(CallArgs, CS.CallArgs);
-    }
-  }
-
-  // MergeWith - Merge the return value and parameters of the these two call
-  // sites.
-  void mergeWith(DSCallSite &CS) {
-    getRetVal().mergeWith(CS.getRetVal());
-    unsigned MinArgs = getNumPtrArgs();
-    if (CS.getNumPtrArgs() < MinArgs) MinArgs = CS.getNumPtrArgs();
-
-    for (unsigned a = 0; a != MinArgs; ++a)
-      getPtrArg(a).mergeWith(CS.getPtrArg(a));
-  }
-
-  /// 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 markReachableNodes(hash_set<DSNode*> &Nodes);
-
-  bool operator<(const DSCallSite &CS) const {
-    if (isDirectCall()) {      // This must sort by callee first!
-      if (CS.isIndirectCall()) return true;
-      if (CalleeF < CS.CalleeF) return true;
-      if (CalleeF > CS.CalleeF) return false;
-    } else {
-      if (CS.isDirectCall()) return false;
-      if (CalleeN < CS.CalleeN) return true;
-      if (CalleeN > CS.CalleeN) return false;
-    }
-    if (RetVal < CS.RetVal) return true;
-    if (RetVal > CS.RetVal) return false;
-    return CallArgs < CS.CallArgs;
-  }
-
-  bool operator==(const DSCallSite &CS) const {
-    return RetVal == CS.RetVal && CalleeN == CS.CalleeN &&
-           CalleeF == CS.CalleeF && CallArgs == CS.CallArgs;
-  }
-};
-
-namespace std {
-  inline void swap(DSCallSite &CS1, DSCallSite &CS2) { CS1.swap(CS2); }
-}
-#endif
diff --git a/poolalloc/include/dsa/DataStructure.h b/poolalloc/include/dsa/DataStructure.h
deleted file mode 100644
index d8f30d2..0000000
--- a/poolalloc/include/dsa/DataStructure.h
+++ /dev/null
@@ -1,176 +0,0 @@
-//===- DataStructure.h - Build data structure graphs ------------*- C++ -*-===//
-//
-// Implement the LLVM data structure analysis library.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_DATA_STRUCTURE_H
-#define LLVM_ANALYSIS_DATA_STRUCTURE_H
-
-#include "llvm/Pass.h"
-#include "Support/hash_set"
-
-class Type;
-class CallInst;
-class DSGraph;
-class DSNode;
-class DSCallSite;
-
-// FIXME: move this stuff to a private header
-namespace DataStructureAnalysis {
-  // isPointerType - Return true if this first class type is big enough to hold
-  // a pointer.
-  //
-  bool isPointerType(const Type *Ty);
-}
-
-
-// LocalDataStructures - The analysis that computes the local data structure
-// graphs for all of the functions in the program.
-//
-// FIXME: This should be a Function pass that can be USED by a Pass, and would
-// be automatically preserved.  Until we can do that, this is a Pass.
-//
-class LocalDataStructures : public Pass {
-  // DSInfo, one graph for each function
-  hash_map<Function*, DSGraph*> DSInfo;
-  DSGraph *GlobalsGraph;
-public:
-  ~LocalDataStructures() { releaseMemory(); }
-
-  virtual bool run(Module &M);
-
-  bool hasGraph(const Function &F) const {
-    return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
-  }
-
-  // getDSGraph - Return the data structure graph for the specified function.
-  DSGraph &getDSGraph(const Function &F) const {
-    hash_map<Function*, DSGraph*>::const_iterator I =
-      DSInfo.find(const_cast<Function*>(&F));
-    assert(I != DSInfo.end() && "Function not in module!");
-    return *I->second;
-  }
-
-  DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
-
-  // print - Print out the analysis results...
-  void print(std::ostream &O, const Module *M) const;
-
-  // If the pass pipeline is done with this pass, we can release our memory...
-  virtual void releaseMemory();
-
-  // getAnalysisUsage - This obviously provides a data structure graph.
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.setPreservesAll();
-  }
-};
-
-
-// BUDataStructures - The analysis that computes the interprocedurally closed
-// data structure graphs for all of the functions in the program.  This pass
-// only performs a "Bottom Up" propagation (hence the name).
-//
-class BUDataStructures : public Pass {
-  // DSInfo, one graph for each function
-  hash_map<Function*, DSGraph*> DSInfo;
-  DSGraph *GlobalsGraph;
-  hash_multimap<CallInst*, Function*> ActualCallees;
-public:
-  ~BUDataStructures() { releaseMemory(); }
-
-  virtual bool run(Module &M);
-
-  bool hasGraph(const Function &F) const {
-    return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
-  }
-
-  // getDSGraph - Return the data structure graph for the specified function.
-  DSGraph &getDSGraph(const Function &F) const {
-    hash_map<Function*, DSGraph*>::const_iterator I =
-      DSInfo.find(const_cast<Function*>(&F));
-    assert(I != DSInfo.end() && "Function not in module!");
-    return *I->second;
-  }
-
-  DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
-
-  // print - Print out the analysis results...
-  void print(std::ostream &O, const Module *M) const;
-
-  // If the pass pipeline is done with this pass, we can release our memory...
-  virtual void releaseMemory();
-
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.setPreservesAll();
-    AU.addRequired<LocalDataStructures>();
-  }
-
-  typedef hash_multimap<CallInst*, Function*> ActualCalleesTy;
-  const ActualCalleesTy &getActualCallees() const {
-    return ActualCallees;
-  }
-
-private:
-  void calculateGraph(DSGraph &G);
-
-  void calculateReachableGraphs(Function *F);
-
-
-  DSGraph &getOrCreateGraph(Function *F);
-
-  unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
-                           unsigned &NextID, 
-                           hash_map<Function*, unsigned> &ValMap);
-};
-
-
-// TDDataStructures - Analysis that computes new data structure graphs
-// for each function using the closed graphs for the callers computed
-// by the bottom-up pass.
-//
-class TDDataStructures : public Pass {
-  // DSInfo, one graph for each function
-  hash_map<Function*, DSGraph*> DSInfo;
-  hash_set<Function*> ArgsRemainIncomplete;
-  DSGraph *GlobalsGraph;
-public:
-  ~TDDataStructures() { releaseMyMemory(); }
-
-  virtual bool run(Module &M);
-
-  bool hasGraph(const Function &F) const {
-    return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
-  }
-
-  // getDSGraph - Return the data structure graph for the specified function.
-  DSGraph &getDSGraph(const Function &F) const {
-    hash_map<Function*, DSGraph*>::const_iterator I =
-      DSInfo.find(const_cast<Function*>(&F));
-    assert(I != DSInfo.end() && "Function not in module!");
-    return *I->second;
-  }
-
-  DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
-
-  // print - Print out the analysis results...
-  void print(std::ostream &O, const Module *M) const;
-
-  // If the pass pipeline is done with this pass, we can release our memory...
-  virtual void releaseMyMemory();
-
-  // getAnalysisUsage - This obviously provides a data structure graph.
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.setPreservesAll();
-    AU.addRequired<BUDataStructures>();
-  }
-
-private:
-  void inlineGraphIntoCallees(DSGraph &G);
-  DSGraph &getOrCreateDSGraph(Function &F);
-  void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
-                        std::vector<DSGraph*> &PostOrder,
-                        const BUDataStructures::ActualCalleesTy &ActualCallees);
-};
-
-#endif
diff --git a/poolalloc/include/poolalloc/PoolAllocate.h b/poolalloc/include/poolalloc/PoolAllocate.h
deleted file mode 100644
index b6806c1..0000000
--- a/poolalloc/include/poolalloc/PoolAllocate.h
+++ /dev/null
@@ -1,156 +0,0 @@
-//===-- PoolAllocate.h - Pool allocation pass -------------------*- C++ -*-===//
-//
-// This transform changes programs so that disjoint data structures are
-// allocated out of different pools of memory, increasing locality.  This header
-// file exposes information about the pool allocation itself so that follow-on
-// passes may extend or use the pool allocation for analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_POOLALLOCATE_H
-#define LLVM_TRANSFORMS_POOLALLOCATE_H
-
-#include "llvm/Pass.h"
-#include "Support/hash_set"
-#include "Support/EquivalenceClasses.h"
-class BUDataStructures;
-class TDDataStructures;
-class DSNode;
-class DSGraph;
-class CallInst;
-
-namespace PA {
-  /// FuncInfo - Represent the pool allocation information for one function in
-  /// the program.  Note that many functions must actually be cloned in order
-  /// for pool allocation to add arguments to the function signature.  In this
-  /// case, the Clone and NewToOldValueMap information identify how the clone
-  /// maps to the original function...
-  ///
-  struct FuncInfo {
-    /// MarkedNodes - The set of nodes which are not locally pool allocatable in
-    /// the current function.
-    ///
-    hash_set<DSNode*> MarkedNodes;
-
-    /// Clone - The cloned version of the function, if applicable.
-    Function *Clone;
-
-    /// ArgNodes - The list of DSNodes which have pools passed in as arguments.
-    /// 
-    std::vector<DSNode*> ArgNodes;
-
-    /// In order to handle indirect functions, the start and end of the 
-    /// arguments that are useful to this function. 
-    /// The pool arguments useful to this function are PoolArgFirst to 
-    /// PoolArgLast not inclusive.
-    int PoolArgFirst, PoolArgLast;
-    
-    /// PoolDescriptors - The Value* (either an argument or an alloca) which
-    /// defines the pool descriptor for this DSNode.  Pools are mapped one to
-    /// one with nodes in the DSGraph, so this contains a pointer to the node it
-    /// corresponds to.  In addition, the pool is initialized by calling the
-    /// "poolinit" library function with a chunk of memory allocated with an
-    /// alloca instruction.  This entry contains a pointer to that alloca if the
-    /// pool is locally allocated or the argument it is passed in through if
-    /// not.
-    /// Note: Does not include pool arguments that are passed in because of
-    /// indirect function calls that are not used in the function.
-    std::map<DSNode*, Value*> PoolDescriptors;
-
-    /// NewToOldValueMap - When and if a function needs to be cloned, this map
-    /// contains a mapping from all of the values in the new function back to
-    /// the values they correspond to in the old function.
-    ///
-    std::map<Value*, const Value*> NewToOldValueMap;
-  };
-}
-
-/// PoolAllocate - The main pool allocation pass
-///
-class PoolAllocate : public Pass {
-  Module *CurModule;
-  BUDataStructures *BU;
-
-  TDDataStructures *TDDS;
-
-  hash_set<Function*> InlinedFuncs;
-  
-  std::map<Function*, PA::FuncInfo> FunctionInfo;
-
-  void buildIndirectFunctionSets(Module &M);   
-
-  void FindFunctionPoolArgs(Function &F);   
-  
-  // Debug function to print the FuncECs
-  void printFuncECs();
-  
- public:
-  Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolAllocArray, *PoolFree;
-
-  // Equivalence class where functions that can potentially be called via
-  // the same function pointer are in the same class.
-  EquivalenceClasses<Function *> FuncECs;
-
-  // Map from an Indirect CallInst to the set of Functions that it can point to
-  std::multimap<CallInst *, Function *> CallInstTargets;
-
-  // This maps an equivalence class to the last pool argument number for that 
-  // class. This is used because the pool arguments for all functions within
-  // an equivalence class is passed to all the functions in that class.
-  // If an equivalence class does not require pool arguments, it is not
-  // on this map.
-  std::map<Function *, int> EqClass2LastPoolArg;
-
-  // Exception flags
-  // CollapseFlag set if all data structures are not pool allocated, due to
-  // collapsing of nodes in the DS graph
-  unsigned CollapseFlag;
-  
- public:
-  bool run(Module &M);
-  
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-  
-  BUDataStructures &getBUDataStructures() const { return *BU; }
-  
-  PA::FuncInfo *getFuncInfo(Function &F) {
-    std::map<Function*, PA::FuncInfo>::iterator I = FunctionInfo.find(&F);
-    return I != FunctionInfo.end() ? &I->second : 0;
-  }
-
-  Module *getCurModule() { return CurModule; }
-
- private:
-  
-  /// AddPoolPrototypes - Add prototypes for the pool functions to the
-  /// specified module and update the Pool* instance variables to point to
-  /// them.
-  ///
-  void AddPoolPrototypes();
-  
-  /// MakeFunctionClone - If the specified function needs to be modified for
-  /// pool allocation support, make a clone of it, adding additional arguments
-  /// as neccesary, and return it.  If not, just return null.
-  ///
-  Function *MakeFunctionClone(Function &F);
-  
-  /// ProcessFunctionBody - Rewrite the body of a transformed function to use
-  /// pool allocation where appropriate.
-  ///
-  void ProcessFunctionBody(Function &Old, Function &New);
-  
-  /// CreatePools - This creates the pool initialization and destruction code
-  /// for the DSNodes specified by the NodesToPA list.  This adds an entry to
-  /// the PoolDescriptors map for each DSNode.
-  ///
-  void CreatePools(Function &F, const std::vector<DSNode*> &NodesToPA,
-                   std::map<DSNode*, Value*> &PoolDescriptors);
-  
-  void TransformFunctionBody(Function &F, Function &OldF,
-                             DSGraph &G, PA::FuncInfo &FI);
-
-  void InlineIndirectCalls(Function &F, DSGraph &G, 
-			   hash_set<Function*> &visited);
-};
-
-#endif
diff --git a/poolalloc/lib/DSA/BottomUpClosure.cpp b/poolalloc/lib/DSA/BottomUpClosure.cpp
deleted file mode 100644
index dd141f2..0000000
--- a/poolalloc/lib/DSA/BottomUpClosure.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-//===- BottomUpClosure.cpp - Compute bottom-up interprocedural closure ----===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Module.h"
-#include "Support/Statistic.h"
-#include "Support/Debug.h"
-#include "DSCallSiteIterator.h"
-
-namespace {
-  Statistic<> MaxSCC("budatastructure", "Maximum SCC Size in Call Graph");
-  Statistic<> NumBUInlines("budatastructures", "Number of graphs inlined");
-  Statistic<> NumCallEdges("budatastructures", "Number of 'actual' call edges");
-  
-  RegisterAnalysis<BUDataStructures>
-  X("budatastructure", "Bottom-up Data Structure Analysis");
-}
-
-using namespace DS;
-
-// run - Calculate the bottom up data structure graphs for each function in the
-// program.
-//
-bool BUDataStructures::run(Module &M) {
-  LocalDataStructures &LocalDSA = getAnalysis<LocalDataStructures>();
-  GlobalsGraph = new DSGraph(LocalDSA.getGlobalsGraph());
-  GlobalsGraph->setPrintAuxCalls();
-
-  Function *MainFunc = M.getMainFunction();
-  if (MainFunc)
-    calculateReachableGraphs(MainFunc);
-
-  // 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->isExternal() && !DSInfo.count(I)) {
-#ifndef NDEBUG
-      if (MainFunc)
-        std::cerr << "*** Function unreachable from main: "
-                  << I->getName() << "\n";
-#endif
-      calculateReachableGraphs(I);    // Calculate all graphs...
-    }
-
-  NumCallEdges += ActualCallees.size();
-  return false;
-}
-
-void BUDataStructures::calculateReachableGraphs(Function *F) {
-  std::vector<Function*> Stack;
-  hash_map<Function*, unsigned> ValMap;
-  unsigned NextID = 1;
-  calculateGraphs(F, Stack, NextID, ValMap);
-}
-
-DSGraph &BUDataStructures::getOrCreateGraph(Function *F) {
-  // Has the graph already been created?
-  DSGraph *&Graph = DSInfo[F];
-  if (Graph) return *Graph;
-
-  // Copy the local version into DSInfo...
-  Graph = new DSGraph(getAnalysis<LocalDataStructures>().getDSGraph(*F));
-
-  Graph->setGlobalsGraph(GlobalsGraph);
-  Graph->setPrintAuxCalls();
-
-  // Start with a copy of the original call sites...
-  Graph->getAuxFunctionCalls() = Graph->getFunctionCalls();
-  return *Graph;
-}
-
-unsigned BUDataStructures::calculateGraphs(Function *F,
-                                           std::vector<Function*> &Stack,
-                                           unsigned &NextID, 
-                                     hash_map<Function*, unsigned> &ValMap) {
-  assert(ValMap.find(F) == ValMap.end() && "Shouldn't revisit functions!");
-  unsigned Min = NextID++, MyID = Min;
-  ValMap[F] = Min;
-  Stack.push_back(F);
-
-  if (F->isExternal()) {   // sprintf, fprintf, sscanf, etc...
-    // No callees!
-    Stack.pop_back();
-    ValMap[F] = ~0;
-    return Min;
-  }
-
-  DSGraph &Graph = getOrCreateGraph(F);
-
-  // The edges out of the current node are the call site targets...
-  for (DSCallSiteIterator I = DSCallSiteIterator::begin_aux(Graph),
-         E = DSCallSiteIterator::end_aux(Graph); I != E; ++I) {
-    Function *Callee = *I;
-    unsigned M;
-    // Have we visited the destination function yet?
-    hash_map<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(std::cerr << "Visiting single node SCC #: " << MyID << " fn: "
-                    << F->getName() << "\n");
-    Stack.pop_back();
-    DSGraph &G = getDSGraph(*F);
-    DEBUG(std::cerr << "  [BU] Calculating graph for: " << F->getName()<< "\n");
-    calculateGraph(G);
-    DEBUG(std::cerr << "  [BU] Done inlining: " << F->getName() << " ["
-                    << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size()
-                    << "]\n");
-
-    if (MaxSCC < 1) MaxSCC = 1;
-
-    // Should we revisit the graph?
-    if (DSCallSiteIterator::begin_aux(G) != DSCallSiteIterator::end_aux(G)) {
-      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
-    //
-    hash_set<Function*> SCCFunctions;
-
-    Function *NF;
-    std::vector<Function*>::iterator FirstInSCC = Stack.end();
-    DSGraph *SCCGraph = 0;
-    do {
-      NF = *--FirstInSCC;
-      ValMap[NF] = ~0U;
-      SCCFunctions.insert(NF);
-
-      // Figure out which graph is the largest one, in order to speed things up
-      // a bit in situations where functions in the SCC have widely different
-      // graph sizes.
-      DSGraph &NFGraph = getDSGraph(*NF);
-      if (!SCCGraph || SCCGraph->getGraphSize() < NFGraph.getGraphSize())
-        SCCGraph = &NFGraph;
-    } while (NF != F);
-
-    std::cerr << "Calculating graph for SCC #: " << MyID << " of size: "
-              << SCCFunctions.size() << "\n";
-
-    // Compute the Max SCC Size...
-    if (MaxSCC < SCCFunctions.size())
-      MaxSCC = SCCFunctions.size();
-
-    // First thing first, collapse all of the DSGraphs into a single graph for
-    // the entire SCC.  We computed the largest graph, so clone all of the other
-    // (smaller) graphs into it.  Discard all of the old graphs.
-    //
-    for (hash_set<Function*>::iterator I = SCCFunctions.begin(),
-           E = SCCFunctions.end(); I != E; ++I) {
-      DSGraph &G = getDSGraph(**I);
-      if (&G != SCCGraph) {
-        DSGraph::NodeMapTy NodeMap;
-        SCCGraph->cloneInto(G, SCCGraph->getScalarMap(),
-                            SCCGraph->getReturnNodes(), NodeMap, 0);
-        // Update the DSInfo map and delete the old graph...
-        DSInfo[*I] = SCCGraph;
-        delete &G;
-      }
-    }
-
-    // Clean up the graph before we start inlining a bunch again...
-    SCCGraph->removeTriviallyDeadNodes();
-
-    // Now that we have one big happy family, resolve all of the call sites in
-    // the graph...
-    calculateGraph(*SCCGraph);
-    DEBUG(std::cerr << "  [BU] Done inlining SCC  [" << SCCGraph->getGraphSize()
-                    << "+" << SCCGraph->getAuxFunctionCalls().size() << "]\n");
-
-    std::cerr << "DONE with SCC #: " << MyID << "\n";
-
-    // We never have to revisit "SCC" processed functions...
-    
-    // Drop the stuff we don't need from the end of the stack
-    Stack.erase(FirstInSCC, Stack.end());
-    return MyID;
-  }
-
-  return MyID;  // == Min
-}
-
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void BUDataStructures::releaseMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
-
-void BUDataStructures::calculateGraph(DSGraph &Graph) {
-  // 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::vector<DSCallSite> TempFCs;
-  std::vector<DSCallSite> &AuxCallsList = Graph.getAuxFunctionCalls();
-  TempFCs.swap(AuxCallsList);
-
-  DSGraph::ReturnNodesTy &ReturnNodes = Graph.getReturnNodes();
-
-  // Loop over all of the resolvable call sites
-  unsigned LastCallSiteIdx = ~0U;
-  for (DSCallSiteIterator I = DSCallSiteIterator::begin(TempFCs),
-         E = DSCallSiteIterator::end(TempFCs); I != E; ++I) {
-    // If we skipped over any call sites, they must be unresolvable, copy them
-    // to the real call site list.
-    LastCallSiteIdx++;
-    for (; LastCallSiteIdx < I.getCallSiteIdx(); ++LastCallSiteIdx)
-      AuxCallsList.push_back(TempFCs[LastCallSiteIdx]);
-    LastCallSiteIdx = I.getCallSiteIdx();
-    
-    // Resolve the current call...
-    Function *Callee = *I;
-    DSCallSite CS = I.getCallSite();
-
-    if (Callee->isExternal()) {
-      // Ignore this case, simple varargs functions we cannot stub out!
-    } else if (ReturnNodes.find(Callee) != ReturnNodes.end()) {
-      // Self recursion... simply link up the formal arguments with the
-      // actual arguments...
-      DEBUG(std::cerr << "    Self Inlining: " << Callee->getName() << "\n");
-
-      // Handle self recursion by resolving the arguments and return value
-      Graph.mergeInGraph(CS, *Callee, Graph, 0);
-
-    } else {
-      ActualCallees.insert(std::make_pair(&CS.getCallInst(), Callee));
-
-      // Get the data structure graph for the called function.
-      //
-      DSGraph &GI = getDSGraph(*Callee);  // Graph to inline
-      
-      DEBUG(std::cerr << "    Inlining graph for " << Callee->getName()
-            << "[" << GI.getGraphSize() << "+"
-            << GI.getAuxFunctionCalls().size() << "] into '"
-            << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() << "+"
-            << Graph.getAuxFunctionCalls().size() << "]\n");
-      
-      // Handle self recursion by resolving the arguments and return value
-      Graph.mergeInGraph(CS, *Callee, GI,
-                         DSGraph::KeepModRefBits | 
-                         DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes);
-      ++NumBUInlines;
-
-#if 0
-      Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" +
-                             Callee->getName());
-#endif
-    }
-  }
-
-  // Make sure to catch any leftover unresolvable calls...
-  for (++LastCallSiteIdx; LastCallSiteIdx < TempFCs.size(); ++LastCallSiteIdx)
-    AuxCallsList.push_back(TempFCs[LastCallSiteIdx]);
-
-  TempFCs.clear();
-
-  // Re-materialize nodes from the globals graph.
-  // Do not ignore globals inlined from callees -- they are not up-to-date!
-  Graph.getInlinedGlobals().clear();
-  Graph.updateFromGlobalGraph();
-
-  // 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);
-
-  //Graph.writeGraphToFile(std::cerr, "bu_" + F.getName());
-}
-
diff --git a/poolalloc/lib/DSA/DSCallSiteIterator.h b/poolalloc/lib/DSA/DSCallSiteIterator.h
deleted file mode 100644
index acbf808..0000000
--- a/poolalloc/lib/DSA/DSCallSiteIterator.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//===- DSCallSiteIterator.h - Iterator for DSGraph call sites ---*- C++ -*-===//
-//
-// This file implements an iterator for complete call sites in DSGraphs.  This
-// code can either iterator over the normal call list or the aux calls list, and
-// is used by the TD and BU passes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef DSCALLSITEITERATOR_H
-#define DSCALLSITEITERATOR_H
-
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Function.h"
-
-struct DSCallSiteIterator {
-  // FCs are the edges out of the current node are the call site targets...
-  const std::vector<DSCallSite> *FCs;
-  unsigned CallSite;
-  unsigned CallSiteEntry;
-
-  DSCallSiteIterator(const std::vector<DSCallSite> &CS) : FCs(&CS) {
-    CallSite = 0; CallSiteEntry = 0;
-    advanceToValidCallee();
-  }
-
-  // End iterator ctor...
-  DSCallSiteIterator(const std::vector<DSCallSite> &CS, bool) : FCs(&CS) {
-    CallSite = FCs->size(); CallSiteEntry = 0;
-  }
-
-  static bool isVAHackFn(const Function *F) {
-    return F->getName() == "printf"  || F->getName() == "sscanf" ||
-      F->getName() == "fprintf" || F->getName() == "open" ||
-      F->getName() == "sprintf" || F->getName() == "fputs" ||
-      F->getName() == "fscanf" || F->getName() == "bzero" ||
-      F->getName() == "memset";
-  }
-
-  // isUnresolvableFunction - Return true if this is an unresolvable
-  // external function.  A direct or indirect call to this cannot be resolved.
-  // 
-  static bool isUnresolvableFunc(const Function* callee) {
-    return callee->isExternal() && !isVAHackFn(callee);
-  } 
-
-  void advanceToValidCallee() {
-    while (CallSite < FCs->size()) {
-      if ((*FCs)[CallSite].isDirectCall()) {
-        if (CallSiteEntry == 0 &&        // direct call only has one target...
-            ! isUnresolvableFunc((*FCs)[CallSite].getCalleeFunc()))
-          return;                       // and not an unresolvable external func
-      } else {
-        DSNode *CalleeNode = (*FCs)[CallSite].getCalleeNode();
-        if (CallSiteEntry || isCompleteNode(CalleeNode)) {
-          const std::vector<GlobalValue*> &Callees = CalleeNode->getGlobals();
-          while (CallSiteEntry < Callees.size()) {
-            if (isa<Function>(Callees[CallSiteEntry]))
-              return;
-            ++CallSiteEntry;
-          }
-        }
-      }
-      CallSiteEntry = 0;
-      ++CallSite;
-    }
-  }
-  
-  // isCompleteNode - Return true if we know all of the targets of this node,
-  // and if the call sites are not external.
-  //
-  static inline bool isCompleteNode(DSNode *N) {
-    if (N->isIncomplete()) return false;
-    const std::vector<GlobalValue*> &Callees = N->getGlobals();
-    for (unsigned i = 0, e = Callees.size(); i != e; ++i)
-      if (isUnresolvableFunc(cast<Function>(Callees[i])))
-        return false;               // Unresolvable external function found...
-    return true;  // otherwise ok
-  }
-
-public:
-  static DSCallSiteIterator begin_aux(DSGraph &G) {
-    return G.getAuxFunctionCalls();
-  }
-  static DSCallSiteIterator end_aux(DSGraph &G) {
-    return DSCallSiteIterator(G.getAuxFunctionCalls(), true);
-  }
-  static DSCallSiteIterator begin_std(DSGraph &G) {
-    return G.getFunctionCalls();
-  }
-  static DSCallSiteIterator end_std(DSGraph &G) {
-    return DSCallSiteIterator(G.getFunctionCalls(), true);
-  }
-  static DSCallSiteIterator begin(std::vector<DSCallSite> &CSs) { return CSs; }
-  static DSCallSiteIterator end(std::vector<DSCallSite> &CSs) {
-    return DSCallSiteIterator(CSs, true);
-  }
-  bool operator==(const DSCallSiteIterator &CSI) const {
-    return CallSite == CSI.CallSite && CallSiteEntry == CSI.CallSiteEntry;
-  }
-  bool operator!=(const DSCallSiteIterator &CSI) const {
-    return !operator==(CSI);
-  }
-
-  unsigned getCallSiteIdx() const { return CallSite; }
-  const DSCallSite &getCallSite() const { return (*FCs)[CallSite]; }
-
-  Function *operator*() const {
-    if ((*FCs)[CallSite].isDirectCall()) {
-      return (*FCs)[CallSite].getCalleeFunc();
-    } else {
-      DSNode *Node = (*FCs)[CallSite].getCalleeNode();
-      return cast<Function>(Node->getGlobals()[CallSiteEntry]);
-    }
-  }
-
-  DSCallSiteIterator& operator++() {                // Preincrement
-    ++CallSiteEntry;
-    advanceToValidCallee();
-    return *this;
-  }
-  DSCallSiteIterator operator++(int) { // Postincrement
-    DSCallSiteIterator tmp = *this; ++*this; return tmp; 
-  }
-};
-
-#endif
diff --git a/poolalloc/lib/DSA/DataStructure.cpp b/poolalloc/lib/DSA/DataStructure.cpp
deleted file mode 100644
index 241c2a9..0000000
--- a/poolalloc/lib/DSA/DataStructure.cpp
+++ /dev/null
@@ -1,1612 +0,0 @@
-//===- DataStructure.cpp - Implement the core data structure analysis -----===//
-//
-// This file implements the core data structure functionality.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Function.h"
-#include "llvm/iOther.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Assembly/Writer.h"
-#include "Support/Debug.h"
-#include "Support/STLExtras.h"
-#include "Support/Statistic.h"
-#include "Support/Timer.h"
-#include <algorithm>
-
-namespace {
-  Statistic<> NumFolds          ("dsnode", "Number of nodes completely folded");
-  Statistic<> NumCallNodesMerged("dsnode", "Number of call nodes merged");
-};
-
-namespace DS {   // TODO: FIXME
-  extern TargetData TD;
-}
-using namespace DS;
-
-DSNode *DSNodeHandle::HandleForwarding() const {
-  assert(!N->ForwardNH.isNull() && "Can only be invoked if forwarding!");
-
-  // 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;
-}
-
-//===----------------------------------------------------------------------===//
-// DSNode Implementation
-//===----------------------------------------------------------------------===//
-
-DSNode::DSNode(const Type *T, DSGraph *G)
-  : NumReferrers(0), Size(0), ParentGraph(G), Ty(Type::VoidTy), NodeType(0) {
-  // Add the type entry if it is specified...
-  if (T) mergeTypeInfo(T, 0);
-  G->getNodes().push_back(this);
-}
-
-// DSNode copy constructor... do not copy over the referrers list!
-DSNode::DSNode(const DSNode &N, DSGraph *G)
-  : NumReferrers(0), Size(N.Size), ParentGraph(G),
-    Ty(N.Ty), Links(N.Links), Globals(N.Globals), NodeType(N.NodeType) {
-  G->getNodes().push_back(this);
-}
-
-void DSNode::assertOK() const {
-  assert((Ty != Type::VoidTy ||
-          Ty == Type::VoidTy && (Size == 0 ||
-                                 (NodeType & DSNode::Array))) &&
-         "Node not OK!");
-
-  assert(ParentGraph && "Node has no parent?");
-  const DSGraph::ScalarMapTy &SM = ParentGraph->getScalarMap();
-  for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
-    assert(SM.find(Globals[i]) != SM.end());
-    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.setNode(To);
-  ForwardNH.setOffset(Offset);
-  NodeType = DEAD;
-  Size = 0;
-  Ty = Type::VoidTy;
-}
-
-// addGlobal - Add an entry for a global value to the Globals list.  This also
-// marks the node with the 'G' flag if it does not already have it.
-//
-void DSNode::addGlobal(GlobalValue *GV) {
-  // Keep the list sorted.
-  std::vector<GlobalValue*>::iterator I =
-    std::lower_bound(Globals.begin(), Globals.end(), GV);
-
-  if (I == Globals.end() || *I != GV) {
-    //assert(GV->getType()->getElementType() == Ty);
-    Globals.insert(I, GV);
-    NodeType |= GlobalNode;
-  }
-}
-
-/// 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;
-
-  // Create the node we are going to forward to...
-  DSNode *DestNode = new DSNode(0, ParentGraph);
-  DestNode->NodeType = NodeType|DSNode::Array;
-  DestNode->Ty = Type::VoidTy;
-  DestNode->Size = 1;
-  DestNode->Globals.swap(Globals);
-
-  // Start forwarding to the destination node...
-  forwardNode(DestNode, 0);
-  
-  if (Links.size()) {
-    DestNode->Links.push_back(Links[0]);
-    DSNodeHandle NH(DestNode);
-
-    // 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::VoidTy && isArray();
-}
-
-
-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;
-  public:
-    TypeElementWalker(const Type *T) {
-      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->getElementTypes().size()) {
-            const StructLayout *SL = TD.getStructLayout(ST);
-            SS.Offset += SL->MemberOffsets[SS.Idx]-SL->MemberOffsets[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 += TD.getTypeSize(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->getElementTypes().empty()) {
-            assert(SS.Idx == 0);
-            PopStackAndAdvance();
-          } else {
-            // Step into the structure...
-            assert(SS.Idx < ST->getElementTypes().size());
-            const StructLayout *SL = TD.getStructLayout(ST);
-            Stack.push_back(StackState(ST->getElementTypes()[SS.Idx],
-                                       SS.Offset+SL->MemberOffsets[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*
-                                       TD.getTypeSize(AT->getElementType())));
-          }
-        }
-      }
-    }
-  };
-}
-
-/// 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.
-///
-static bool ElementTypesAreCompatible(const Type *T1, const Type *T2) {
-  TypeElementWalker T1W(T1), T2W(T2);
-  
-  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->isLosslesslyConvertibleTo(T2))
-      return false;
-    
-    T1W.StepToNextType();
-    T2W.StepToNextType();
-  }
-  
-  return 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) {
-  // 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::VoidTy && !isArray()) ||
-          (Size == 0 && !Ty->isSized() && !isArray()) ||
-          (Size == 1 && Ty == Type::VoidTy && isArray()) ||
-          (Size == 0 && !Ty->isSized() && !isArray()) ||
-          (TD.getTypeSize(Ty) == Size)) &&
-         "Size member of DSNode doesn't match the type structure!");
-  assert(NewTy != Type::VoidTy && "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() ? TD.getTypeSize(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::VoidTy) {
-    // If this is the first type that this node has seen, just accept it without
-    // question....
-    assert(Offset == 0 && "Cannot have an offset into a void node!");
-    assert(!isArray() && "This shouldn't happen!");
-    Ty = NewTy;
-    NodeType &= ~Array;
-    if (WillBeArray) NodeType |= Array;
-    Size = NewTySize;
-
-    // Calculate the number of outgoing links from this node.
-    Links.resize((Size+DS::PointerSize-1) >> DS::PointerShift);
-    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 (isArray()) {
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-    }
-
-    if (Offset) {  // We could handle this case, but we don't for now...
-      std::cerr << "UNIMP: Trying to merge a growth type into "
-                << "offset != 0: Collapsing!\n";
-      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 &= ~Array;
-    if (WillBeArray) NodeType |= Array;
-    Size = NewTySize;
-
-    // Must grow links to be the appropriate size...
-    Links.resize((Size+DS::PointerSize-1) >> DS::PointerShift);
-
-    // 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.getTypeSize(SubType) && "Offset out of range!");
-
-    switch (SubType->getPrimitiveID()) {
-    case Type::StructTyID: {
-      const StructType *STy = cast<StructType>(SubType);
-      const StructLayout &SL = *TD.getStructLayout(STy);
-
-      unsigned i = 0, e = SL.MemberOffsets.size();
-      for (; i+1 < e && SL.MemberOffsets[i+1] <= Offset-O; ++i)
-        /* empty */;
-
-      // The offset we are looking for must be in the i'th element...
-      SubType = STy->getElementTypes()[i];
-      O += SL.MemberOffsets[i];
-      break;
-    }
-    case Type::ArrayTyID: {
-      SubType = cast<ArrayType>(SubType)->getElementType();
-      unsigned ElSize = TD.getTypeSize(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;
-
-  unsigned SubTypeSize = SubType->isSized() ? TD.getTypeSize(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))
-    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->getPrimitiveID()) {
-    case Type::StructTyID: {
-      const StructType *STy = cast<StructType>(SubType);
-      const StructLayout &SL = *TD.getStructLayout(STy);
-      if (SL.MemberOffsets.size() > 1)
-        NextPadSize = SL.MemberOffsets[1];
-      else
-        NextPadSize = SubTypeSize;
-      NextSubType = STy->getElementTypes()[0];
-      NextSubTypeSize = TD.getTypeSize(NextSubType);
-      break;
-    }
-    case Type::ArrayTyID:
-      NextSubType = cast<ArrayType>(SubType)->getElementType();
-      NextSubTypeSize = TD.getTypeSize(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->isLosslesslyConvertibleTo(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;
-  }
-
-  Module *M = 0;
-  if (getParentGraph()->getReturnNodes().size())
-    M = getParentGraph()->getReturnNodes().begin()->first->getParent();
-  DEBUG(std::cerr << "MergeTypeInfo Folding OrigTy: ";
-        WriteTypeSymbolic(std::cerr, Ty, M) << "\n due to:";
-        WriteTypeSymbolic(std::cerr, NewTy, M) << " @ " << Offset << "!\n"
-                  << "SubType: ";
-        WriteTypeSymbolic(std::cerr, SubType, M) << "\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.getNode() == 0) return;       // Nothing to do
-
-  DSNodeHandle &ExistingEdge = getLink(Offset);
-  if (ExistingEdge.getNode()) {
-    // Merge the two nodes...
-    ExistingEdge.mergeWith(NH);
-  } else {                             // No merging to perform...
-    setLink(Offset, NH);               // Just force a link in there...
-  }
-}
-
-
-// MergeSortedVectors - Efficiently merge a vector into another vector where
-// duplicates are not allowed and both are sorted.  This assumes that 'T's are
-// efficiently copyable and have sane comparison semantics.
-//
-static void MergeSortedVectors(std::vector<GlobalValue*> &Dest,
-                               const std::vector<GlobalValue*> &Src) {
-  // By far, the most common cases will be the simple ones.  In these cases,
-  // avoid having to allocate a temporary vector...
-  //
-  if (Src.empty()) {             // Nothing to merge in...
-    return;
-  } else if (Dest.empty()) {     // Just copy the result in...
-    Dest = Src;
-  } else if (Src.size() == 1) {  // Insert a single element...
-    const GlobalValue *V = Src[0];
-    std::vector<GlobalValue*>::iterator I =
-      std::lower_bound(Dest.begin(), Dest.end(), V);
-    if (I == Dest.end() || *I != Src[0])  // If not already contained...
-      Dest.insert(I, Src[0]);
-  } else if (Dest.size() == 1) {
-    GlobalValue *Tmp = Dest[0];           // Save value in temporary...
-    Dest = Src;                           // Copy over list...
-    std::vector<GlobalValue*>::iterator I =
-      std::lower_bound(Dest.begin(), Dest.end(), Tmp);
-    if (I == Dest.end() || *I != Tmp)     // If not already contained...
-      Dest.insert(I, Tmp);
-
-  } else {
-    // Make a copy to the side of Dest...
-    std::vector<GlobalValue*> Old(Dest);
-    
-    // Make space for all of the type entries now...
-    Dest.resize(Dest.size()+Src.size());
-    
-    // Merge the two sorted ranges together... into Dest.
-    std::merge(Old.begin(), Old.end(), Src.begin(), Src.end(), Dest.begin());
-    
-    // Now erase any duplicate entries that may have accumulated into the 
-    // vectors (because they were in both of the input sets)
-    Dest.erase(std::unique(Dest.begin(), Dest.end()), Dest.end());
-  }
-}
-
-
-// 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.");
-
-  // 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 (NSize < CurNodeH.getNode()->getSize()) {
-      if (NH.getNode()->isArray())
-        NH.getNode()->foldNodeCompletely();
-    } else if (CurNodeH.getNode()->isArray()) {
-      NH.getNode()->foldNodeCompletely();
-    }
-  }
-
-  // Merge the type entries of the two nodes together...    
-  if (NH.getNode()->Ty != Type::VoidTy)
-    CurNodeH.getNode()->mergeTypeInfo(NH.getNode()->Ty, NOffset);
-  assert(!CurNodeH.getNode()->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?");
-    NOffset = NH.getOffset();
-    NSize = NH.getNode()->getSize();
-    assert(NOffset == 0 && NSize == 1);
-  }
-
-  DSNode *N = NH.getNode();
-  if (CurNodeH.getNode() == N || N == 0) return;
-  assert(!CurNodeH.getNode()->isDeadNode());
-
-  // Merge the NodeType information...
-  CurNodeH.getNode()->NodeType |= N->NodeType;
-
-  // Start forwarding to the new node!
-  N->forwardNode(CurNodeH.getNode(), NOffset);
-  assert(!CurNodeH.getNode()->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 << DS::PointerShift);
-    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 << DS::PointerShift)+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()) {
-    MergeSortedVectors(CurNodeH.getNode()->Globals, N->Globals);
-
-    // Delete the globals from the old node...
-    std::vector<GlobalValue*>().swap(N->Globals);
-  }
-}
-
-
-// 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, nothing happens).
-//
-void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
-  DSNode *N = NH.getNode();
-  if (N == 0 || (N == this && NH.getOffset() == Offset))
-    return;  // Noop
-
-  assert(!N->isDeadNode() && !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.
-    DEBUG(std::cerr << "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);
-  DSNode::MergeNodes(CurNodeH, NHCopy);
-}
-
-//===----------------------------------------------------------------------===//
-// DSCallSite Implementation
-//===----------------------------------------------------------------------===//
-
-// Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
-Function &DSCallSite::getCaller() const {
-  return *Inst->getParent()->getParent();
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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 getReturnNodes().begin()->first->getName();
-  default:
-    std::string Return;
-    for (DSGraph::ReturnNodesTy::const_iterator I = getReturnNodes().begin();
-         I != getReturnNodes().end(); ++I)
-      Return += I->first->getName() + " ";
-    Return.erase(Return.end()-1, Return.end());   // Remove last space character
-    return Return;
-  }
-}
-
-
-DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0) {
-  PrintAuxCalls = false;
-  NodeMapTy NodeMap;
-  cloneInto(G, ScalarMap, ReturnNodes, NodeMap);
-  InlinedGlobals.clear();               // clear set of "up-to-date" globals
-}
-
-DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap)
-  : GlobalsGraph(0) {
-  PrintAuxCalls = false;
-  cloneInto(G, ScalarMap, ReturnNodes, NodeMap);
-  InlinedGlobals.clear();               // clear set of "up-to-date" globals
-}
-
-DSGraph::~DSGraph() {
-  FunctionCalls.clear();
-  AuxFunctionCalls.clear();
-  InlinedGlobals.clear();
-  ScalarMap.clear();
-  ReturnNodes.clear();
-
-  // Drop all intra-node references, so that assertions don't fail...
-  std::for_each(Nodes.begin(), Nodes.end(),
-                std::mem_fun(&DSNode::dropAllReferences));
-
-  // Delete all of the nodes themselves...
-  std::for_each(Nodes.begin(), Nodes.end(), deleter<DSNode>);
-}
-
-// dump - Allow inspection of graph in a debugger.
-void DSGraph::dump() const { print(std::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) {
-    DSNodeHandle &H = OldNodeMap[Links[i].getNode()];
-    Links[i].setNode(H.getNode());
-    Links[i].setOffset(Links[i].getOffset()+H.getOffset());
-  }
-}
-
-
-/// cloneReachableNodes - Clone all reachable nodes from *Node into the
-/// current graph.  This is a recursive function.  The map OldNodeMap is a
-/// map from the original nodes to their clones.
-/// 
-void DSGraph::cloneReachableNodes(const DSNode*  Node,
-                                  unsigned BitsToClear,
-                                  NodeMapTy& OldNodeMap,
-                                  NodeMapTy& CompletedNodeMap) {
-  if (CompletedNodeMap.find(Node) != CompletedNodeMap.end())
-    return;
-
-  DSNodeHandle& NH = OldNodeMap[Node];
-  if (NH.getNode() != NULL)
-    return;
-
-  // else Node has not yet been cloned: clone it and clear the specified bits
-  NH = new DSNode(*Node, this);          // enters in OldNodeMap
-  NH.getNode()->maskNodeTypes(~BitsToClear);
-
-  // now recursively clone nodes pointed to by this node
-  for (unsigned i = 0, e = Node->getNumLinks(); i != e; ++i) {
-    const DSNodeHandle &Link = Node->getLink(i << DS::PointerShift);
-    if (const DSNode* nextNode = Link.getNode())
-      cloneReachableNodes(nextNode, BitsToClear, OldNodeMap, CompletedNodeMap);
-  }
-}
-
-void DSGraph::cloneReachableSubgraph(const DSGraph& G,
-                                     const hash_set<const DSNode*>& RootNodes,
-                                     NodeMapTy& OldNodeMap,
-                                     NodeMapTy& CompletedNodeMap,
-                                     unsigned CloneFlags) {
-  if (RootNodes.empty())
-    return;
-
-  assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
-  assert(&G != this && "Cannot clone graph into itself!");
-  assert((*RootNodes.begin())->getParentGraph() == &G &&
-         "Root nodes do not belong to this graph!");
-
-  // Remove alloca or mod/ref bits as specified...
-  unsigned BitsToClear = ((CloneFlags & StripAllocaBit)? DSNode::AllocaNode : 0)
-    | ((CloneFlags & StripModRefBits)? (DSNode::Modified | DSNode::Read) : 0)
-    | ((CloneFlags & StripIncompleteBit)? DSNode::Incomplete : 0);
-  BitsToClear |= DSNode::DEAD;  // Clear dead flag...
-
-  // Clone all nodes reachable from each root node, using a recursive helper
-  for (hash_set<const DSNode*>::const_iterator I = RootNodes.begin(),
-         E = RootNodes.end(); I != E; ++I)
-    cloneReachableNodes(*I, BitsToClear, OldNodeMap, CompletedNodeMap);
-
-  // Merge the map entries in OldNodeMap and CompletedNodeMap to remap links
-  NodeMapTy MergedMap(OldNodeMap);
-  MergedMap.insert(CompletedNodeMap.begin(), CompletedNodeMap.end());
-
-  // Rewrite the links in the newly created nodes (the nodes in OldNodeMap)
-  // to point into the current graph.  MergedMap gives the full mapping.
-  for (NodeMapTy::iterator I=OldNodeMap.begin(), E=OldNodeMap.end(); I!= E; ++I)
-    I->second.getNode()->remapLinks(MergedMap);
-
-  // Now merge cloned global nodes with their copies in the current graph
-  // Just look through OldNodeMap to find such nodes!
-  for (NodeMapTy::iterator I=OldNodeMap.begin(), E=OldNodeMap.end(); I!= E; ++I)
-    if (I->first->isGlobalNode()) {
-      DSNodeHandle &GClone = I->second;
-      assert(GClone.getNode() != NULL && "NULL node in OldNodeMap?");
-      const std::vector<GlobalValue*> &Globals = I->first->getGlobals();
-      for (unsigned gi = 0, ge = Globals.size(); gi != ge; ++gi) {
-        DSNodeHandle &GH = ScalarMap[Globals[gi]];
-        GH.mergeWith(GClone);
-      }
-    }
-}
-
-
-/// updateFromGlobalGraph - This function rematerializes global nodes and
-/// nodes reachable from them from the globals graph into the current graph.
-/// It invokes cloneReachableSubgraph, using the globals in the current graph
-/// as the roots.  It also uses the vector InlinedGlobals to avoid cloning and
-/// merging globals that are already up-to-date in the current graph.  In
-/// practice, in the TD pass, this is likely to be a large fraction of the
-/// live global nodes in each function (since most live nodes are likely to
-/// have been brought up-to-date in at _some_ caller or callee).
-/// 
-void DSGraph::updateFromGlobalGraph() {
-
-  // Use a map to keep track of the mapping between nodes in the globals graph
-  // and this graph for up-to-date global nodes, which do not need to be cloned.
-  NodeMapTy CompletedMap;
-
-  // Put the live, non-up-to-date global nodes into a set and the up-to-date
-  // ones in the map above, mapping node in GlobalsGraph to the up-to-date node.
-  hash_set<const DSNode*> GlobalNodeSet;
-  for (ScalarMapTy::const_iterator I = getScalarMap().begin(),
-         E = getScalarMap().end(); I != E; ++I)
-    if (GlobalValue* GV = dyn_cast<GlobalValue>(I->first)) {
-      DSNode* GNode = I->second.getNode();
-      assert(GNode && "No node for live global in current Graph?");
-      if (const DSNode* GGNode = GlobalsGraph->ScalarMap[GV].getNode())
-        if (InlinedGlobals.count(GV) == 0) // GNode is not up-to-date
-          GlobalNodeSet.insert(GGNode);
-        else {                                       // GNode is up-to-date 
-          CompletedMap[GGNode] = I->second;
-          assert(GGNode->getNumLinks() == GNode->getNumLinks() &&
-                 "Links dont match in a node that is supposed to be up-to-date?"
-                 "\nremapLinks() will not work if the links don't match!");
-        }
-    }
-
-  // Clone the subgraph reachable from the vector of nodes in GlobalNodes
-  // and merge the cloned global nodes with the corresponding ones, if any.
-  NodeMapTy OldNodeMap;
-  cloneReachableSubgraph(*GlobalsGraph, GlobalNodeSet, OldNodeMap,CompletedMap);
-
-  // Merging global nodes leaves behind unused nodes: get rid of them now.
-  OldNodeMap.clear();      // remove references before dead node cleanup 
-  CompletedMap.clear();    // remove references before dead node cleanup 
-  removeTriviallyDeadNodes();
-}
-
-/// cloneInto - Clone the specified DSGraph into the current graph.  The
-/// translated ScalarMap for the old function is filled into the OldValMap
-/// member, and the translated ReturnNodes map is returned into ReturnNodes.
-///
-/// The CloneFlags member controls various aspects of the cloning process.
-///
-void DSGraph::cloneInto(const DSGraph &G, ScalarMapTy &OldValMap,
-                        ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap,
-                        unsigned CloneFlags) {
-  assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
-  assert(&G != this && "Cannot clone graph into itself!");
-
-  unsigned FN = Nodes.size();           // First new node...
-
-  // Duplicate all of the nodes, populating the node map...
-  Nodes.reserve(FN+G.Nodes.size());
-
-  // Remove alloca or mod/ref bits as specified...
-  unsigned BitsToClear = ((CloneFlags & StripAllocaBit)? DSNode::AllocaNode : 0)
-    | ((CloneFlags & StripModRefBits)? (DSNode::Modified | DSNode::Read) : 0)
-    | ((CloneFlags & StripIncompleteBit)? DSNode::Incomplete : 0);
-  BitsToClear |= DSNode::DEAD;  // Clear dead flag...
-  for (unsigned i = 0, e = G.Nodes.size(); i != e; ++i) {
-    DSNode *Old = G.Nodes[i];
-    DSNode *New = new DSNode(*Old, this);
-    New->maskNodeTypes(~BitsToClear);
-    OldNodeMap[Old] = New;
-  }
-
-#ifndef NDEBUG
-  Timer::addPeakMemoryMeasurement();
-#endif
-
-  // Rewrite the links in the new nodes to point into the current graph now.
-  for (unsigned i = FN, e = Nodes.size(); i != e; ++i)
-    Nodes[i]->remapLinks(OldNodeMap);
-
-  // Copy the scalar map... merging all of the global nodes...
-  for (ScalarMapTy::const_iterator I = G.ScalarMap.begin(),
-         E = G.ScalarMap.end(); I != E; ++I) {
-    DSNodeHandle &MappedNode = OldNodeMap[I->second.getNode()];
-    DSNodeHandle &H = OldValMap[I->first];
-    H.mergeWith(DSNodeHandle(MappedNode.getNode(),
-                             I->second.getOffset()+MappedNode.getOffset()));
-
-    // If this is a global, add the global to this fn or merge if already exists
-    if (GlobalValue* GV = dyn_cast<GlobalValue>(I->first)) {
-      ScalarMap[GV].mergeWith(H);
-      InlinedGlobals.insert(GV);
-    }
-  }
-
-  if (!(CloneFlags & DontCloneCallNodes)) {
-    // Copy the function calls list...
-    unsigned FC = FunctionCalls.size();  // FirstCall
-    FunctionCalls.reserve(FC+G.FunctionCalls.size());
-    for (unsigned i = 0, ei = G.FunctionCalls.size(); i != ei; ++i)
-      FunctionCalls.push_back(DSCallSite(G.FunctionCalls[i], OldNodeMap));
-  }
-
-  if (!(CloneFlags & DontCloneAuxCallNodes)) {
-    // Copy the auxillary function calls list...
-    unsigned FC = AuxFunctionCalls.size();  // FirstCall
-    AuxFunctionCalls.reserve(FC+G.AuxFunctionCalls.size());
-    for (unsigned i = 0, ei = G.AuxFunctionCalls.size(); i != ei; ++i)
-      AuxFunctionCalls.push_back(DSCallSite(G.AuxFunctionCalls[i], OldNodeMap));
-  }
-
-  // Map the return node pointers over...
-  for (ReturnNodesTy::const_iterator I = G.getReturnNodes().begin(),
-         E = G.getReturnNodes().end(); I != E; ++I) {
-    const DSNodeHandle &Ret = I->second;
-    DSNodeHandle &MappedRet = OldNodeMap[Ret.getNode()];
-    OldReturnNodes.insert(std::make_pair(I->first,
-                          DSNodeHandle(MappedRet.getNode(),
-                                       MappedRet.getOffset()+Ret.getOffset())));
-  }
-}
-
-/// 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, Function &F,
-                           const DSGraph &Graph, unsigned CloneFlags) {
-  ScalarMapTy OldValMap, *ScalarMap;
-  DSNodeHandle RetVal;
-
-  // If this is not a recursive call, clone the graph into this graph...
-  if (&Graph != this) {
-    // 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.
-    NodeMapTy OldNodeMap;
-    
-    // The clone call may invalidate any of the vectors in the data
-    // structure graph.  Strip locals and don't copy the list of callers
-    ReturnNodesTy OldRetNodes;
-    cloneInto(Graph, OldValMap, OldRetNodes, OldNodeMap, CloneFlags);
-
-    // We need to map the arguments for the function to the cloned nodes old
-    // argument values.  Do this now.
-    RetVal = OldRetNodes[&F];
-    ScalarMap = &OldValMap;
-  } else {
-    RetVal = getReturnNodeFor(F);
-    ScalarMap = &getScalarMap();
-  }
-
-  // Merge the return value with the return value of the context...
-  RetVal.mergeWith(CS.getRetVal());
-
-  // Resolve all of the function arguments...
-  Function::aiterator AI = F.abegin();
-
-  for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i, ++AI) {
-    // Advance the argument iterator to the first pointer argument...
-    while (AI != F.aend() && !isPointerType(AI->getType())) {
-      ++AI;
-#ifndef NDEBUG
-      if (AI == F.aend())
-        std::cerr << "Bad call to Function: " << F.getName() << "\n";
-#endif
-    }
-    if (AI == F.aend()) break;
-    
-    // Add the link from the argument scalar to the provided value
-    assert(ScalarMap->count(AI) && "Argument not in scalar map?");
-    DSNodeHandle &NH = (*ScalarMap)[AI];
-    assert(NH.getNode() && "Pointer argument without scalarmap entry?");
-    NH.mergeWith(CS.getPtrArg(i));
-  }
-}
-
-/// getCallSiteForArguments - Get the arguments and return value bindings for
-/// the specified function in the current graph.
-///
-DSCallSite DSGraph::getCallSiteForArguments(Function &F) const {
-  std::vector<DSNodeHandle> Args;
-
-  for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
-    if (isPointerType(I->getType()))
-      Args.push_back(getScalarMap().find(I)->second);
-
-  return DSCallSite(*(CallInst*)0, getReturnNodeFor(F), &F, 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->isIncomplete()) return;
-
-  // Actually mark the node
-  N->setIncompleteMarker();
-
-  // Recusively process children...
-  for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
-    if (DSNode *DSN = N->getLink(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) {
-      Function &F = *FI->first;
-      if (F.getName() != "main")
-        for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
-          if (isPointerType(I->getType()) &&
-              ScalarMap.find(I) != ScalarMap.end())
-            markIncompleteNode(ScalarMap[I].getNode());
-    }
-
-  // Mark stuff passed into functions calls as being incomplete...
-  if (!shouldPrintAuxCalls())
-    for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i)
-      markIncomplete(FunctionCalls[i]);
-  else
-    for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i)
-      markIncomplete(AuxFunctionCalls[i]);
-    
-
-  // Mark all global nodes as incomplete...
-  if ((Flags & DSGraph::IgnoreGlobals) == 0)
-    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-      if (Nodes[i]->isGlobalNode() && Nodes[i]->getNumLinks())
-        markIncompleteNode(Nodes[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() & ~DSNode::Incomplete) == 0 &&
-          N->getType() == Type::VoidTy && !N->isNodeCompletelyFolded())
-        Edge.setNode(0);  // Kill the edge!
-}
-
-static inline bool nodeContainsExternalFunction(const DSNode *N) {
-  const std::vector<GlobalValue*> &Globals = N->getGlobals();
-  for (unsigned i = 0, e = Globals.size(); i != e; ++i)
-    if (Globals[i]->isExternal())
-      return true;
-  return false;
-}
-
-static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
-
-  // Remove trivially identical function calls
-  unsigned NumFns = Calls.size();
-  std::sort(Calls.begin(), Calls.end());  // Sort by callee as primary key!
-
-  // Scan the call list cleaning it up as necessary...
-  DSNode   *LastCalleeNode = 0;
-  Function *LastCalleeFunc = 0;
-  unsigned NumDuplicateCalls = 0;
-  bool LastCalleeContainsExternalFunction = false;
-  for (unsigned i = 0; i != Calls.size(); ++i) {
-    DSCallSite &CS = Calls[i];
-
-    // If the Callee is a useless edge, this must be an unreachable call site,
-    // eliminate it.
-    if (CS.isIndirectCall() && CS.getCalleeNode()->getNumReferrers() == 1 &&
-        CS.getCalleeNode()->getNodeFlags() == 0) {  // No useful info?
-      std::cerr << "WARNING: Useless call site found??\n";
-      CS.swap(Calls.back());
-      Calls.pop_back();
-      --i;
-    } else {
-      // 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 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 =
-              nodeContainsExternalFunction(LastCalleeNode);
-          else
-            LastCalleeContainsExternalFunction = LastCalleeFunc->isExternal();
-        }
-        
-#if 1
-        if (LastCalleeContainsExternalFunction ||
-            // This should be more than enough context sensitivity!
-            // FIXME: Evaluate how many times this is tripped!
-            NumDuplicateCalls > 20) {
-          DSCallSite &OCS = Calls[i-1];
-          OCS.mergeWith(CS);
-          
-          // The node will now be eliminated as a duplicate!
-          if (CS.getNumPtrArgs() < OCS.getNumPtrArgs())
-            CS = OCS;
-          else if (CS.getNumPtrArgs() > OCS.getNumPtrArgs())
-            OCS = CS;
-        }
-#endif
-      } else {
-        if (CS.isDirectCall()) {
-          LastCalleeFunc = CS.getCalleeFunc();
-          LastCalleeNode = 0;
-        } else {
-          LastCalleeNode = CS.getCalleeNode();
-          LastCalleeFunc = 0;
-        }
-        NumDuplicateCalls = 0;
-      }
-    }
-  }
-
-  Calls.erase(std::unique(Calls.begin(), Calls.end()),
-              Calls.end());
-
-  // Track the number of call nodes merged away...
-  NumCallNodesMerged += NumFns-Calls.size();
-
-  DEBUG(if (NumFns != Calls.size())
-          std::cerr << "Merged " << (NumFns-Calls.size()) << " call nodes.\n";);
-}
-
-
-// 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() {
-  removeIdenticalCalls(FunctionCalls);
-  removeIdenticalCalls(AuxFunctionCalls);
-
-  bool isGlobalsGraph = !GlobalsGraph;
-
-  for (unsigned i = 0; i != Nodes.size(); ++i) {
-    DSNode *Node = Nodes[i];
-
-    // 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->isGlobalNode() && isGlobalsGraph)
-      continue;
-
-    if (Node->isComplete() && !Node->isModified() && !Node->isRead()) {
-      // 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->getGlobals().size()) {
-        const std::vector<GlobalValue*> &Globals = Node->getGlobals();
-
-        // Loop through and make sure all of the globals are referring directly
-        // to the node...
-        for (unsigned j = 0, e = Globals.size(); j != e; ++j) {
-          DSNode *N = ScalarMap.find(Globals[j])->second.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() == Globals.size()) {
-          for (unsigned j = 0, e = Globals.size(); j != e; ++j)
-            ScalarMap.erase(Globals[j]);
-          Node->makeNodeDead();
-        }
-      }
-
-#ifdef SANER_CODE_FOR_CHECKING_IF_ALL_REFERRERS_ARE_FROM_SCALARMAP
-      //
-      // *** It seems to me that we should be able to simply check if 
-      // *** there are fewer or equal #referrers as #globals and make
-      // *** sure that all those referrers are in the scalar map?
-      // 
-      if (Node->getNumReferrers() <= Node->getGlobals().size()) {
-        const std::vector<GlobalValue*> &Globals = Node->getGlobals();
-
-#ifndef NDEBUG
-        // Loop through and make sure all of the globals are referring directly
-        // to the node...
-        for (unsigned j = 0, e = Globals.size(); j != e; ++j) {
-          DSNode *N = ScalarMap.find(Globals[j])->second.getNode();
-          assert(N == Node && "ScalarMap doesn't match globals list!");
-        }
-#endif
-
-        // Make sure NumReferrers still agrees.  The node is truly dead.
-        assert(Node->getNumReferrers() == Globals.size());
-        for (unsigned j = 0, e = Globals.size(); j != e; ++j)
-          ScalarMap.erase(Globals[j]);
-        Node->makeNodeDead();
-      }
-#endif
-    }
-
-    if (Node->getNodeFlags() == 0 && Node->hasNoReferrers()) {
-      // This node is dead!
-      delete Node;                        // Free memory...
-      Nodes[i--] = Nodes.back();
-      Nodes.pop_back();                   // Remove from node list...
-    }
-  }
-}
-
-
-/// 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<DSNode*> &ReachableNodes) {
-  if (this == 0) return;
-  assert(getForwardNode() == 0 && "Cannot mark a forwarded node!");
-  if (ReachableNodes.count(this)) return;          // Already marked reachable
-  ReachableNodes.insert(this);                     // Is reachable now
-
-  for (unsigned i = 0, e = getSize(); i < e; i += DS::PointerSize)
-    getLink(i).getNode()->markReachableNodes(ReachableNodes);
-}
-
-void DSCallSite::markReachableNodes(hash_set<DSNode*> &Nodes) {
-  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<DSNode*> &Alive,
-                               hash_set<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->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 (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
-    if (CanReachAliveNodes(N->getLink(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(DSCallSite &CS, hash_set<DSNode*> &Alive,
-                                  hash_set<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(); GlobalsGraph->AssertGraphOK());
-
-  // Reduce the amount of work we have to do... remove dummy nodes left over by
-  // merging...
-  removeTriviallyDeadNodes();
-
-  // FIXME: Merge nontrivially identical call nodes...
-
-  // Alive - a set that holds all nodes found to be reachable/alive.
-  hash_set<DSNode*> Alive;
-  std::vector<std::pair<Value*, DSNode*> > GlobalNodes;
-
-  // Mark all nodes reachable by (non-global) scalar nodes as alive...
-  for (ScalarMapTy::iterator I = ScalarMap.begin(), E = ScalarMap.end(); I !=E;)
-    if (isa<GlobalValue>(I->first)) {             // Keep track of global nodes
-      assert(I->second.getNode() && "Null global node?");
-      assert(I->second.getNode()->isGlobalNode() && "Should be a global node!");
-      GlobalNodes.push_back(std::make_pair(I->first, I->second.getNode()));
-      ++I;
-    } else {
-      // Check to see if this is a worthless node generated for non-pointer
-      // values, such as integers.  Consider an addition of long types: A+B.
-      // Assuming we can track all uses of the value in this context, and it is
-      // NOT used as a pointer, we can delete the node.  We will be able to
-      // detect this situation if the node pointed to ONLY has Unknown bit set
-      // in the node.  In this case, the node is not incomplete, does not point
-      // to any other nodes (no mod/ref bits set), and is therefore
-      // uninteresting for data structure analysis.  If we run across one of
-      // these, prune the scalar pointing to it.
-      //
-      DSNode *N = I->second.getNode();
-      if (N->getNodeFlags() == DSNode::UnknownNode && !isa<Argument>(I->first)){
-        ScalarMap.erase(I++);
-      } else {
-        I->second.getNode()->markReachableNodes(Alive);
-        ++I;
-      }
-    }
-
-  // The return value is 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 (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i)
-    FunctionCalls[i].markReachableNodes(Alive);
-
-  // Copy and merge all information about globals to the GlobalsGraph
-  // if this is not a final pass (where unreachable globals are removed)
-  NodeMapTy GlobalNodeMap;
-  hash_set<const DSNode*> GlobalNodeSet;
-
-  for (std::vector<std::pair<Value*, DSNode*> >::const_iterator
-         I = GlobalNodes.begin(), E = GlobalNodes.end(); I != E; ++I)
-    GlobalNodeSet.insert(I->second);    // put global nodes into a set
-
-  // 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<DSNode*> Visited;
-  std::vector<unsigned char> AuxFCallsAlive(AuxFunctionCalls.size());
-  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 (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i)
-      if (!AuxFCallsAlive[i] &&
-          (AuxFunctionCalls[i].isIndirectCall()
-           || CallSiteUsesAliveArgs(AuxFunctionCalls[i], Alive, Visited,
-                                  Flags & DSGraph::RemoveUnreachableGlobals))) {
-        AuxFunctionCalls[i].markReachableNodes(Alive);
-        AuxFCallsAlive[i] = true;
-        Iterate = true;
-      }
-  } while (Iterate);
-
-  // Move dead aux function calls to the end of the list
-  unsigned CurIdx = 0;
-  for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i)
-    if (AuxFCallsAlive[i])
-      AuxFunctionCalls[CurIdx++].swap(AuxFunctionCalls[i]);
-
-  // Copy and merge all global nodes and dead aux call nodes into the
-  // GlobalsGraph, and all nodes reachable from those nodes
-  // 
-  if (!(Flags & DSGraph::RemoveUnreachableGlobals)) {
-
-    // First, add the dead aux call nodes to the set of root nodes for cloning
-    // -- return value at this call site, if any
-    // -- actual arguments passed at this call site
-    // -- callee node at this call site, if this is an indirect call
-    for (unsigned i = CurIdx, e = AuxFunctionCalls.size(); i != e; ++i) {
-      if (const DSNode* RetNode = AuxFunctionCalls[i].getRetVal().getNode())
-        GlobalNodeSet.insert(RetNode);
-      for (unsigned j=0, N=AuxFunctionCalls[i].getNumPtrArgs(); j < N; ++j)
-        if (const DSNode* ArgTarget=AuxFunctionCalls[i].getPtrArg(j).getNode())
-          GlobalNodeSet.insert(ArgTarget);
-      if (AuxFunctionCalls[i].isIndirectCall())
-        GlobalNodeSet.insert(AuxFunctionCalls[i].getCalleeNode());
-    }
-    
-    // There are no "pre-completed" nodes so use any empty map for those.
-    // 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.
-    // 
-    NodeMapTy CompletedMap;
-    GlobalsGraph->cloneReachableSubgraph(*this, GlobalNodeSet,
-                                         GlobalNodeMap, CompletedMap,
-                                         (DSGraph::StripAllocaBit |
-                                          DSGraph::StripIncompleteBit));
-  }
-
-  // Remove all dead aux function calls...
-  if (!(Flags & DSGraph::RemoveUnreachableGlobals)) {
-    assert(GlobalsGraph && "No globals graph available??");
-
-    // Copy the unreachable call nodes to the globals graph, updating
-    // their target pointers using the GlobalNodeMap
-    for (unsigned i = CurIdx, e = AuxFunctionCalls.size(); i != e; ++i)
-      GlobalsGraph->AuxFunctionCalls.push_back(DSCallSite(AuxFunctionCalls[i],
-                                                          GlobalNodeMap));
-  }
-  // Crop all the useless ones out...
-  AuxFunctionCalls.erase(AuxFunctionCalls.begin()+CurIdx,
-                         AuxFunctionCalls.end());
-
-  // We are finally done with the GlobalNodeMap so we can clear it and
-  // then get rid of unused nodes in the GlobalsGraph produced by merging.
-  GlobalNodeMap.clear();
-  GlobalsGraph->removeTriviallyDeadNodes();
-
-  // 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 (unsigned i = 0; i != Nodes.size(); ++i)
-    if (!Alive.count(Nodes[i])) {
-      DSNode *N = Nodes[i];
-      Nodes[i--] = Nodes.back();            // move node to end of vector
-      Nodes.pop_back();                     // Erase node from alive list.
-      DeadNodes.push_back(N);
-      N->dropAllReferences();
-    } else {
-      assert(Nodes[i]->getForwardNode() == 0 && "Alive forwarded node?");
-    }
-
-  // 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) {
-    assert(((Flags & DSGraph::RemoveUnreachableGlobals) ||
-            !Alive.count(GlobalNodes[i].second)) && "huh? non-dead global");
-    if (!Alive.count(GlobalNodes[i].second))
-      ScalarMap.erase(GlobalNodes[i].first);
-  }
-
-  // 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::AssertGraphOK() const {
-  for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-    Nodes[i]->assertOK();
-
-  for (ScalarMapTy::const_iterator I = ScalarMap.begin(),
-         E = ScalarMap.end(); I != E; ++I) {
-    assert(I->second.getNode() && "Null node in scalarmap!");
-    AssertNodeInGraph(I->second.getNode());
-    if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
-      assert(I->second.getNode()->isGlobalNode() &&
-             "Global points to node, but node isn't global?");
-      AssertNodeContainsGlobal(I->second.getNode(), GV);
-    }
-  }
-  AssertCallNodesInGraph();
-  AssertAuxCallNodesInGraph();
-}
-
-/// mergeInGlobalsGraph - This method is useful for clients to incorporate the
-/// globals graph into the DS, BU or TD graph for a function.  This code retains
-/// all globals, i.e., does not delete unreachable globals after they are
-/// inlined.
-///
-void DSGraph::mergeInGlobalsGraph() {
-  NodeMapTy GlobalNodeMap;
-  ScalarMapTy OldValMap;
-  ReturnNodesTy OldRetNodes;
-  cloneInto(*GlobalsGraph, OldValMap, OldRetNodes, GlobalNodeMap,
-            DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes |
-            DSGraph::DontCloneAuxCallNodes);
-  
-  // Now merge existing global nodes in the GlobalsGraph with their copies
-  for (ScalarMapTy::iterator I = ScalarMap.begin(), E = ScalarMap.end(); 
-       I != E; ++I)
-    if (isa<GlobalValue>(I->first)) {             // Found a global node
-      DSNodeHandle &GH = I->second;
-      DSNodeHandle &GGNodeH = GlobalsGraph->getScalarMap()[I->first];
-      GH.mergeWith(GlobalNodeMap[GGNodeH.getNode()]);
-    }
-  
-  // Merging leaves behind unused nodes: get rid of them now.
-  GlobalNodeMap.clear();
-  OldValMap.clear();
-  OldRetNodes.clear();
-  removeTriviallyDeadNodes();
-}
diff --git a/poolalloc/lib/DSA/DataStructureAA.cpp b/poolalloc/lib/DSA/DataStructureAA.cpp
deleted file mode 100644
index e7e963a..0000000
--- a/poolalloc/lib/DSA/DataStructureAA.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-//===- DataStructureAA.cpp - Data Structure Based Alias Analysis ----------===//
-//
-// This pass uses the top-down data structure graphs to implement a simple
-// context sensitive alias analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Module.h"
-
-namespace {
-  class DSAA : public Pass, public AliasAnalysis {
-    TDDataStructures *TD;
-  public:
-    DSAA() : TD(0) {}
-
-    //------------------------------------------------
-    // Implement the Pass API
-    //
-
-    // run - Build up the result graph, representing the pointer graph for the
-    // program.
-    //
-    bool run(Module &M) {
-      InitializeAliasAnalysis(this);
-      TD = &getAnalysis<TDDataStructures>();
-      return false;
-    }
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AliasAnalysis::getAnalysisUsage(AU);
-      AU.setPreservesAll();                    // Does not transform code...
-      AU.addRequired<TDDataStructures>();      // Uses TD Datastructures
-      AU.addRequired<AliasAnalysis>();         // Chains to another AA impl...
-    }
-
-    //------------------------------------------------
-    // Implement the AliasAnalysis API
-    //  
-
-    AliasResult alias(const Value *V1, unsigned V1Size,
-                      const Value *V2, unsigned V2Size);
-
-    void getMustAliases(Value *P, std::vector<Value*> &RetVals);
-
-  private:
-    DSGraph *getGraphForValue(const Value *V);
-  };
-
-  // Register the pass...
-  RegisterOpt<DSAA> X("ds-aa", "Data Structure Graph Based Alias Analysis");
-
-  // Register as an implementation of AliasAnalysis
-  RegisterAnalysisGroup<AliasAnalysis, DSAA> Y;
-}
-
-// 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;
-}
-
-// isSinglePhysicalObject - For now, the only case that we know that there is
-// only one memory object in the node is when there is a single global in the
-// node, and the only composition bit set is Global.
-//
-static bool isSinglePhysicalObject(DSNode *N) {
-  assert(N->isComplete() && "Can only tell if this is a complete object!");
-  return N->isGlobalNode() && N->getGlobals().size() == 1 &&
-         !N->isHeapNode() && !N->isAllocaNode() && !N->isUnknownNode();
-}
-
-// alias - This is the only method here that does anything interesting...
-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()) {
-    assert(I->second.getNode() && "Scalar map points to null node?");
-    DSGraph::ScalarMapTy::const_iterator J = GSM.find((Value*)V2);
-    if (J != GSM.end()) {
-      assert(J->second.getNode() && "Scalar map points to null node?");
-
-      DSNode  *N1 = I->second.getNode(),  *N2 = J->second.getNode();
-      unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset();
-        
-      // We can only make a judgement of one of the nodes is complete...
-      if (N1->isComplete() || N2->isComplete()) {
-        if (N1 != N2)
-          return NoAlias;   // Completely different nodes.
-
-#if 0  // This does not correctly handle arrays!
-        // Both point to the same node and same offset, and there is only one
-        // physical memory object represented in the node, return must alias.
-        //
-        // FIXME: This isn't correct because we do not handle array indexing
-        // correctly.
-
-        if (O1 == O2 && isSinglePhysicalObject(N1))
-          return MustAlias; // Exactly the same object & offset
-#endif
-
-        // 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);
-          }
-
-          // FIXME: This is not correct because we do not handle array
-          // indexing correctly with this check!
-          //if (O1+V1Size <= O2) return NoAlias;
-        }
-      }
-    }
-  }
-
-  // FIXME: we could improve on this by checking the globals graph for aliased
-  // global queries...
-  return getAnalysis<AliasAnalysis>().alias(V1, V1Size, V2, V2Size);
-}
-
-
-/// getMustAliases - If there are any pointers known that must alias this
-/// pointer, return them now.  This allows alias-set based alias analyses to
-/// perform a form a value numbering (which is exposed by load-vn).  If an alias
-/// analysis supports this, it should ADD any must aliased pointers to the
-/// specified vector.
-///
-void DSAA::getMustAliases(Value *P, std::vector<Value*> &RetVals) {
-#if 0    // This does not correctly handle arrays!
-  // Currently the only must alias information we can provide is to say that
-  // something is equal to a global value. If we already have a global value,
-  // don't get worked up about it.
-  if (!isa<GlobalValue>(P)) {
-    DSGraph *G = getGraphForValue(P);
-    if (!G) G = &TD->getGlobalsGraph();
-    
-    // The only must alias information we can currently determine occurs when
-    // the node for P is a global node with only one entry.
-    const DSGraph::ScalarMapTy &GSM = G->getScalarMap();
-    DSGraph::ScalarMapTy::const_iterator I = GSM.find(P);
-    if (I != GSM.end()) {
-      DSNode *N = I->second.getNode();
-      if (N->isComplete() && isSinglePhysicalObject(N))
-        RetVals.push_back(N->getGlobals()[0]);
-    }
-  }
-#endif
-  return getAnalysis<AliasAnalysis>().getMustAliases(P, RetVals);
-}
diff --git a/poolalloc/lib/DSA/DataStructureOpt.cpp b/poolalloc/lib/DSA/DataStructureOpt.cpp
deleted file mode 100644
index 297979a..0000000
--- a/poolalloc/lib/DSA/DataStructureOpt.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===- DataStructureOpt.cpp - Data Structure Analysis Based Optimizations -===//
-//
-// This pass uses DSA to a series of simple optimizations, like marking
-// unwritten global variables 'constant'.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/Constant.h"
-#include "Support/Statistic.h"
-
-namespace {
-  Statistic<>
-  NumGlobalsConstanted("ds-opt", "Number of globals marked constant");
-  Statistic<>
-  NumGlobalsIsolated("ds-opt", "Number of globals with references dropped");
-
-  class DSOpt : public Pass {
-    TDDataStructures *TD;
-  public:
-    bool run(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);
-  };
-
-  RegisterOpt<DSOpt> X("ds-opt", "DSA-based simple optimizations");
-}
-
-
-/// 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::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
-    if (!I->isExternal()) { // 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(Constant::getNullValue((Type*)I->getType()));
-          ++NumGlobalsIsolated;
-        }
-      } else if (GNode && GNode->isComplete()) {
-
-        // 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->isModified() && !GNode->isRead() &&I->hasInternalLinkage()){
-          if (!I->use_empty()) {
-            I->replaceAllUsesWith(Constant::getNullValue((Type*)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->isModified() && !I->isConstant()) {
-          I->setConstant(true);
-          ++NumGlobalsConstanted;
-          Changed = true;
-        }
-      }
-    }
-  return Changed;
-}
diff --git a/poolalloc/lib/DSA/DataStructureStats.cpp b/poolalloc/lib/DSA/DataStructureStats.cpp
deleted file mode 100644
index c2ca7ea..0000000
--- a/poolalloc/lib/DSA/DataStructureStats.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-//===- DSGraphStats.cpp - Various statistics for DS Graphs -----*- C++ -*--===//
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Function.h"
-#include "llvm/iOther.h"
-#include "llvm/Pass.h"
-#include "Support/Statistic.h"
-#include <vector>
-
-namespace {
-  Statistic<> TotalNumCallees("totalcallees",
-                "Total number of callee functions at all indirect call sites");
-  Statistic<> NumIndirectCalls("numindirect",
-                "Total number of indirect call sites in the program");
-  Statistic<> NumPoolNodes("numpools",
-                  "Number of allocation nodes that could be pool allocated");
-
-  class DSGraphStats: public FunctionPass {
-    void countCallees(const Function& F, const DSGraph& tdGraph);
-
-  public:
-    /// 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>();
-    }
-
-    /// Debugging support methods
-    void print(std::ostream &O) const { }
-    void dump() const;
-  };
-
-  static RegisterAnalysis<DSGraphStats> Z("dsstats", "DS Graph Statistics");
-}
-
-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, const DSGraph& tdGraph) {
-  unsigned numIndirectCalls = 0, totalNumCallees = 0;
-
-  const std::vector<DSCallSite>& callSites = tdGraph.getFunctionCalls();
-  for (unsigned i=0, N = callSites.size(); i < N; ++i)
-    if (isIndirectCallee(callSites[i].getCallInst().getCalledValue()))
-      { // This is an indirect function call
-        std::vector<GlobalValue*> Callees =
-          callSites[i].getCalleeNode()->getGlobals();
-        if (Callees.size() > 0) {
-          totalNumCallees  += Callees.size();
-          ++numIndirectCalls;
-        }
-#ifndef NDEBUG
-        else
-          std::cerr << "WARNING: No callee in Function " << F.getName()
-                      << "at call:\n" << callSites[i].getCallInst();
-#endif
-      }
-
-  TotalNumCallees  += totalNumCallees;
-  NumIndirectCalls += numIndirectCalls;
-
-  if (numIndirectCalls)
-    std::cout << "  In function " << F.getName() << ":  "
-              << (totalNumCallees / (double) numIndirectCalls)
-              << " average callees per indirect call\n";
-}
-
-
-bool DSGraphStats::runOnFunction(Function& F) {
-  const DSGraph& tdGraph = getAnalysis<TDDataStructures>().getDSGraph(F);
-  countCallees(F, tdGraph);
-  return true;
-}
-
-void DSGraphStats::dump() const
-{
-  this->print(std::cerr);
-}
diff --git a/poolalloc/lib/DSA/GraphChecker.cpp b/poolalloc/lib/DSA/GraphChecker.cpp
deleted file mode 100644
index 4c690b1..0000000
--- a/poolalloc/lib/DSA/GraphChecker.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-//===- GraphChecker.cpp - Assert that various graph properties hold -------===//
-//
-// 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-dsapass={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 "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "Support/CommandLine.h"
-#include "llvm/Value.h"
-#include <set>
-
-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"), 0), 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 {
-    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);
-  };
-
-  RegisterAnalysis<DSGC> X("datastructure-gc", "DSA Graph Checking Pass");
-}
-
-DSGC::DSGC() {
-  if (!AbortIfAnyCollapsed && AbortIfCollapsed.empty() &&
-      CheckFlags.empty() && AbortIfMerged.empty()) {
-    std::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) {
-    const std::vector<DSNode*> &Nodes = G.getNodes();
-    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-      if (Nodes[i]->isNodeCompletelyFolded()) {
-        std::cerr << "Node is collapsed: ";
-        Nodes[i]->print(std::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) {
-      unsigned ColonPos = I->rfind(':');
-      if (ColonPos == std::string::npos) {
-        std::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 |= DSNode::AllocaNode;  break;
-        case 'H': Flags |= DSNode::HeapNode;    break;
-        case 'G': Flags |= DSNode::GlobalNode;  break;
-        case 'U': Flags |= DSNode::UnknownNode; break;
-        case 'I': Flags |= DSNode::Incomplete;  break;
-        case 'M': Flags |= DSNode::Modified;    break;
-        case 'R': Flags |= DSNode::Read;        break;
-        case 'A': Flags |= DSNode::Array;       break;
-        default: std::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)) {
-          std::cerr << "Node for value '%" << Name << "' is collapsed: ";
-          N->print(std::cerr, &G);
-          abort();
-        }
-
-        if (CheckFlagsM.count(Name) && CheckFlagsM[Name] != N->getNodeFlags()) {
-          std::cerr << "Node flags are not as expected for node: " << Name
-                    << "\n";
-          N->print(std::cerr, &G);
-          abort();
-        }
-
-        // Verify that it is not merged if it is not supposed to be...
-        if (AbortIfMergedS.count(Name)) {
-          if (AbortIfMergedNodes.count(N)) {
-            std::cerr << "Nodes for values '%" << Name << "' and '%"
-                      << AbortIfMergedNodes[N] << "' is merged: ";
-            N->print(std::cerr, &G);
-            abort();
-          }
-          AbortIfMergedNodes[N] = Name;
-        }
-      }
-  }
-}
diff --git a/poolalloc/lib/DSA/IPModRef.cpp b/poolalloc/lib/DSA/IPModRef.cpp
deleted file mode 100644
index 86bddc8..0000000
--- a/poolalloc/lib/DSA/IPModRef.cpp
+++ /dev/null
@@ -1,439 +0,0 @@
-//===- IPModRef.cpp - Compute IP Mod/Ref information ------------*- C++ -*-===//
-//
-// See high-level comments in include/llvm/Analysis/IPModRef.h
-// 
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/IPModRef.h"
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/Function.h"
-#include "llvm/iMemory.h"
-#include "llvm/iOther.h"
-#include "Support/Statistic.h"
-#include "Support/STLExtras.h"
-#include "Support/StringExtras.h"
-#include <vector>
-
-//----------------------------------------------------------------------------
-// Private constants and data
-//----------------------------------------------------------------------------
-
-static RegisterAnalysis<IPModRef>
-Z("ipmodref", "Interprocedural mod/ref analysis");
-
-
-//----------------------------------------------------------------------------
-// class ModRefInfo
-//----------------------------------------------------------------------------
-
-void ModRefInfo::print(std::ostream &O,
-                       const std::string& sprefix) const
-{
-  O << sprefix << "Modified   nodes = " << modNodeSet;
-  O << sprefix << "Referenced nodes = " << refNodeSet;
-}
-
-void ModRefInfo::dump() const
-{
-  print(std::cerr);
-}
-
-//----------------------------------------------------------------------------
-// class FunctionModRefInfo
-//----------------------------------------------------------------------------
-
-
-// This constructor computes a node numbering for the TD graph.
-// 
-FunctionModRefInfo::FunctionModRefInfo(const Function& func,
-                                       IPModRef& ipmro,
-                                       DSGraph* tdgClone)
-  : F(func), IPModRefObj(ipmro), 
-    funcTDGraph(tdgClone),
-    funcModRefInfo(tdgClone->getGraphSize())
-{
-  for (unsigned i=0, N = funcTDGraph->getGraphSize(); i < N; ++i)
-    NodeIds[funcTDGraph->getNodes()[i]] = i;
-}
-
-
-FunctionModRefInfo::~FunctionModRefInfo()
-{
-  for(std::map<const CallInst*, ModRefInfo*>::iterator
-        I=callSiteModRefInfo.begin(), E=callSiteModRefInfo.end(); I != E; ++I)
-    delete(I->second);
-
-  // Empty map just to make problems easier to track down
-  callSiteModRefInfo.clear();
-
-  delete funcTDGraph;
-}
-
-unsigned FunctionModRefInfo::getNodeId(const Value* value) const {
-  return getNodeId(funcTDGraph->getNodeForValue(const_cast<Value*>(value))
-                   .getNode());
-}
-
-
-
-// Compute Mod/Ref bit vectors for the entire function.
-// These are simply copies of the Read/Write flags from the nodes of
-// the top-down DS graph.
-// 
-void FunctionModRefInfo::computeModRef(const Function &func)
-{
-  // Mark all nodes in the graph that are marked MOD as being mod
-  // and all those marked REF as being ref.
-  for (unsigned i = 0, N = funcTDGraph->getGraphSize(); i < N; ++i)
-    {
-      if (funcTDGraph->getNodes()[i]->isModified())
-        funcModRefInfo.setNodeIsMod(i);
-      if (funcTDGraph->getNodes()[i]->isRead())
-        funcModRefInfo.setNodeIsRef(i);
-    }
-
-  // Compute the Mod/Ref info for all call sites within the function.
-  // The call sites are recorded in the TD graph.
-  const std::vector<DSCallSite>& callSites = funcTDGraph->getFunctionCalls();
-  for (unsigned i = 0, N = callSites.size(); i < N; ++i)
-    computeModRef(callSites[i].getCallInst());
-}
-
-
-// ResolveCallSiteModRefInfo - This method performs the following actions:
-//
-//  1. It clones the top-down graph for the current function
-//  2. It clears all of the mod/ref bits in the cloned graph
-//  3. It then merges the bottom-up graph(s) for the specified call-site into
-//     the clone (bringing new mod/ref bits).
-//  4. It returns the clone, and a mapping of nodes from the original TDGraph to
-//     the cloned graph with Mod/Ref info for the callsite.
-//
-// NOTE: Because this clones a dsgraph and returns it, the caller is responsible
-//       for deleting the returned graph!
-// NOTE: This method may return a null pointer if it is unable to determine the
-//       requested information (because the call site calls an external
-//       function or we cannot determine the complete set of functions invoked).
-//
-DSGraph* FunctionModRefInfo::ResolveCallSiteModRefInfo(CallInst &CI,
-                               hash_map<const DSNode*, DSNodeHandle> &NodeMap)
-{
-  // Step #0: Quick check if we are going to fail anyway: avoid
-  // all the graph cloning and map copying in steps #1 and #2.
-  // 
-  if (const Function *F = CI.getCalledFunction())
-    {
-      if (F->isExternal())
-        return 0;   // We cannot compute Mod/Ref info for this callsite...
-    }
-  else
-    {
-      // Eventually, should check here if any callee is external.
-      // For now we are not handling this case anyway.
-      std::cerr << "IP Mod/Ref indirect call not implemented yet: "
-              << "Being conservative\n";
-      return 0;   // We cannot compute Mod/Ref info for this callsite...
-    }
-
-  // Step #1: Clone the top-down graph...
-  DSGraph *Result = new DSGraph(*funcTDGraph, NodeMap);
-
-  // Step #2: Clear Mod/Ref information...
-  Result->maskNodeTypes(~(DSNode::Modified | DSNode::Read));
-
-  // Step #3: clone the bottom up graphs for the callees into the caller graph
-  if (Function *F = CI.getCalledFunction())
-    {
-      assert(!F->isExternal());
-
-      // Build up a DSCallSite for our invocation point here...
-
-      // If the call returns a value, make sure to merge the nodes...
-      DSNodeHandle RetVal;
-      if (DS::isPointerType(CI.getType()))
-        RetVal = Result->getNodeForValue(&CI);
-
-      // Populate the arguments list...
-      std::vector<DSNodeHandle> Args;
-      for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
-        if (DS::isPointerType(CI.getOperand(i)->getType()))
-          Args.push_back(Result->getNodeForValue(CI.getOperand(i)));
-
-      // Build the call site...
-      DSCallSite CS(CI, RetVal, F, Args);
-
-      // Perform the merging now of the graph for the callee, which will
-      // come with mod/ref bits set...
-      Result->mergeInGraph(CS, *F, IPModRefObj.getBUDSGraph(*F),
-                           DSGraph::StripAllocaBit
-                           | DSGraph::DontCloneCallNodes
-                           | DSGraph::DontCloneAuxCallNodes);
-    }
-  else
-    assert(0 && "See error message");
-
-  // Remove dead nodes aggressively to match the caller's original graph.
-  Result->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-  // Step #4: Return the clone + the mapping (by ref)
-  return Result;
-}
-
-// Compute Mod/Ref bit vectors for a single call site.
-// These are copies of the Read/Write flags from the nodes of
-// the graph produced by clearing all flags in teh caller's TD graph
-// and then inlining the callee's BU graph into the caller's TD graph.
-// 
-void
-FunctionModRefInfo::computeModRef(const CallInst& callInst)
-{
-  // Allocate the mod/ref info for the call site.  Bits automatically cleared.
-  ModRefInfo* callModRefInfo = new ModRefInfo(funcTDGraph->getGraphSize());
-  callSiteModRefInfo[&callInst] = callModRefInfo;
-
-  // Get a copy of the graph for the callee with the callee inlined
-  hash_map<const DSNode*, DSNodeHandle> NodeMap;
-  DSGraph* csgp = ResolveCallSiteModRefInfo(const_cast<CallInst&>(callInst),
-                                            NodeMap);
-  if (!csgp)
-    { // Callee's side effects are unknown: mark all nodes Mod and Ref.
-      // Eventually this should only mark nodes visible to the callee, i.e.,
-      // exclude stack variables not reachable from any outgoing argument
-      // or any global.
-      callModRefInfo->getModSet().set();
-      callModRefInfo->getRefSet().set();
-      return;
-    }
-
-  // For all nodes in the graph, extract the mod/ref information
-  const std::vector<DSNode*>& csgNodes = csgp->getNodes();
-  const std::vector<DSNode*>& origNodes = funcTDGraph->getNodes();
-  assert(csgNodes.size() == origNodes.size());
-  for (unsigned i=0, N = origNodes.size(); i < N; ++i)
-    { 
-      DSNode* csgNode = NodeMap[origNodes[i]].getNode();
-      assert(csgNode && "Inlined and original graphs do not correspond!");
-      if (csgNode->isModified())
-        callModRefInfo->setNodeIsMod(getNodeId(origNodes[i]));
-      if (csgNode->isRead())
-        callModRefInfo->setNodeIsRef(getNodeId(origNodes[i]));
-    }
-
-  // Drop nodemap before we delete the graph...
-  NodeMap.clear();
-  delete csgp;
-}
-
-
-class DSGraphPrintHelper {
-  const DSGraph& tdGraph;
-  std::vector<std::vector<const Value*> > knownValues; // identifiable objects
-
-public:
-  /*ctor*/ DSGraphPrintHelper(const FunctionModRefInfo& fmrInfo)
-    : tdGraph(fmrInfo.getFuncGraph())
-  {
-    knownValues.resize(tdGraph.getGraphSize());
-
-    // For every identifiable value, save Value pointer in knownValues[i]
-    for (hash_map<Value*, DSNodeHandle>::const_iterator
-           I = tdGraph.getScalarMap().begin(),
-           E = tdGraph.getScalarMap().end(); I != E; ++I)
-      if (isa<GlobalValue>(I->first) ||
-          isa<Argument>(I->first) ||
-          isa<LoadInst>(I->first) ||
-          isa<AllocaInst>(I->first) ||
-          isa<MallocInst>(I->first))
-        {
-          unsigned nodeId = fmrInfo.getNodeId(I->second.getNode());
-          knownValues[nodeId].push_back(I->first);
-        }
-  }
-
-  void printValuesInBitVec(std::ostream &O, const BitSetVector& bv) const
-  {
-    assert(bv.size() == knownValues.size());
-
-    if (bv.none())
-      { // No bits are set: just say so and return
-        O << "\tNONE.\n";
-        return;
-      }
-
-    if (bv.all())
-      { // All bits are set: just say so and return
-        O << "\tALL GRAPH NODES.\n";
-        return;
-      }
-
-    for (unsigned i=0, N=bv.size(); i < N; ++i)
-      if (bv.test(i))
-        {
-          O << "\tNode# " << i << " : ";
-          if (! knownValues[i].empty())
-            for (unsigned j=0, NV=knownValues[i].size(); j < NV; j++)
-              {
-                const Value* V = knownValues[i][j];
-
-                if      (isa<GlobalValue>(V))  O << "(Global) ";
-                else if (isa<Argument>(V))     O << "(Target of FormalParm) ";
-                else if (isa<LoadInst>(V))     O << "(Target of LoadInst  ) ";
-                else if (isa<AllocaInst>(V))   O << "(Target of AllocaInst) ";
-                else if (isa<MallocInst>(V))   O << "(Target of MallocInst) ";
-
-                if (V->hasName())             O << V->getName();
-                else if (isa<Instruction>(V)) O << *V;
-                else                          O << "(Value*) 0x" << (void*) V;
-
-                O << std::string((j < NV-1)? "; " : "\n");
-              }
-          else
-            tdGraph.getNodes()[i]->print(O, /*graph*/ NULL);
-        }
-  }
-};
-
-
-// Print the results of the pass.
-// Currently this just prints bit-vectors and is not very readable.
-// 
-void FunctionModRefInfo::print(std::ostream &O) const
-{
-  DSGraphPrintHelper DPH(*this);
-
-  O << "========== Mod/ref information for function "
-    << F.getName() << "========== \n\n";
-
-  // First: Print Globals and Locals modified anywhere in the function.
-  // 
-  O << "  -----Mod/Ref in the body of function " << F.getName()<< ":\n";
-
-  O << "    --Objects modified in the function body:\n";
-  DPH.printValuesInBitVec(O, funcModRefInfo.getModSet());
-
-  O << "    --Objects referenced in the function body:\n";
-  DPH.printValuesInBitVec(O, funcModRefInfo.getRefSet());
-
-  O << "    --Mod and Ref vectors for the nodes listed above:\n";
-  funcModRefInfo.print(O, "\t");
-
-  O << "\n";
-
-  // Second: Print Globals and Locals modified at each call site in function
-  // 
-  for (std::map<const CallInst*, ModRefInfo*>::const_iterator
-         CI = callSiteModRefInfo.begin(), CE = callSiteModRefInfo.end();
-       CI != CE; ++CI)
-    {
-      O << "  ----Mod/Ref information for call site\n" << CI->first;
-
-      O << "    --Objects modified at call site:\n";
-      DPH.printValuesInBitVec(O, CI->second->getModSet());
-
-      O << "    --Objects referenced at call site:\n";
-      DPH.printValuesInBitVec(O, CI->second->getRefSet());
-
-      O << "    --Mod and Ref vectors for the nodes listed above:\n";
-      CI->second->print(O, "\t");
-
-      O << "\n";
-    }
-
-  O << "\n";
-}
-
-void FunctionModRefInfo::dump() const
-{
-  print(std::cerr);
-}
-
-
-//----------------------------------------------------------------------------
-// class IPModRef: An interprocedural pass that computes IP Mod/Ref info.
-//----------------------------------------------------------------------------
-
-// Free the FunctionModRefInfo objects cached in funcToModRefInfoMap.
-// 
-void IPModRef::releaseMemory()
-{
-  for(std::map<const Function*, FunctionModRefInfo*>::iterator
-        I=funcToModRefInfoMap.begin(), E=funcToModRefInfoMap.end(); I != E; ++I)
-    delete(I->second);
-
-  // Clear map so memory is not re-released if we are called again
-  funcToModRefInfoMap.clear();
-}
-
-// Run the "interprocedural" pass on each function.  This needs to do
-// NO real interprocedural work because all that has been done the
-// data structure analysis.
-// 
-bool IPModRef::run(Module &theModule)
-{
-  M = &theModule;
-
-  for (Module::const_iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI)
-    if (! FI->isExternal())
-      getFuncInfo(*FI, /*computeIfMissing*/ true);
-  return true;
-}
-
-
-FunctionModRefInfo& IPModRef::getFuncInfo(const Function& func,
-                                          bool computeIfMissing)
-{
-  FunctionModRefInfo*& funcInfo = funcToModRefInfoMap[&func];
-  assert (funcInfo != NULL || computeIfMissing);
-  if (funcInfo == NULL)
-    { // Create a new FunctionModRefInfo object.
-      // Clone the top-down graph and remove any dead nodes first, because
-      // otherwise original and merged graphs will not match.
-      // The memory for this graph clone will be freed by FunctionModRefInfo.
-      DSGraph* funcTDGraph =
-        new DSGraph(getAnalysis<TDDataStructures>().getDSGraph(func));
-      funcTDGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-      funcInfo = new FunctionModRefInfo(func, *this, funcTDGraph); //auto-insert
-      funcInfo->computeModRef(func);  // computes the mod/ref info
-    }
-  return *funcInfo;
-}
-
-/// getBUDSGraph - This method returns the BU data structure graph for F through
-/// the use of the BUDataStructures object.
-///
-const DSGraph &IPModRef::getBUDSGraph(const Function &F) {
-  return getAnalysis<BUDataStructures>().getDSGraph(F);
-}
-
-
-// getAnalysisUsage - This pass requires top-down data structure graphs.
-// It modifies nothing.
-// 
-void IPModRef::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.setPreservesAll();
-  AU.addRequired<LocalDataStructures>();
-  AU.addRequired<BUDataStructures>();
-  AU.addRequired<TDDataStructures>();
-}
-
-
-void IPModRef::print(std::ostream &O) const
-{
-  O << "\nRESULTS OF INTERPROCEDURAL MOD/REF ANALYSIS:\n\n";
-  
-  for (std::map<const Function*, FunctionModRefInfo*>::const_iterator
-         mapI = funcToModRefInfoMap.begin(), mapE = funcToModRefInfoMap.end();
-       mapI != mapE; ++mapI)
-    mapI->second->print(O);
-
-  O << "\n";
-}
-
-
-void IPModRef::dump() const
-{
-  print(std::cerr);
-}
diff --git a/poolalloc/lib/DSA/Local.cpp b/poolalloc/lib/DSA/Local.cpp
deleted file mode 100644
index a03354d..0000000
--- a/poolalloc/lib/DSA/Local.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-//===- Local.cpp - Compute a local data structure graph for a function ----===//
-//
-// Compute the local version of the data structure graph for a function.  The
-// external interface to this file is the DSGraph constructor.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/iMemory.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iOther.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Target/TargetData.h"
-#include "Support/CommandLine.h"
-#include "Support/Debug.h"
-#include "Support/Timer.h"
-
-// FIXME: This should eventually be a FunctionPass that is automatically
-// aggregated into a Pass.
-//
-#include "llvm/Module.h"
-
-static RegisterAnalysis<LocalDataStructures>
-X("datastructure", "Local Data Structure Analysis");
-
-namespace DS {
-  // FIXME: Do something smarter with target data!
-  TargetData TD("temp-td");
-
-  // isPointerType - Return true if this type is big enough to hold a pointer.
-  bool isPointerType(const Type *Ty) {
-    if (isa<PointerType>(Ty))
-      return true;
-    else if (Ty->isPrimitiveType() && Ty->isInteger())
-      return Ty->getPrimitiveSize() >= PointerSize;
-    return false;
-  }
-}
-using namespace DS;
-
-
-namespace {
-  cl::opt<bool>
-  DisableDirectCallOpt("disable-direct-call-dsopt", cl::Hidden,
-                       cl::desc("Disable direct call optimization in "
-                                "DSGraph construction"));
-  cl::opt<bool>
-  DisableFieldSensitivity("disable-ds-field-sensitivity", cl::Hidden,
-                          cl::desc("Disable field sensitivity in DSGraphs"));
-
-  //===--------------------------------------------------------------------===//
-  //  GraphBuilder Class
-  //===--------------------------------------------------------------------===//
-  //
-  /// This class is the builder class that constructs the local data structure
-  /// graph by performing a single pass over the function in question.
-  ///
-  class GraphBuilder : InstVisitor<GraphBuilder> {
-    Function &F;
-    DSGraph &G;
-    DSNodeHandle &RetNode;               // Node that gets returned...
-    DSGraph::ScalarMapTy &ScalarMap;
-    std::vector<DSCallSite> &FunctionCalls;
-
-  public:
-    GraphBuilder(Function &f, DSGraph &g, DSNodeHandle &retNode, 
-                 DSGraph::ScalarMapTy &SM, std::vector<DSCallSite> &fc)
-      : F(f), G(g), RetNode(retNode), ScalarMap(SM),
-        FunctionCalls(fc) {
-
-      // Create scalar nodes for all pointer arguments...
-      for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
-        if (isPointerType(I->getType()))
-          getValueDest(*I);
-
-      visit(F);  // Single pass over the function
-    }
-
-  private:
-    // Visitor functions, used to handle each instruction type we encounter...
-    friend class InstVisitor<GraphBuilder>;
-    void visitMallocInst(MallocInst &MI) { handleAlloc(MI, true); }
-    void visitAllocaInst(AllocaInst &AI) { handleAlloc(AI, false); }
-    void handleAlloc(AllocationInst &AI, bool isHeap);
-
-    void visitPHINode(PHINode &PN);
-
-    void visitGetElementPtrInst(User &GEP);
-    void visitReturnInst(ReturnInst &RI);
-    void visitLoadInst(LoadInst &LI);
-    void visitStoreInst(StoreInst &SI);
-    void visitCallInst(CallInst &CI);
-    void visitSetCondInst(SetCondInst &SCI) {}  // SetEQ & friends are ignored
-    void visitFreeInst(FreeInst &FI);
-    void visitCastInst(CastInst &CI);
-    void visitInstruction(Instruction &I);
-
-  private:
-    // Helper functions used to implement the visitation functions...
-
-    /// createNode - Create a new DSNode, ensuring that it is properly added to
-    /// the graph.
-    ///
-    DSNode *createNode(const Type *Ty = 0) {
-      DSNode *N = new DSNode(Ty, &G);   // Create the node
-      if (DisableFieldSensitivity) {
-        N->foldNodeCompletely();
-        if (DSNode *FN = N->getForwardNode())
-          N = FN;
-      }
-      return N;
-    }
-
-    /// 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);
-
-    /// getValueDest - Return the DSNode that the actual value points to. 
-    ///
-    DSNodeHandle getValueDest(Value &V);
-
-    /// 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);
-  };
-}
-
-//===----------------------------------------------------------------------===//
-// DSGraph constructor - Simply use the GraphBuilder to construct the local
-// graph.
-DSGraph::DSGraph(Function &F, DSGraph *GG) : GlobalsGraph(GG) {
-  PrintAuxCalls = false;
-
-  DEBUG(std::cerr << "  [Loc] Calculating graph for: " << F.getName() << "\n");
-
-  // Use the graph builder to construct the local version of the graph
-  GraphBuilder B(F, *this, ReturnNodes[&F], ScalarMap, FunctionCalls);
-#ifndef NDEBUG
-  Timer::addPeakMemoryMeasurement();
-#endif
-
-  // Remove all integral constants from the scalarmap!
-  for (ScalarMapTy::iterator I = ScalarMap.begin(); I != ScalarMap.end();)
-    if (isa<ConstantIntegral>(I->first)) {
-      ScalarMapTy::iterator J = I++;
-      ScalarMap.erase(J);
-    } else
-      ++I;
-
-  markIncompleteNodes(DSGraph::MarkFormalArgs);
-
-  // Remove any nodes made dead due to merging...
-  removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Helper method implementations...
-//
-
-/// getValueDest - Return the DSNode that the actual value points to.
-///
-DSNodeHandle GraphBuilder::getValueDest(Value &Val) {
-  Value *V = &Val;
-  if (V == Constant::getNullValue(V->getType()))
-    return 0;  // Null doesn't point to anything, don't add to ScalarMap!
-
-  DSNodeHandle &NH = ScalarMap[V];
-  if (NH.getNode())
-    return NH;     // Already have a node?  Just return it...
-
-  // Otherwise we need to create a new node to point to.
-  // Check first for constant expressions that must be traversed to
-  // extract the actual value.
-  if (Constant *C = dyn_cast<Constant>(V))
-    if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
-      return NH = getValueDest(*CPR->getValue());
-    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
-      if (CE->getOpcode() == Instruction::Cast)
-        NH = getValueDest(*CE->getOperand(0));
-      else if (CE->getOpcode() == Instruction::GetElementPtr) {
-        visitGetElementPtrInst(*CE);
-        DSGraph::ScalarMapTy::iterator I = ScalarMap.find(CE);
-        assert(I != ScalarMap.end() && "GEP didn't get processed right?");
-        NH = I->second;
-      } else {
-        // This returns a conservative unknown node for any unhandled ConstExpr
-        return NH = createNode()->setUnknownNodeMarker();
-      }
-      if (NH.getNode() == 0) {  // (getelementptr null, X) returns null
-        ScalarMap.erase(V);
-        return 0;
-      }
-      return NH;
-
-    } else if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(C)) {
-      // Random constants are unknown mem
-      return NH = createNode()->setUnknownNodeMarker();
-    } else {
-      assert(0 && "Unknown constant type!");
-    }
-
-  // Otherwise we need to create a new node to point to...
-  DSNode *N;
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
-    // Create a new global node for this global variable...
-    N = createNode(GV->getType()->getElementType());
-    N->addGlobal(GV);
-  } else {
-    // Otherwise just create a shadow node
-    N = createNode();
-  }
-
-  NH.setNode(N);      // Remember that we are pointing to it...
-  NH.setOffset(0);
-  return NH;
-}
-
-
-/// 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 &GraphBuilder::getLink(const DSNodeHandle &node, unsigned LinkNo) {
-  DSNodeHandle &Node = const_cast<DSNodeHandle&>(node);
-  DSNodeHandle &Link = Node.getLink(LinkNo);
-  if (!Link.getNode()) {
-    // 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 GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
-  DSNodeHandle &AINH = ScalarMap[&V];
-  if (AINH.getNode() == 0)   // Not pointing to anything yet?
-    AINH = NH;               // Just point directly to NH
-  else
-    AINH.mergeWith(NH);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Specific instruction type handler implementations...
-//
-
-/// Alloca & Malloc instruction implementation - Simply create a new memory
-/// object, pointing the scalar to it.
-///
-void GraphBuilder::handleAlloc(AllocationInst &AI, bool isHeap) {
-  DSNode *N = createNode();
-  if (isHeap)
-    N->setHeapNodeMarker();
-  else
-    N->setAllocaNodeMarker();
-  setDestTo(AI, N);
-}
-
-// PHINode - Make the scalar for the PHI node point to all of the things the
-// incoming values point to... which effectively causes them to be merged.
-//
-void GraphBuilder::visitPHINode(PHINode &PN) {
-  if (!isPointerType(PN.getType())) return; // Only pointer PHIs
-
-  DSNodeHandle &PNDest = ScalarMap[&PN];
-  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
-    PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
-}
-
-void GraphBuilder::visitGetElementPtrInst(User &GEP) {
-  DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
-  if (Value.getNode() == 0) return;
-
-  unsigned Offset = 0;
-  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;
-  }
-
-#if 0
-  // Handle the pointer index specially...
-  if (GEP.getNumOperands() > 1 &&
-      GEP.getOperand(1) != ConstantSInt::getNullValue(Type::LongTy)) {
-
-    // 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...
-  for (unsigned i = 2, e = GEP.getNumOperands(); i < e; ++i)
-    if (GEP.getOperand(i)->getType() == Type::LongTy) {
-      // Get the type indexing into...
-      const SequentialType *STy = cast<SequentialType>(CurTy);
-      CurTy = STy->getElementType();
-#if 0
-      if (ConstantSInt *CS = dyn_cast<ConstantSInt>(GEP.getOperand(i))) {
-        Offset += CS->getValue()*TD.getTypeSize(CurTy);
-      } else {
-        // Variable index into a node.  We must merge all of the elements of the
-        // sequential type here.
-        if (isa<PointerType>(STy))
-          std::cerr << "Pointer indexing not handled yet!\n";
-        else {
-          const ArrayType *ATy = cast<ArrayType>(STy);
-          unsigned ElSize = TD.getTypeSize(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
-          // zero'th 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
-    } else if (GEP.getOperand(i)->getType() == Type::UByteTy) {
-      unsigned FieldNo = cast<ConstantUInt>(GEP.getOperand(i))->getValue();
-      const StructType *STy = cast<StructType>(CurTy);
-      Offset += TD.getStructLayout(STy)->MemberOffsets[FieldNo];
-      CurTy = STy->getContainedType(FieldNo);
-    }
-
-  // Add in the offset calculated...
-  Value.setOffset(Value.getOffset()+Offset);
-
-  // Value is now the pointer we want to GEP to be...
-  setDestTo(GEP, Value);
-}
-
-void GraphBuilder::visitLoadInst(LoadInst &LI) {
-  DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
-  if (Ptr.getNode() == 0) return;
-
-  // Make that the node is read from...
-  Ptr.getNode()->setReadMarker();
-
-  // Ensure a typerecord exists...
-  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
-
-  if (isPointerType(LI.getType()))
-    setDestTo(LI, getLink(Ptr));
-}
-
-void GraphBuilder::visitStoreInst(StoreInst &SI) {
-  const Type *StoredTy = SI.getOperand(0)->getType();
-  DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
-  if (Dest.getNode() == 0) return;
-
-  // Mark that the node is written to...
-  Dest.getNode()->setModifiedMarker();
-
-  // Ensure a typerecord exists...
-  Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());
-
-  // Avoid adding edges from null, or processing non-"pointer" stores
-  if (isPointerType(StoredTy))
-    Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
-}
-
-void GraphBuilder::visitReturnInst(ReturnInst &RI) {
-  if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()))
-    RetNode.mergeWith(getValueDest(*RI.getOperand(0)));
-}
-
-void GraphBuilder::visitCallInst(CallInst &CI) {
-  // Set up the return value...
-  DSNodeHandle RetVal;
-  if (isPointerType(CI.getType()))
-    RetVal = getValueDest(CI);
-
-  DSNode *Callee = 0;
-  if (DisableDirectCallOpt || !isa<Function>(CI.getOperand(0)))
-    Callee = getValueDest(*CI.getOperand(0)).getNode();
-
-  std::vector<DSNodeHandle> Args;
-  Args.reserve(CI.getNumOperands()-1);
-
-  // Calculate the arguments vector...
-  for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
-    if (isPointerType(CI.getOperand(i)->getType()))
-      Args.push_back(getValueDest(*CI.getOperand(i)));
-
-  // Add a new function call entry...
-  if (Callee)
-    FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
-  else
-    FunctionCalls.push_back(DSCallSite(CI, RetVal,
-                                       cast<Function>(CI.getOperand(0)), Args));
-}
-
-void GraphBuilder::visitFreeInst(FreeInst &FI) {
-  // Mark that the node is written to...
-  DSNode *N = getValueDest(*FI.getOperand(0)).getNode();
-  N->setModifiedMarker();
-  N->setHeapNodeMarker();
-}
-
-/// Handle casts...
-void GraphBuilder::visitCastInst(CastInst &CI) {
-  if (isPointerType(CI.getType()))
-    if (isPointerType(CI.getOperand(0)->getType())) {
-      // Cast one pointer to the other, just act like a copy instruction
-      setDestTo(CI, getValueDest(*CI.getOperand(0)));
-    } else {
-      // Cast something (floating point, small integer) to a pointer.  We need
-      // to track the fact that the node points to SOMETHING, just something we
-      // don't know about.  Make an "Unknown" node.
-      //
-      setDestTo(CI, createNode()->setUnknownNodeMarker());
-    }
-}
-
-
-// visitInstruction - For all other instruction types, if we have any arguments
-// that are of pointer type, make them have unknown composition bits, and merge
-// the nodes together.
-void GraphBuilder::visitInstruction(Instruction &Inst) {
-  DSNodeHandle CurNode;
-  if (isPointerType(Inst.getType()))
-    CurNode = getValueDest(Inst);
-  for (User::op_iterator I = Inst.op_begin(), E = Inst.op_end(); I != E; ++I)
-    if (isPointerType((*I)->getType()))
-      CurNode.mergeWith(getValueDest(**I));
-
-  if (CurNode.getNode())
-    CurNode.getNode()->setUnknownNodeMarker();
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// LocalDataStructures Implementation
-//===----------------------------------------------------------------------===//
-
-bool LocalDataStructures::run(Module &M) {
-  GlobalsGraph = new DSGraph();
-
-  // Calculate all of the graphs...
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isExternal())
-      DSInfo.insert(std::make_pair(I, new DSGraph(*I, GlobalsGraph)));
-  return false;
-}
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-void LocalDataStructures::releaseMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
diff --git a/poolalloc/lib/DSA/Makefile b/poolalloc/lib/DSA/Makefile
deleted file mode 100644
index 3c4c7e2..0000000
--- a/poolalloc/lib/DSA/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-LEVEL = ../../..
-LIBRARYNAME = datastructure
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/poolalloc/lib/DSA/MemoryDepAnalysis.cpp b/poolalloc/lib/DSA/MemoryDepAnalysis.cpp
deleted file mode 100644
index 598bff9..0000000
--- a/poolalloc/lib/DSA/MemoryDepAnalysis.cpp
+++ /dev/null
@@ -1,491 +0,0 @@
-//===- MemoryDepAnalysis.cpp - Compute dep graph for memory ops --*-C++-*--===//
-//
-// This file implements a pass (MemoryDepAnalysis) that computes memory-based
-// data dependences between instructions for each function in a module.  
-// Memory-based dependences occur due to load and store operations, but
-// also the side-effects of call instructions.
-//
-// The result of this pass is a DependenceGraph for each function
-// representing the memory-based data dependences between instructions.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/MemoryDepAnalysis.h"
-#include "llvm/Analysis/IPModRef.h"
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/Function.h"
-#include "llvm/iMemory.h"
-#include "llvm/iOther.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/CFG.h"
-#include "Support/TarjanSCCIterator.h"
-#include "Support/Statistic.h"
-#include "Support/STLExtras.h"
-#include "Support/hash_map"
-#include "Support/hash_set"
-#include <iostream>
-
-
-///--------------------------------------------------------------------------
-/// struct ModRefTable:
-/// 
-/// A data structure that tracks ModRefInfo for instructions:
-///   -- modRefMap is a map of Instruction* -> ModRefInfo for the instr.
-///   -- definers  is a vector of instructions that define    any node
-///   -- users     is a vector of instructions that reference any node
-///   -- numUsersBeforeDef is a vector indicating that the number of users
-///                seen before definers[i] is numUsersBeforeDef[i].
-/// 
-/// numUsersBeforeDef[] effectively tells us the exact interleaving of
-/// definers and users within the ModRefTable.
-/// This is only maintained when constructing the table for one SCC, and
-/// not copied over from one table to another since it is no longer useful.
-///--------------------------------------------------------------------------
-
-struct ModRefTable
-{
-  typedef hash_map<Instruction*, ModRefInfo> ModRefMap;
-  typedef ModRefMap::const_iterator                 const_map_iterator;
-  typedef ModRefMap::      iterator                        map_iterator;
-  typedef std::vector<Instruction*>::const_iterator const_ref_iterator;
-  typedef std::vector<Instruction*>::      iterator       ref_iterator;
-
-  ModRefMap                 modRefMap;
-  std::vector<Instruction*> definers;
-  std::vector<Instruction*> users;
-  std::vector<unsigned>     numUsersBeforeDef;
-
-  // Iterators to enumerate all the defining instructions
-  const_ref_iterator defsBegin()  const {  return definers.begin(); }
-        ref_iterator defsBegin()        {  return definers.begin(); }
-  const_ref_iterator defsEnd()    const {  return definers.end(); }
-        ref_iterator defsEnd()          {  return definers.end(); }
-
-  // Iterators to enumerate all the user instructions
-  const_ref_iterator usersBegin() const {  return users.begin(); }
-        ref_iterator usersBegin()       {  return users.begin(); }
-  const_ref_iterator usersEnd()   const {  return users.end(); }
-        ref_iterator usersEnd()         {  return users.end(); }
-
-  // Iterator identifying the last user that was seen *before* a
-  // specified def.  In particular, all users in the half-closed range
-  //    [ usersBegin(), usersBeforeDef_End(defPtr) )
-  // were seen *before* the specified def.  All users in the half-closed range
-  //    [ usersBeforeDef_End(defPtr), usersEnd() )
-  // were seen *after* the specified def.
-  // 
-  ref_iterator usersBeforeDef_End(const_ref_iterator defPtr) {
-    unsigned defIndex = (unsigned) (defPtr - defsBegin());
-    assert(defIndex < numUsersBeforeDef.size());
-    assert(usersBegin() + numUsersBeforeDef[defIndex] <= usersEnd()); 
-    return usersBegin() + numUsersBeforeDef[defIndex]; 
-  }
-  const_ref_iterator usersBeforeDef_End(const_ref_iterator defPtr) const {
-    return const_cast<ModRefTable*>(this)->usersBeforeDef_End(defPtr);
-  }
-
-  // 
-  // Modifier methods
-  // 
-  void AddDef(Instruction* D) {
-    definers.push_back(D);
-    numUsersBeforeDef.push_back(users.size());
-  }
-  void AddUse(Instruction* U) {
-    users.push_back(U);
-  }
-  void Insert(const ModRefTable& fromTable) {
-    modRefMap.insert(fromTable.modRefMap.begin(), fromTable.modRefMap.end());
-    definers.insert(definers.end(),
-                    fromTable.definers.begin(), fromTable.definers.end());
-    users.insert(users.end(),
-                 fromTable.users.begin(), fromTable.users.end());
-    numUsersBeforeDef.clear(); /* fromTable.numUsersBeforeDef is ignored */
-  }
-};
-
-
-///--------------------------------------------------------------------------
-/// class ModRefInfoBuilder:
-/// 
-/// A simple InstVisitor<> class that retrieves the Mod/Ref info for
-/// Load/Store/Call instructions and inserts this information in
-/// a ModRefTable.  It also records all instructions that Mod any node
-/// and all that use any node.
-///--------------------------------------------------------------------------
-
-class ModRefInfoBuilder : public InstVisitor<ModRefInfoBuilder> {
-  const DSGraph&            funcGraph;
-  const FunctionModRefInfo& funcModRef;
-  ModRefTable&              modRefTable;
-
-  ModRefInfoBuilder();                         // DO NOT IMPLEMENT
-  ModRefInfoBuilder(const ModRefInfoBuilder&); // DO NOT IMPLEMENT
-  void operator=(const ModRefInfoBuilder&);    // DO NOT IMPLEMENT
-
-public:
-  /*ctor*/      ModRefInfoBuilder(const DSGraph&  _funcGraph,
-                                  const FunctionModRefInfo& _funcModRef,
-                                  ModRefTable&    _modRefTable)
-    : funcGraph(_funcGraph), funcModRef(_funcModRef), modRefTable(_modRefTable)
-  {
-  }
-
-  // At a call instruction, retrieve the ModRefInfo using IPModRef results.
-  // Add the call to the defs list if it modifies any nodes and to the uses
-  // list if it refs any nodes.
-  // 
-  void          visitCallInst   (CallInst& callInst) {
-    ModRefInfo safeModRef(funcGraph.getGraphSize());
-    const ModRefInfo* callModRef = funcModRef.getModRefInfo(callInst);
-    if (callModRef == NULL)
-      { // call to external/unknown function: mark all nodes as Mod and Ref
-        safeModRef.getModSet().set();
-        safeModRef.getRefSet().set();
-        callModRef = &safeModRef;
-      }
-
-    modRefTable.modRefMap.insert(std::make_pair(&callInst,
-                                                ModRefInfo(*callModRef)));
-    if (callModRef->getModSet().any())
-      modRefTable.AddDef(&callInst);
-    if (callModRef->getRefSet().any())
-      modRefTable.AddUse(&callInst);
-  }
-
-  // At a store instruction, add to the mod set the single node pointed to
-  // by the pointer argument of the store.  Interestingly, if there is no
-  // such node, that would be a null pointer reference!
-  void          visitStoreInst  (StoreInst& storeInst) {
-    const DSNodeHandle& ptrNode =
-      funcGraph.getNodeForValue(storeInst.getPointerOperand());
-    if (const DSNode* target = ptrNode.getNode())
-      {
-        unsigned nodeId = funcModRef.getNodeId(target);
-        ModRefInfo& minfo =
-          modRefTable.modRefMap.insert(
-            std::make_pair(&storeInst,
-                           ModRefInfo(funcGraph.getGraphSize()))).first->second;
-        minfo.setNodeIsMod(nodeId);
-        modRefTable.AddDef(&storeInst);
-      }
-    else
-      std::cerr << "Warning: Uninitialized pointer reference!\n";
-  }
-
-  // At a load instruction, add to the ref set the single node pointed to
-  // by the pointer argument of the load.  Interestingly, if there is no
-  // such node, that would be a null pointer reference!
-  void          visitLoadInst  (LoadInst& loadInst) {
-    const DSNodeHandle& ptrNode =
-      funcGraph.getNodeForValue(loadInst.getPointerOperand());
-    if (const DSNode* target = ptrNode.getNode())
-      {
-        unsigned nodeId = funcModRef.getNodeId(target);
-        ModRefInfo& minfo =
-          modRefTable.modRefMap.insert(
-            std::make_pair(&loadInst,
-                           ModRefInfo(funcGraph.getGraphSize()))).first->second;
-        minfo.setNodeIsRef(nodeId);
-        modRefTable.AddUse(&loadInst);
-      }
-    else
-      std::cerr << "Warning: Uninitialized pointer reference!\n";
-  }
-};
-
-
-//----------------------------------------------------------------------------
-// class MemoryDepAnalysis: A dep. graph for load/store/call instructions
-//----------------------------------------------------------------------------
-
-/// Basic dependence gathering algorithm, using TarjanSCCIterator on CFG:
-/// 
-/// for every SCC S in the CFG in PostOrder on the SCC DAG
-///     {
-///       for every basic block BB in S in *postorder*
-///         for every instruction I in BB in reverse
-///           Add (I, ModRef[I]) to ModRefCurrent
-///           if (Mod[I] != NULL)
-///               Add I to DefSetCurrent:  { I \in S : Mod[I] != NULL }
-///           if (Ref[I] != NULL)
-///               Add I to UseSetCurrent:  { I       : Ref[I] != NULL }
-/// 
-///       for every def D in DefSetCurrent
-/// 
-///           // NOTE: D comes after itself iff S contains a loop
-///           if (HasLoop(S) && D & D)
-///               Add output-dep: D -> D2
-/// 
-///           for every def D2 *after* D in DefSetCurrent
-///               // NOTE: D2 comes before D in execution order
-///               if (D & D2)
-///                   Add output-dep: D2 -> D
-///                   if (HasLoop(S))
-///                       Add output-dep: D -> D2
-/// 
-///           for every use U in UseSetCurrent that was seen *before* D
-///               // NOTE: U comes after D in execution order
-///               if (U & D)
-///                   if (U != D || HasLoop(S))
-///                       Add true-dep: D -> U
-///                   if (HasLoop(S))
-///                       Add anti-dep: U -> D
-/// 
-///           for every use U in UseSetCurrent that was seen *after* D
-///               // NOTE: U comes before D in execution order
-///               if (U & D)
-///                   if (U != D || HasLoop(S))
-///                       Add anti-dep: U -> D
-///                   if (HasLoop(S))
-///                       Add true-dep: D -> U
-/// 
-///           for every def Dnext in DefSetAfter
-///               // NOTE: Dnext comes after D in execution order
-///               if (Dnext & D)
-///                   Add output-dep: D -> Dnext
-/// 
-///           for every use Unext in UseSetAfter
-///               // NOTE: Unext comes after D in execution order
-///               if (Unext & D)
-///                   Add true-dep: D -> Unext
-/// 
-///       for every use U in UseSetCurrent
-///           for every def Dnext in DefSetAfter
-///               // NOTE: Dnext comes after U in execution order
-///               if (Dnext & D)
-///                   Add anti-dep: U -> Dnext
-/// 
-///       Add ModRefCurrent to ModRefAfter: { (I, ModRef[I] ) }
-///       Add DefSetCurrent to DefSetAfter: { I : Mod[I] != NULL }
-///       Add UseSetCurrent to UseSetAfter: { I : Ref[I] != NULL }
-///     }
-///         
-///
-
-void MemoryDepAnalysis::ProcessSCC(SCC<Function*>& S,
-                                   ModRefTable& ModRefAfter)
-{
-  ModRefTable ModRefCurrent;
-  ModRefTable::ModRefMap& mapCurrent = ModRefCurrent.modRefMap;
-  ModRefTable::ModRefMap& mapAfter   = ModRefAfter.modRefMap;
-
-  bool hasLoop = S.HasLoop();
-
-  // Builder class fills out a ModRefTable one instruction at a time.
-  // To use it, we just invoke it's visit function for each basic block:
-  // 
-  //   for each basic block BB in the SCC in *postorder*
-  //       for each instruction  I in BB in *reverse*
-  //           ModRefInfoBuilder::visit(I)
-  //           : Add (I, ModRef[I]) to ModRefCurrent.modRefMap
-  //           : Add I  to ModRefCurrent.definers if it defines any node
-  //           : Add I  to ModRefCurrent.users    if it uses any node
-  // 
-  ModRefInfoBuilder builder(*funcGraph, *funcModRef, ModRefCurrent);
-  for (SCC<Function*>::iterator BI=S.begin(), BE=S.end(); BI != BE; ++BI)
-    // Note: BBs in the SCC<> created by TarjanSCCIterator are in postorder.
-    for (BasicBlock::reverse_iterator II=(*BI)->rbegin(), IE=(*BI)->rend();
-         II != IE; ++II)
-      builder.visit(*II);
-
-  ///       for every def D in DefSetCurrent
-  /// 
-  for (ModRefTable::ref_iterator II=ModRefCurrent.defsBegin(),
-         IE=ModRefCurrent.defsEnd(); II != IE; ++II)
-    {
-      ///           // NOTE: D comes after itself iff S contains a loop
-      ///           if (HasLoop(S))
-      ///               Add output-dep: D -> D2
-      if (hasLoop)
-        funcDepGraph->AddSimpleDependence(**II, **II, OutputDependence);
-
-      ///           for every def D2 *after* D in DefSetCurrent
-      ///               // NOTE: D2 comes before D in execution order
-      ///               if (D2 & D)
-      ///                   Add output-dep: D2 -> D
-      ///                   if (HasLoop(S))
-      ///                       Add output-dep: D -> D2
-      for (ModRefTable::ref_iterator JI=II+1; JI != IE; ++JI)
-        if (!Disjoint(mapCurrent.find(*II)->second.getModSet(),
-                      mapCurrent.find(*JI)->second.getModSet()))
-          {
-            funcDepGraph->AddSimpleDependence(**JI, **II, OutputDependence);
-            if (hasLoop)
-              funcDepGraph->AddSimpleDependence(**II, **JI, OutputDependence);
-          }
-  
-      ///           for every use U in UseSetCurrent that was seen *before* D
-      ///               // NOTE: U comes after D in execution order
-      ///               if (U & D)
-      ///                   if (U != D || HasLoop(S))
-      ///                       Add true-dep: U -> D
-      ///                   if (HasLoop(S))
-      ///                       Add anti-dep: D -> U
-      ModRefTable::ref_iterator JI=ModRefCurrent.usersBegin();
-      ModRefTable::ref_iterator JE = ModRefCurrent.usersBeforeDef_End(II);
-      for ( ; JI != JE; ++JI)
-        if (!Disjoint(mapCurrent.find(*II)->second.getModSet(),
-                      mapCurrent.find(*JI)->second.getRefSet()))
-          {
-            if (*II != *JI || hasLoop)
-              funcDepGraph->AddSimpleDependence(**II, **JI, TrueDependence);
-            if (hasLoop)
-              funcDepGraph->AddSimpleDependence(**JI, **II, AntiDependence);
-          }
-
-      ///           for every use U in UseSetCurrent that was seen *after* D
-      ///               // NOTE: U comes before D in execution order
-      ///               if (U & D)
-      ///                   if (U != D || HasLoop(S))
-      ///                       Add anti-dep: U -> D
-      ///                   if (HasLoop(S))
-      ///                       Add true-dep: D -> U
-      for (/*continue JI*/ JE = ModRefCurrent.usersEnd(); JI != JE; ++JI)
-        if (!Disjoint(mapCurrent.find(*II)->second.getModSet(),
-                      mapCurrent.find(*JI)->second.getRefSet()))
-          {
-            if (*II != *JI || hasLoop)
-              funcDepGraph->AddSimpleDependence(**JI, **II, AntiDependence);
-            if (hasLoop)
-              funcDepGraph->AddSimpleDependence(**II, **JI, TrueDependence);
-          }
-
-      ///           for every def Dnext in DefSetPrev
-      ///               // NOTE: Dnext comes after D in execution order
-      ///               if (Dnext & D)
-      ///                   Add output-dep: D -> Dnext
-      for (ModRefTable::ref_iterator JI=ModRefAfter.defsBegin(),
-             JE=ModRefAfter.defsEnd(); JI != JE; ++JI)
-        if (!Disjoint(mapCurrent.find(*II)->second.getModSet(),
-                      mapAfter.find(*JI)->second.getModSet()))
-          funcDepGraph->AddSimpleDependence(**II, **JI, OutputDependence);
-
-      ///           for every use Unext in UseSetAfter
-      ///               // NOTE: Unext comes after D in execution order
-      ///               if (Unext & D)
-      ///                   Add true-dep: D -> Unext
-      for (ModRefTable::ref_iterator JI=ModRefAfter.usersBegin(),
-             JE=ModRefAfter.usersEnd(); JI != JE; ++JI)
-        if (!Disjoint(mapCurrent.find(*II)->second.getModSet(),
-                      mapAfter.find(*JI)->second.getRefSet()))
-          funcDepGraph->AddSimpleDependence(**II, **JI, TrueDependence);
-    }
-
-  /// 
-  ///       for every use U in UseSetCurrent
-  ///           for every def Dnext in DefSetAfter
-  ///               // NOTE: Dnext comes after U in execution order
-  ///               if (Dnext & D)
-  ///                   Add anti-dep: U -> Dnext
-  for (ModRefTable::ref_iterator II=ModRefCurrent.usersBegin(),
-         IE=ModRefCurrent.usersEnd(); II != IE; ++II)
-    for (ModRefTable::ref_iterator JI=ModRefAfter.defsBegin(),
-           JE=ModRefAfter.defsEnd(); JI != JE; ++JI)
-      if (!Disjoint(mapCurrent.find(*II)->second.getRefSet(),
-                    mapAfter.find(*JI)->second.getModSet()))
-        funcDepGraph->AddSimpleDependence(**II, **JI, AntiDependence);
-    
-  ///       Add ModRefCurrent to ModRefAfter: { (I, ModRef[I] ) }
-  ///       Add DefSetCurrent to DefSetAfter: { I : Mod[I] != NULL }
-  ///       Add UseSetCurrent to UseSetAfter: { I : Ref[I] != NULL }
-  ModRefAfter.Insert(ModRefCurrent);
-}
-
-
-/// Debugging support methods
-/// 
-void MemoryDepAnalysis::print(std::ostream &O) const
-{
-  // TEMPORARY LOOP
-  for (hash_map<Function*, DependenceGraph*>::const_iterator
-         I = funcMap.begin(), E = funcMap.end(); I != E; ++I)
-    {
-      Function* func = I->first;
-      DependenceGraph* depGraph = I->second;
-
-  O << "\n================================================================\n";
-  O << "DEPENDENCE GRAPH FOR MEMORY OPERATIONS IN FUNCTION " << func->getName();
-  O << "\n================================================================\n\n";
-  depGraph->print(*func, O);
-
-    }
-}
-
-
-/// 
-/// Run the pass on a function
-/// 
-bool MemoryDepAnalysis::runOnFunction(Function& func)
-{
-  assert(! func.isExternal());
-
-  // Get the FunctionModRefInfo holding IPModRef results for this function.
-  // Use the TD graph recorded within the FunctionModRefInfo object, which
-  // may not be the same as the original TD graph computed by DS analysis.
-  // 
-  funcModRef = &getAnalysis<IPModRef>().getFunctionModRefInfo(func);
-  funcGraph  = &funcModRef->getFuncGraph();
-
-  // TEMPORARY: ptr to depGraph (later just becomes "this").
-  assert(funcMap.find(&func) == funcMap.end() && "Analyzing function twice?");
-  funcDepGraph = funcMap[&func] = new DependenceGraph();
-
-  ModRefTable ModRefAfter;
-
-  SCC<Function*>* nextSCC;
-  for (TarjanSCC_iterator<Function*> tarjSCCiter = tarj_begin(&func);
-       (nextSCC = *tarjSCCiter) != NULL; ++tarjSCCiter)
-    ProcessSCC(*nextSCC, ModRefAfter);
-
-  return true;
-}
-
-
-//-------------------------------------------------------------------------
-// TEMPORARY FUNCTIONS TO MAKE THIS A MODULE PASS ---
-// These functions will go away once this class becomes a FunctionPass.
-// 
-
-// Driver function to compute dependence graphs for every function.
-// This is temporary and will go away once this is a FunctionPass.
-// 
-bool MemoryDepAnalysis::run(Module& M)
-{
-  for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
-    if (! FI->isExternal())
-      runOnFunction(*FI); // automatically inserts each depGraph into funcMap
-  return true;
-}
-  
-// Release all the dependence graphs in the map.
-void MemoryDepAnalysis::releaseMemory()
-{
-  for (hash_map<Function*, DependenceGraph*>::const_iterator
-         I = funcMap.begin(), E = funcMap.end(); I != E; ++I)
-    delete I->second;
-  funcMap.clear();
-
-  // Clear pointers because the pass constructor will not be invoked again.
-  funcDepGraph = NULL;
-  funcGraph = NULL;
-  funcModRef = NULL;
-}
-
-MemoryDepAnalysis::~MemoryDepAnalysis()
-{
-  releaseMemory();
-}
-
-//----END TEMPORARY FUNCTIONS----------------------------------------------
-
-
-void MemoryDepAnalysis::dump() const
-{
-  this->print(std::cerr);
-}
-
-static RegisterAnalysis<MemoryDepAnalysis>
-Z("memdep", "Memory Dependence Analysis");
-
diff --git a/poolalloc/lib/DSA/Parallelize.cpp b/poolalloc/lib/DSA/Parallelize.cpp
deleted file mode 100644
index 81a5252..0000000
--- a/poolalloc/lib/DSA/Parallelize.cpp
+++ /dev/null
@@ -1,548 +0,0 @@
-//===- Parallelize.cpp - Auto parallelization using DS Graphs ---*- C++ -*-===//
-//
-// This file implements a pass that automatically parallelizes a program,
-// using the Cilk multi-threaded runtime system to execute parallel code.
-// 
-// The pass uses the Program Dependence Graph (class PDGIterator) to
-// identify parallelizable function calls, i.e., calls whose instances
-// can be executed in parallel with instances of other function calls.
-// (In the future, this should also execute different instances of the same
-// function call in parallel, but that requires parallelizing across
-// loop iterations.)
-//
-// The output of the pass is LLVM code with:
-// (1) all parallelizable functions renamed to flag them as parallelizable;
-// (2) calls to a sync() function introduced at synchronization points.
-// The CWriter recognizes these functions and inserts the appropriate Cilk
-// keywords when writing out C code.  This C code must be compiled with cilk2c.
-// 
-// Current algorithmic limitations:
-// -- no array dependence analysis
-// -- no parallelization for function calls in different loop iterations
-//    (except in unlikely trivial cases)
-//
-// Limitations of using Cilk:
-// -- No parallelism within a function body, e.g., in a loop;
-// -- Simplistic synchronization model requiring all parallel threads 
-//    created within a function to block at a sync().
-// -- Excessive overhead at "spawned" function calls, which has no benefit
-//    once all threads are busy (especially common when the degree of
-//    parallelism is low).
-//===----------------------------------------------------------------------===//
-
-
-#include "llvm/Transforms/Parallelize.h"
-#include "llvm/Transforms/Utils/DemoteRegToStack.h"
-#include "llvm/Analysis/PgmDependenceGraph.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/Function.h"
-#include "llvm/iOther.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iTerminators.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/Cilkifier.h"
-#include "Support/Statistic.h"
-#include "Support/STLExtras.h"
-#include "Support/hash_set"
-#include "Support/hash_map"
-#include <vector>
-#include <stack>
-#include <functional>
-#include <algorithm>
-
-
-
-#if 0
-void AddToDomSet(vector<BasicBlock*>& domSet, BasicBlock* bb,
-                 const DominatorTree& domTree)
-{
-  DominatorTreeBase::Node* bbNode = domTree.getNode(bb);
-  const std::vector<Node*>& domKids = bbNode.getChildren();
-  domSet.insert(domSet.end(), domKids.begin(), domKids.end());
-  for (unsigned i = 0; i < domKids.size(); ++i)
-    AddToDomSet(domSet, domKids[i]->getNode(), domTree);
-}
-
-bool CheckDominance(Function& func,
-                    const CallInst& callInst1,
-                    const CallInst& callInst2)
-{
-  if (callInst1 == callInst2)           // makes sense if this is in a loop but
-    return false;                       // we're not handling loops yet
-
-  // Check first if one call dominates the other
-  DominatorSet& domSet = getAnalysis<DominatorSet>(func);
-  if (domSet.dominates(callInst2, callInst1))
-    { // swap callInst1 and callInst2
-      const CallInst& tmp = callInst2; callInst2 = callInst1; callInst1 = tmp;
-    }
-  else if (! domSet.dominates(callInst1, callInst2))
-    return false;                       // neither dominates the other: 
-
-  // 
-  if (! AreIndependent(func, callInst1, callInst2))
-    return false;
-}
-
-#endif
-
-
-//---------------------------------------------------------------------------- 
-// class Cilkifier
-//
-// Code generation pass that transforms code to identify where Cilk keywords
-// should be inserted.  This relies on dis -c to print out the keywords.
-//---------------------------------------------------------------------------- 
-
-
-class Cilkifier: public InstVisitor<Cilkifier>
-{
-  Function* DummySyncFunc;
-
-  // Data used when transforming each function.
-  hash_set<const Instruction*>  stmtsVisited;    // Flags for recursive DFS
-  hash_map<const CallInst*, hash_set<CallInst*> > spawnToSyncsMap;
-
-  // Input data for the transformation.
-  const hash_set<Function*>*    cilkFunctions;   // Set of parallel functions
-  PgmDependenceGraph*           depGraph;
-
-  void          DFSVisitInstr   (Instruction* I,
-                                 Instruction* root,
-                                 hash_set<const Instruction*>& depsOfRoot);
-
-public:
-  /*ctor*/      Cilkifier       (Module& M);
-
-  // Transform a single function including its name, its call sites, and syncs
-  // 
-  void          TransformFunc   (Function* F,
-                                 const hash_set<Function*>& cilkFunctions,
-                                 PgmDependenceGraph&  _depGraph);
-
-  // The visitor function that does most of the hard work, via DFSVisitInstr
-  // 
-  void visitCallInst(CallInst& CI);
-};
-
-
-Cilkifier::Cilkifier(Module& M)
-{
-  // create the dummy Sync function and add it to the Module
-  DummySyncFunc = new Function(FunctionType::get( Type::VoidTy,
-                                                 std::vector<const Type*>(),
-                                                 /*isVararg*/ false),
-                               GlobalValue::ExternalLinkage, DummySyncFuncName,
-                               &M);
-}
-
-void Cilkifier::TransformFunc(Function* F,
-                              const hash_set<Function*>& _cilkFunctions,
-                              PgmDependenceGraph& _depGraph)
-{
-  // Memoize the information for this function
-  cilkFunctions = &_cilkFunctions;
-  depGraph = &_depGraph;
-
-  // Add the marker suffix to the Function name
-  // This should automatically mark all calls to the function also!
-  F->setName(F->getName() + CilkSuffix);
-
-  // Insert sync operations for each separate spawn
-  visit(*F);
-
-  // Now traverse the CFG in rPostorder and eliminate redundant syncs, i.e.,
-  // two consecutive sync's on a straight-line path with no intervening spawn.
-  
-}
-
-
-void Cilkifier::DFSVisitInstr(Instruction* I,
-                              Instruction* root,
-                              hash_set<const Instruction*>& depsOfRoot)
-{
-  assert(stmtsVisited.find(I) == stmtsVisited.end());
-  stmtsVisited.insert(I);
-
-  // If there is a dependence from root to I, insert Sync and return
-  if (depsOfRoot.find(I) != depsOfRoot.end())
-    { // Insert a sync before I and stop searching along this path.
-      // If I is a Phi instruction, the dependence can only be an SSA dep.
-      // and we need to insert the sync in the predecessor on the appropriate
-      // incoming edge!
-      CallInst* syncI = 0;
-      if (PHINode* phiI = dyn_cast<PHINode>(I))
-        { // check all operands of the Phi and insert before each one
-          for (unsigned i = 0, N = phiI->getNumIncomingValues(); i < N; ++i)
-            if (phiI->getIncomingValue(i) == root)
-              syncI = new CallInst(DummySyncFunc, std::vector<Value*>(), "",
-                                   phiI->getIncomingBlock(i)->getTerminator());
-        }
-      else
-        syncI = new CallInst(DummySyncFunc, std::vector<Value*>(), "", I);
-
-      // Remember the sync for each spawn to eliminate rendundant ones later
-      spawnToSyncsMap[cast<CallInst>(root)].insert(syncI);
-
-      return;
-    }
-
-  // else visit unvisited successors
-  if (BranchInst* brI = dyn_cast<BranchInst>(I))
-    { // visit first instruction in each successor BB
-      for (unsigned i = 0, N = brI->getNumSuccessors(); i < N; ++i)
-        if (stmtsVisited.find(&brI->getSuccessor(i)->front())
-            == stmtsVisited.end())
-          DFSVisitInstr(&brI->getSuccessor(i)->front(), root, depsOfRoot);
-    }
-  else
-    if (Instruction* nextI = I->getNext())
-      if (stmtsVisited.find(nextI) == stmtsVisited.end())
-        DFSVisitInstr(nextI, root, depsOfRoot);
-}
-
-
-void Cilkifier::visitCallInst(CallInst& CI)
-{
-  assert(CI.getCalledFunction() != 0 && "Only direct calls can be spawned.");
-  if (cilkFunctions->find(CI.getCalledFunction()) == cilkFunctions->end())
-    return;                             // not a spawn
-
-  // Find all the outgoing memory dependences.
-  hash_set<const Instruction*> depsOfRoot;
-  for (PgmDependenceGraph::iterator DI =
-         depGraph->outDepBegin(CI, MemoryDeps); ! DI.fini(); ++DI)
-    depsOfRoot.insert(&DI->getSink()->getInstr());
-
-  // Now find all outgoing SSA dependences to the eventual non-Phi users of
-  // the call value (i.e., direct users that are not phis, and for any
-  // user that is a Phi, direct non-Phi users of that Phi, and recursively).
-  std::stack<const PHINode*> phiUsers;
-  hash_set<const PHINode*> phisSeen;    // ensures we don't visit a phi twice
-  for (Value::use_iterator UI=CI.use_begin(), UE=CI.use_end(); UI != UE; ++UI)
-    if (const PHINode* phiUser = dyn_cast<PHINode>(*UI))
-      {
-        if (phisSeen.find(phiUser) == phisSeen.end())
-          {
-            phiUsers.push(phiUser);
-            phisSeen.insert(phiUser);
-          }
-      }
-    else
-      depsOfRoot.insert(cast<Instruction>(*UI));
-
-  // Now we've found the non-Phi users and immediate phi users.
-  // Recursively walk the phi users and add their non-phi users.
-  for (const PHINode* phiUser; !phiUsers.empty(); phiUsers.pop())
-    {
-      phiUser = phiUsers.top();
-      for (Value::use_const_iterator UI=phiUser->use_begin(),
-             UE=phiUser->use_end(); UI != UE; ++UI)
-        if (const PHINode* pn = dyn_cast<PHINode>(*UI))
-          {
-            if (phisSeen.find(pn) == phisSeen.end())
-              {
-                phiUsers.push(pn);
-                phisSeen.insert(pn);
-              }
-          }
-        else
-          depsOfRoot.insert(cast<Instruction>(*UI));
-    }
-
-  // Walk paths of the CFG starting at the call instruction and insert
-  // one sync before the first dependence on each path, if any.
-  if (! depsOfRoot.empty())
-    {
-      stmtsVisited.clear();             // start a new DFS for this CallInst
-      assert(CI.getNext() && "Call instruction cannot be a terminator!");
-      DFSVisitInstr(CI.getNext(), &CI, depsOfRoot);
-    }
-
-  // Now, eliminate all users of the SSA value of the CallInst, i.e., 
-  // if the call instruction returns a value, delete the return value
-  // register and replace it by a stack slot.
-  if (CI.getType() != Type::VoidTy)
-    DemoteRegToStack(CI);
-}
-
-
-//---------------------------------------------------------------------------- 
-// class FindParallelCalls
-//
-// Find all CallInst instructions that have at least one other CallInst
-// that is independent.  These are the instructions that can produce
-// useful parallelism.
-//---------------------------------------------------------------------------- 
-
-class FindParallelCalls : public InstVisitor<FindParallelCalls> {
-  typedef hash_set<CallInst*>           DependentsSet;
-  typedef DependentsSet::iterator       Dependents_iterator;
-  typedef DependentsSet::const_iterator Dependents_const_iterator;
-
-  PgmDependenceGraph& depGraph;         // dependence graph for the function
-  hash_set<Instruction*> stmtsVisited;  // flags for DFS walk of depGraph
-  hash_map<CallInst*, bool > completed; // flags marking if a CI is done
-  hash_map<CallInst*, DependentsSet> dependents; // dependent CIs for each CI
-
-  void VisitOutEdges(Instruction*   I,
-                     CallInst*      root,
-                     DependentsSet& depsOfRoot);
-
-  FindParallelCalls(const FindParallelCalls &); // DO NOT IMPLEMENT
-  void operator=(const FindParallelCalls&);     // DO NOT IMPLEMENT
-public:
-  std::vector<CallInst*> parallelCalls;
-
-public:
-  /*ctor*/      FindParallelCalls       (Function& F, PgmDependenceGraph& DG);
-  void          visitCallInst           (CallInst& CI);
-};
-
-
-FindParallelCalls::FindParallelCalls(Function& F,
-                                     PgmDependenceGraph& DG)
-  : depGraph(DG)
-{
-  // Find all CallInsts reachable from each CallInst using a recursive DFS
-  visit(F);
-
-  // Now we've found all CallInsts reachable from each CallInst.
-  // Find those CallInsts that are parallel with at least one other CallInst
-  // by counting total inEdges and outEdges.
-  // 
-  unsigned long totalNumCalls = completed.size();
-
-  if (totalNumCalls == 1)
-    { // Check first for the special case of a single call instruction not
-      // in any loop.  It is not parallel, even if it has no dependences
-      // (this is why it is a special case).
-      //
-      // FIXME:
-      // THIS CASE IS NOT HANDLED RIGHT NOW, I.E., THERE IS NO
-      // PARALLELISM FOR CALLS IN DIFFERENT ITERATIONS OF A LOOP.
-      // 
-      return;
-    }
-
-  hash_map<CallInst*, unsigned long> numDeps;
-  for (hash_map<CallInst*, DependentsSet>::iterator II = dependents.begin(),
-         IE = dependents.end(); II != IE; ++II)
-    {
-      CallInst* fromCI = II->first;
-      numDeps[fromCI] += II->second.size();
-      for (Dependents_iterator DI = II->second.begin(), DE = II->second.end();
-           DI != DE; ++DI)
-        numDeps[*DI]++;                 // *DI can be reached from II->first
-    }
-
-  for (hash_map<CallInst*, DependentsSet>::iterator
-         II = dependents.begin(), IE = dependents.end(); II != IE; ++II)
-
-    // FIXME: Remove "- 1" when considering parallelism in loops
-    if (numDeps[II->first] < totalNumCalls - 1)
-      parallelCalls.push_back(II->first);
-}
-
-
-void FindParallelCalls::VisitOutEdges(Instruction* I,
-                                      CallInst* root,
-                                      DependentsSet& depsOfRoot)
-{
-  assert(stmtsVisited.find(I) == stmtsVisited.end() && "Stmt visited twice?");
-  stmtsVisited.insert(I);
-
-  if (CallInst* CI = dyn_cast<CallInst>(I))
-
-    // FIXME: Ignoring parallelism in a loop.  Here we're actually *ignoring*
-    // a self-dependence in order to get the count comparison right above.
-    // When we include loop parallelism, self-dependences should be included.
-    // 
-    if (CI != root)
-
-      { // CallInst root has a path to CallInst I and any calls reachable from I
-        depsOfRoot.insert(CI);
-        if (completed[CI])
-          { // We have already visited I so we know all nodes it can reach!
-            DependentsSet& depsOfI = dependents[CI];
-            depsOfRoot.insert(depsOfI.begin(), depsOfI.end());
-            return;
-          }
-      }
-
-  // If we reach here, we need to visit all children of I
-  for (PgmDependenceGraph::iterator DI = depGraph.outDepBegin(*I);
-       ! DI.fini(); ++DI)
-    {
-      Instruction* sink = &DI->getSink()->getInstr();
-      if (stmtsVisited.find(sink) == stmtsVisited.end())
-        VisitOutEdges(sink, root, depsOfRoot);
-    }
-}
-
-
-void FindParallelCalls::visitCallInst(CallInst& CI)
-{
-  if (completed[&CI])
-    return;
-  stmtsVisited.clear();                      // clear flags to do a fresh DFS
-
-  // Visit all children of CI using a recursive walk through dep graph
-  DependentsSet& depsOfRoot = dependents[&CI];
-  for (PgmDependenceGraph::iterator DI = depGraph.outDepBegin(CI);
-       ! DI.fini(); ++DI)
-    {
-      Instruction* sink = &DI->getSink()->getInstr();
-      if (stmtsVisited.find(sink) == stmtsVisited.end())
-        VisitOutEdges(sink, &CI, depsOfRoot);
-    }
-
-  completed[&CI] = true;
-}
-
-
-//---------------------------------------------------------------------------- 
-// class Parallelize
-//
-// (1) Find candidate parallel functions: any function F s.t.
-//       there is a call C1 to the function F that is followed or preceded
-//       by at least one other call C2 that is independent of this one
-//       (i.e., there is no dependence path from C1 to C2 or C2 to C1)
-// (2) Label such a function F as a cilk function.
-// (3) Convert every call to F to a spawn
-// (4) For every function X, insert sync statements so that
-//        every spawn is postdominated by a sync before any statements
-//        with a data dependence to/from the call site for the spawn
-// 
-//---------------------------------------------------------------------------- 
-
-namespace {
-  class Parallelize: public Pass
-  {
-  public:
-    /// Driver functions to transform a program
-    ///
-    bool run(Module& M);
-
-    /// getAnalysisUsage - Modifies extensively so preserve nothing.
-    /// Uses the DependenceGraph and the Top-down DS Graph (only to find
-    /// all functions called via an indirect call).
-    ///
-    void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.addRequired<TDDataStructures>();
-      AU.addRequired<MemoryDepAnalysis>();  // force this not to be released
-      AU.addRequired<PgmDependenceGraph>(); // because it is needed by this
-    }
-  };
-
-  RegisterOpt<Parallelize> X("parallel", "Parallelize program using Cilk");
-}
-
-
-static Function* FindMain(Module& M)
-{
-  for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
-    if (FI->getName() == std::string("main"))
-      return FI;
-  return NULL;
-}
-
-
-bool Parallelize::run(Module& M)
-{
-  hash_set<Function*> parallelFunctions;
-  hash_set<Function*> safeParallelFunctions;
-  hash_set<const GlobalValue*> indirectlyCalled;
-
-  // If there is no main (i.e., for an incomplete program), we can do nothing.
-  // If there is a main, mark main as a parallel function.
-  // 
-  Function* mainFunc = FindMain(M);
-  if (!mainFunc)
-    return false;
-
-  // (1) Find candidate parallel functions and mark them as Cilk functions
-  // 
-  for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
-    if (! FI->isExternal())
-      {
-        Function* F = FI;
-        DSGraph& tdg = getAnalysis<TDDataStructures>().getDSGraph(*F);
-
-        // All the hard analysis work gets done here!
-        // 
-        FindParallelCalls finder(*F,
-                                getAnalysis<PgmDependenceGraph>().getGraph(*F));
-                        /* getAnalysis<MemoryDepAnalysis>().getGraph(*F)); */
-
-        // Now we know which call instructions are useful to parallelize.
-        // Remember those callee functions.
-        // 
-        for (std::vector<CallInst*>::iterator
-               CII = finder.parallelCalls.begin(),
-               CIE = finder.parallelCalls.end(); CII != CIE; ++CII)
-          {
-            // Check if this is a direct call...
-            if ((*CII)->getCalledFunction() != NULL)
-              { // direct call: if this is to a non-external function,
-                // mark it as a parallelizable function
-                if (! (*CII)->getCalledFunction()->isExternal())
-                  parallelFunctions.insert((*CII)->getCalledFunction());
-              }
-            else
-              { // Indirect call: mark all potential callees as bad
-                std::vector<GlobalValue*> callees =
-                  tdg.getNodeForValue((*CII)->getCalledValue())
-                  .getNode()->getGlobals();
-                indirectlyCalled.insert(callees.begin(), callees.end());
-              }
-          }
-      }
-
-  // Remove all indirectly called functions from the list of Cilk functions.
-  // 
-  for (hash_set<Function*>::iterator PFI = parallelFunctions.begin(),
-         PFE = parallelFunctions.end(); PFI != PFE; ++PFI)
-    if (indirectlyCalled.count(*PFI) == 0)
-      safeParallelFunctions.insert(*PFI);
-
-#undef CAN_USE_BIND1ST_ON_REFERENCE_TYPE_ARGS
-#ifdef CAN_USE_BIND1ST_ON_REFERENCE_TYPE_ARGS
-  // Use this undecipherable STLese because erase invalidates iterators.
-  // Otherwise we have to copy sets as above.
-  hash_set<Function*>::iterator extrasBegin = 
-    std::remove_if(parallelFunctions.begin(), parallelFunctions.end(),
-                   compose1(std::bind2nd(std::greater<int>(), 0),
-                            bind_obj(&indirectlyCalled,
-                                     &hash_set<const GlobalValue*>::count)));
-  parallelFunctions.erase(extrasBegin, parallelFunctions.end());
-#endif
-
-  // If there are no parallel functions, we can just give up.
-  if (safeParallelFunctions.empty())
-    return false;
-
-  // Add main as a parallel function since Cilk requires this.
-  safeParallelFunctions.insert(mainFunc);
-
-  // (2,3) Transform each Cilk function and all its calls simply by
-  //     adding a unique suffix to the function name.
-  //     This should identify both functions and calls to such functions
-  //     to the code generator.
-  // (4) Also, insert calls to sync at appropriate points.
-  // 
-  Cilkifier cilkifier(M);
-  for (hash_set<Function*>::iterator CFI = safeParallelFunctions.begin(),
-         CFE = safeParallelFunctions.end(); CFI != CFE; ++CFI)
-    {
-      cilkifier.TransformFunc(*CFI, safeParallelFunctions,
-                             getAnalysis<PgmDependenceGraph>().getGraph(**CFI));
-      /* getAnalysis<MemoryDepAnalysis>().getGraph(**CFI)); */
-    }
-
-  return true;
-}
diff --git a/poolalloc/lib/DSA/PgmDependenceGraph.cpp b/poolalloc/lib/DSA/PgmDependenceGraph.cpp
deleted file mode 100644
index 705a944..0000000
--- a/poolalloc/lib/DSA/PgmDependenceGraph.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-//===- PgmDependenceGraph.cpp - Enumerate PDG for a function ----*- C++ -*-===//
-// 
-// The Program Dependence Graph (PDG) for a single function represents all
-// data and control dependences for the function.  This file provides an
-// iterator to enumerate all these dependences.  In particular, it enumerates:
-// 
-// -- Data dependences on memory locations, computed using the
-//    MemoryDepAnalysis pass;
-// -- Data dependences on SSA registers, directly from Def-Use edges of Values;
-// -- Control dependences, computed using postdominance frontiers
-//    (NOT YET IMPLEMENTED).
-// 
-// Note that this file does not create an explicit dependence graph --
-// it only provides an iterator to traverse the PDG conceptually.
-// The MemoryDepAnalysis does build an explicit graph, which is used internally
-// here.  That graph could be augmented with the other dependences above if
-// desired, but for most uses there will be little need to do that.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/PgmDependenceGraph.h"
-#include "llvm/Analysis/MemoryDepAnalysis.h"
-#include "llvm/Analysis/PostDominators.h"
-#include "llvm/Function.h"
-
-
-//----------------------------------------------------------------------------
-// class DepIterState
-//----------------------------------------------------------------------------
-
-const DepIterState::IterStateFlags DepIterState::NoFlag  = 0x0;
-const DepIterState::IterStateFlags DepIterState::MemDone = 0x1;
-const DepIterState::IterStateFlags DepIterState::SSADone = 0x2;
-const DepIterState::IterStateFlags DepIterState::AllDone = 0x4;
-const DepIterState::IterStateFlags DepIterState::FirstTimeFlag= 0x8;
-
-// Find the first memory dependence for the current Mem In/Out iterators.
-// Find the first memory dependence for the current Mem In/Out iterators.
-// Sets dep to that dependence and returns true if one is found.
-// 
-bool DepIterState::SetFirstMemoryDep()
-{
-  if (! (depFlags & MemoryDeps))
-    return false;
-
-  bool doIncomingDeps = dep.getDepType() & IncomingFlag;
-
-  if (( doIncomingDeps && memDepIter == memDepGraph->inDepEnd( *depNode)) ||
-      (!doIncomingDeps && memDepIter == memDepGraph->outDepEnd(*depNode)))
-    {
-      iterFlags |= MemDone;
-      return false;
-    }
-
-  dep = *memDepIter;     // simple copy from dependence in memory DepGraph
-
-  return true;
-}
-
-
-// Find the first valid data dependence for the current SSA In/Out iterators.
-// A valid data dependence is one that is to/from an Instruction.
-// E.g., an SSA edge from a formal parameter is not a valid dependence.
-// Sets dep to that dependence and returns true if a valid one is found.
-// Returns false and leaves dep unchanged otherwise.
-// 
-bool DepIterState::SetFirstSSADep()
-{
-  if (! (depFlags & SSADeps))
-    return false;
-
-  bool doIncomingDeps = dep.getDepType() & IncomingFlag;
-  Instruction* firstTarget = NULL;
-
-  // Increment the In or Out iterator till it runs out or we find a valid dep
-  if (doIncomingDeps)
-    for (Instruction::op_iterator E = depNode->getInstr().op_end();
-         ssaInEdgeIter != E &&
-           (firstTarget = dyn_cast<Instruction>(ssaInEdgeIter))== NULL; )
-      ++ssaInEdgeIter;
-  else
-    for (Value::use_iterator E = depNode->getInstr().use_end();
-         ssaOutEdgeIter != E &&
-           (firstTarget = dyn_cast<Instruction>(*ssaOutEdgeIter)) == NULL; )
-      ++ssaOutEdgeIter;
-
-  // If the iterator ran out before we found a valid dep, there isn't one.
-  if (!firstTarget)
-    {
-      iterFlags |= SSADone;
-      return false;
-    }
-
-  // Create a simple dependence object to represent this SSA dependence.
-  dep = Dependence(memDepGraph->getNode(*firstTarget, /*create*/ true),
-                   TrueDependence, doIncomingDeps);
-
-  return true;
-}
-
-
-DepIterState::DepIterState(DependenceGraph* _memDepGraph,
-                           Instruction&     I, 
-                           bool             incomingDeps,
-                           PDGIteratorFlags whichDeps)
-  : memDepGraph(_memDepGraph),
-    depFlags(whichDeps),
-    iterFlags(NoFlag)
-{
-  depNode = memDepGraph->getNode(I, /*create*/ true);
-
-  if (incomingDeps)
-    {
-      if (whichDeps & MemoryDeps) memDepIter= memDepGraph->inDepBegin(*depNode);
-      if (whichDeps & SSADeps)    ssaInEdgeIter = I.op_begin();
-      /* Initialize control dependence iterator here. */
-    }
-  else
-    {
-      if (whichDeps & MemoryDeps) memDepIter=memDepGraph->outDepBegin(*depNode);
-      if (whichDeps & SSADeps)    ssaOutEdgeIter = I.use_begin();
-      /* Initialize control dependence iterator here. */
-    }
-
-  // Set the dependence to the first of a memory dep or an SSA dep
-  // and set the done flag if either is found.  Otherwise, set the
-  // init flag to indicate that the iterators have just been initialized.
-  // 
-  if (!SetFirstMemoryDep() && !SetFirstSSADep())
-    iterFlags |= AllDone;
-  else
-    iterFlags |= FirstTimeFlag;
-}
-
-
-// Helper function for ++ operator that bumps iterator by 1 (to next
-// dependence) and resets the dep field to represent the new dependence.
-// 
-void DepIterState::Next()
-{
-  // firstMemDone and firstSsaDone are used to indicate when the memory or
-  // SSA iterators just ran out, or when this is the very first increment.
-  // In either case, the next iterator (if any) should not be incremented.
-  // 
-  bool firstMemDone = iterFlags & FirstTimeFlag;
-  bool firstSsaDone = iterFlags & FirstTimeFlag;
-  bool doIncomingDeps = dep.getDepType() & IncomingFlag;
-
-  if (depFlags & MemoryDeps && ! (iterFlags & MemDone))
-    {
-      iterFlags &= ~FirstTimeFlag;           // clear "firstTime" flag
-      ++memDepIter;
-      if (SetFirstMemoryDep())
-        return;
-      firstMemDone = true;              // flags that we _just_ rolled over
-    }
-
-  if (depFlags & SSADeps && ! (iterFlags & SSADone))
-    {
-      // Don't increment the SSA iterator if we either just rolled over from
-      // the memory dep iterator, or if the SSA iterator is already done.
-      iterFlags &= ~FirstTimeFlag;           // clear "firstTime" flag
-      if (! firstMemDone)
-        if (doIncomingDeps) ++ssaInEdgeIter;
-        else ++ssaOutEdgeIter;
-      if (SetFirstSSADep())
-        return;
-      firstSsaDone = true;                   // flags if we just rolled over
-    } 
-
-  if (depFlags & ControlDeps != 0)
-    {
-      assert(0 && "Cannot handle control deps");
-      // iterFlags &= ~FirstTimeFlag;           // clear "firstTime" flag
-    }
-
-  // This iterator is now complete.
-  iterFlags |= AllDone;
-}
-
-
-//----------------------------------------------------------------------------
-// class PgmDependenceGraph
-//----------------------------------------------------------------------------
-
-
-// MakeIterator -- Create and initialize an iterator as specified.
-// 
-PDGIterator PgmDependenceGraph::MakeIterator(Instruction& I,
-                                             bool incomingDeps,
-                                             PDGIteratorFlags whichDeps)
-{
-  assert(memDepGraph && "Function not initialized!");
-  return PDGIterator(new DepIterState(memDepGraph, I, incomingDeps, whichDeps));
-}
-
-
-void PgmDependenceGraph::printOutgoingSSADeps(Instruction& I,
-                                              std::ostream &O)
-{
-  iterator SI = this->outDepBegin(I, SSADeps);
-  iterator SE = this->outDepEnd(I, SSADeps);
-  if (SI == SE)
-    return;
-
-  O << "\n    Outgoing SSA dependences:\n";
-  for ( ; SI != SE; ++SI)
-    {
-      O << "\t";
-      SI->print(O);
-      O << " to instruction:";
-      O << SI->getSink()->getInstr();
-    }
-}
-
-
-void PgmDependenceGraph::print(std::ostream &O) const
-{
-  MemoryDepAnalysis& graphSet = getAnalysis<MemoryDepAnalysis>();
-
-  // TEMPORARY LOOP
-  for (hash_map<Function*, DependenceGraph*>::iterator
-         I = graphSet.funcMap.begin(), E = graphSet.funcMap.end();
-       I != E; ++I)
-    {
-      Function* func = I->first;
-      DependenceGraph* depGraph = I->second;
-      const_cast<PgmDependenceGraph*>(this)->runOnFunction(*func);
-
-  O << "DEPENDENCE GRAPH FOR FUNCTION " << func->getName() << ":\n";
-  for (Function::iterator BB=func->begin(), FE=func->end(); BB != FE; ++BB)
-    for (BasicBlock::iterator II=BB->begin(), IE=BB->end(); II !=IE; ++II)
-      {
-        DepGraphNode* dgNode = depGraph->getNode(*II, /*create*/ true);
-        dgNode->print(O);
-        const_cast<PgmDependenceGraph*>(this)->printOutgoingSSADeps(*II, O);
-      }
-    } // END TEMPORARY LOOP
-}
-
-
-void PgmDependenceGraph::dump() const
-{
-  this->print(std::cerr);
-}
-
-static RegisterAnalysis<PgmDependenceGraph>
-Z("pgmdep", "Enumerate Program Dependence Graph (data and control)");
diff --git a/poolalloc/lib/DSA/Printer.cpp b/poolalloc/lib/DSA/Printer.cpp
deleted file mode 100644
index 87fc1f7..0000000
--- a/poolalloc/lib/DSA/Printer.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-//===- Printer.cpp - Code for printing data structure graphs nicely -------===//
-//
-// This file implements the 'dot' graph printer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Analysis/DSGraphTraits.h"
-#include "llvm/Module.h"
-#include "llvm/Constants.h"
-#include "llvm/Assembly/Writer.h"
-#include "Support/CommandLine.h"
-#include "Support/GraphWriter.h"
-#include "Support/Statistic.h"
-#include <fstream>
-#include <sstream>
-
-// 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);
-  Statistic<> MaxGraphSize   ("dsnode", "Maximum graph size");
-  Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)");
-}
-
-
-void DSNode::dump() const { print(std::cerr, 0); }
-
-static std::string getCaption(const DSNode *N, const DSGraph *G) {
-  std::stringstream OS;
-  Module *M = 0;
-  // Get the module from ONE of the functions in the graph it is available.
-  if (G && !G->getReturnNodes().empty())
-    M = G->getReturnNodes().begin()->first->getParent();
-
-  if (N->isNodeCompletelyFolded())
-    OS << "COLLAPSED";
-  else {
-    WriteTypeSymbolic(OS, N->getType(), M);
-    if (N->isArray())
-      OS << " array";
-  }
-  if (unsigned NodeType = N->getNodeFlags()) {
-    OS << ": ";
-    if (NodeType & DSNode::AllocaNode ) OS << "S";
-    if (NodeType & DSNode::HeapNode   ) OS << "H";
-    if (NodeType & DSNode::GlobalNode ) OS << "G";
-    if (NodeType & DSNode::UnknownNode) OS << "U";
-    if (NodeType & DSNode::Incomplete ) OS << "I";
-    if (NodeType & DSNode::Modified   ) OS << "M";
-    if (NodeType & DSNode::Read       ) OS << "R";
-#ifndef NDEBUG
-    if (NodeType & DSNode::DEAD       ) OS << "<dead>";
-#endif
-    OS << "\n";
-  }
-
-  for (unsigned i = 0, e = N->getGlobals().size(); i != e; ++i) {
-    WriteAsOperand(OS, N->getGlobals()[i], false, true, M);
-    OS << "\n";
-  }
-
-  return OS.str();
-}
-
-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 const char *getGraphProperties(const DSGraph *G) {
-    return "\tsize=\"10,7.5\";\n"
-           "\trotate=\"90\";\n";
-  }
-
-  static std::string getNodeLabel(const DSNode *Node, const DSGraph *Graph) {
-    return getCaption(Node, Graph);
-  }
-
-  static std::string getNodeAttributes(const DSNode *N) {
-    return "shape=Mrecord";//fontname=Courier";
-  }
-  
-  /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
-  /// and the return node.
-  ///
-  static void addCustomGraphFeatures(const DSGraph *G,
-                                     GraphWriter<const DSGraph*> &GW) {
-    Module *CurMod = 0;
-    if (!G->getReturnNodes().empty())
-      CurMod = G->getReturnNodes().begin()->first->getParent();
-
-    // 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) && !isa<ConstantPointerRef>(I->first)) {
-        std::stringstream OS;
-        WriteAsOperand(OS, I->first, false, true, CurMod);
-        GW.emitSimpleNode(I->first, "", OS.str());
-        
-        // Add edge from return node to real destination
-        int EdgeDest = I->second.getOffset() >> DS::PointerShift;
-        if (EdgeDest == 0) EdgeDest = -1;
-        GW.emitEdge(I->first, -1, I->second.getNode(),
-                    EdgeDest, "arrowtail=tee,color=gray63");
-      }
-
-
-    // Output the returned value pointer...
-    const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
-    for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
-           E = RetNodes.end(); I != E; ++I)
-      if (I->second.getNode()) {
-        std::string Label;
-        if (RetNodes.size() == 1)
-          Label = "returning";
-        else
-          Label = I->first->getName() + " ret node";
-        // Output the return node...
-        GW.emitSimpleNode((void*)1, "plaintext=circle", Label);
-
-        // Add edge from return node to real destination
-        int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
-        if (RetEdgeDest == 0) RetEdgeDest = -1;
-        GW.emitEdge((void*)1, -1, I->second.getNode(),
-                    RetEdgeDest, "arrowtail=tee,color=gray63");
-      }
-
-    // Output all of the call nodes...
-    const std::vector<DSCallSite> &FCs =
-      G->shouldPrintAuxCalls() ? G->getAuxFunctionCalls()
-      : G->getFunctionCalls();
-    for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
-      const DSCallSite &Call = FCs[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() >> DS::PointerShift;
-        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() >> DS::PointerShift;
-          if (EdgeDest == 0) EdgeDest = -1;
-          GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false");
-        }
-    }
-  }
-};
-
-void DSNode::print(std::ostream &O, const DSGraph *G) const {
-  GraphWriter<const DSGraph *> W(O, G);
-  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 = shouldPrintAuxCalls() ?
-      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 {
-  std::ofstream F("/tmp/tempgraph.dot");
-  if (!F.good()) {
-    std::cerr << "Error opening '/tmp/tempgraph.dot' for temporary graph!\n";
-    return;
-  }
-  print(F);
-  F.close();
-  if (system("dot -Tps /tmp/tempgraph.dot > /tmp/tempgraph.ps"))
-    std::cerr << "Error running dot: 'dot' not in path?\n";
-  system("gv /tmp/tempgraph.ps");
-  system("rm /tmp/tempgraph.dot /tmp/tempgraph.ps");
-}
-
-
-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.hasGraph(*I)) {
-      DSGraph &Gr = C.getDSGraph((Function&)*I);
-      TotalNumNodes += Gr.getGraphSize();
-      unsigned NumCalls = Gr.shouldPrintAuxCalls() ?
-        Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size();
-
-      TotalCallNodes += NumCalls;
-      if (I->getName() == "main" || !OnlyPrintMain)
-        Gr.writeGraphToFile(O, Prefix+I->getName());
-      else {
-        O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
-          << Gr.getGraphSize() << "+" << NumCalls << "]\n";
-      }
-
-      if (MaxGraphSize < Gr.getNodes().size())
-        MaxGraphSize = Gr.getNodes().size();
-      for (unsigned i = 0, e = Gr.getNodes().size(); i != e; ++i)
-        if (Gr.getNodes()[i]->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 LocalDataStructures::print(std::ostream &O, const Module *M) const {
-  printCollection(*this, O, M, "ds.");
-}
-
-void BUDataStructures::print(std::ostream &O, const Module *M) const {
-  printCollection(*this, O, M, "bu.");
-}
-
-void TDDataStructures::print(std::ostream &O, const Module *M) const {
-  printCollection(*this, O, M, "td.");
-}
diff --git a/poolalloc/lib/DSA/Steensgaard.cpp b/poolalloc/lib/DSA/Steensgaard.cpp
deleted file mode 100644
index a3034dd..0000000
--- a/poolalloc/lib/DSA/Steensgaard.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-//===- Steensgaard.cpp - Context Insensitive Alias Analysis ---------------===//
-//
-// 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 "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Module.h"
-#include "Support/Debug.h"
-
-namespace {
-  class Steens : public Pass, public AliasAnalysis {
-    DSGraph *ResultGraph;
-    DSGraph *GlobalsGraph;  // FIXME: Eliminate globals graph stuff from DNE
-  public:
-    Steens() : ResultGraph(0), GlobalsGraph(0) {}
-    ~Steens() {
-      releaseMyMemory();
-      assert(ResultGraph == 0 && "releaseMemory not called?");
-    }
-
-    //------------------------------------------------
-    // Implement the Pass API
-    //
-
-    // run - Build up the result graph, representing the pointer graph for the
-    // program.
-    //
-    bool run(Module &M);
-
-    virtual void releaseMyMemory() { delete ResultGraph; ResultGraph = 0; }
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AliasAnalysis::getAnalysisUsage(AU);
-      AU.setPreservesAll();                    // Does not transform code...
-      AU.addRequired<LocalDataStructures>();   // Uses local dsgraph
-      AU.addRequired<AliasAnalysis>();         // Chains to another AA impl...
-    }
-
-    // print - Implement the Pass::print method...
-    void print(std::ostream &O, const Module *M) const {
-      assert(ResultGraph && "Result graph has not yet been computed!");
-      ResultGraph->writeGraphToFile(O, "steensgaards");
-    }
-
-    //------------------------------------------------
-    // Implement the AliasAnalysis API
-    //  
-
-    // alias - This is the only method here that does anything interesting...
-    AliasResult alias(const Value *V1, unsigned V1Size,
-                      const Value *V2, unsigned V2Size);
-    
-  private:
-    void ResolveFunctionCall(Function *F, const DSCallSite &Call,
-                             DSNodeHandle &RetVal);
-  };
-
-  // Register the pass...
-  RegisterOpt<Steens> X("steens-aa",
-                        "Steensgaard's alias analysis (DSGraph based)");
-
-  // Register as an implementation of AliasAnalysis
-  RegisterAnalysisGroup<AliasAnalysis, Steens> Y;
-}
-
-
-/// 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 Steens::ResolveFunctionCall(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::aiterator AI = F->abegin(), AE = F->aend();
-       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++));
-  }
-}
-
-
-/// run - Build up the result graph, representing the pointer graph for the
-/// program.
-///
-bool Steens::run(Module &M) {
-  InitializeAliasAnalysis(this);
-  assert(ResultGraph == 0 && "Result graph already allocated!");
-  LocalDataStructures &LDS = getAnalysis<LocalDataStructures>();
-
-  // Create a new, empty, graph...
-  ResultGraph = new DSGraph();
-  GlobalsGraph = new DSGraph();
-  ResultGraph->setGlobalsGraph(GlobalsGraph);
-  ResultGraph->setPrintAuxCalls();
-
-  // RetValMap - Keep track of the return values for all functions that return
-  // valid pointers.
-  //
-  DSGraph::ReturnNodesTy RetValMap;
-
-  // Loop over the rest of the module, merging graphs for non-external functions
-  // into this graph.
-  //
-  unsigned Count = 0;
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isExternal()) {
-      DSGraph::ScalarMapTy ValMap;
-      {  // Scope to free NodeMap memory ASAP
-        DSGraph::NodeMapTy NodeMap;
-        const DSGraph &FDSG = LDS.getDSGraph(*I);
-        ResultGraph->cloneInto(FDSG, ValMap, RetValMap, NodeMap);
-      }
-
-      // Incorporate the inlined Function's ScalarMap into the global
-      // ScalarMap...
-      DSGraph::ScalarMapTy &GVM = ResultGraph->getScalarMap();
-      for (DSGraph::ScalarMapTy::iterator I = ValMap.begin(),
-             E = ValMap.end(); I != E; ++I)
-        GVM[I->first].mergeWith(I->second);
-
-      if ((++Count & 1) == 0)   // Prune nodes out every other time...
-        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...
-  //
-  std::vector<DSCallSite> &Calls =
-    ResultGraph->getAuxFunctionCalls();
-  assert(Calls.empty() && "Aux call list is already in use??");
-
-  // Start with a copy of the original call sites...
-  Calls = ResultGraph->getFunctionCalls();
-
-  for (unsigned i = 0; i != Calls.size(); ) {
-    DSCallSite &CurCall = Calls[i];
-    
-    // Loop over the called functions, eliminating as many as possible...
-    std::vector<GlobalValue*> CallTargets;
-    if (CurCall.isDirectCall())
-      CallTargets.push_back(CurCall.getCalleeFunc());
-    else 
-      CallTargets = CurCall.getCalleeNode()->getGlobals();
-
-    for (unsigned c = 0; c != CallTargets.size(); ) {
-      // If we can eliminate this function call, do so!
-      bool Eliminated = false;
-      if (Function *F = dyn_cast<Function>(CallTargets[c]))
-        if (!F->isExternal()) {
-          ResolveFunctionCall(F, CurCall, RetValMap[F]);
-          Eliminated = true;
-        }
-      if (Eliminated) {
-        CallTargets[c] = CallTargets.back();
-        CallTargets.pop_back();
-      } else
-        ++c;  // Cannot eliminate this call, skip over it...
-    }
-
-    if (CallTargets.empty()) {        // Eliminated all calls?
-      CurCall = Calls.back();         // Remove entry
-      Calls.pop_back();
-    } else
-      ++i;                            // Skip this call site...
-  }
-
-  RetValMap.clear();
-
-  // Update the "incomplete" markers on the nodes, ignoring unknownness due to
-  // incoming arguments...
-  ResultGraph->maskIncompleteMarkers();
-  ResultGraph->markIncompleteNodes(DSGraph::IgnoreFormalArgs);
-
-  // Remove any nodes that are dead after all of the merging we have done...
-  // FIXME: We should be able to disable the globals graph for steens!
-  ResultGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
-
-  DEBUG(print(std::cerr, &M));
-  return false;
-}
-
-// alias - This is the only method here that does anything interesting...
-AliasAnalysis::AliasResult Steens::alias(const Value *V1, unsigned V1Size,
-                                         const Value *V2, unsigned V2Size) {
-  // FIXME: HANDLE Size argument!
-  assert(ResultGraph && "Result graph has not been computed yet!");
-
-  DSGraph::ScalarMapTy &GSM = ResultGraph->getScalarMap();
-
-  DSGraph::ScalarMapTy::iterator I = GSM.find(const_cast<Value*>(V1));
-  if (I != GSM.end() && I->second.getNode()) {
-    DSNodeHandle &V1H = I->second;
-    DSGraph::ScalarMapTy::iterator J=GSM.find(const_cast<Value*>(V2));
-    if (J != GSM.end() && J->second.getNode()) {
-      DSNodeHandle &V2H = J->second;
-      // If the two pointers point to different data structure graph nodes, they
-      // cannot alias!
-      if (V1H.getNode() != V2H.getNode())    // FIXME: Handle incompleteness!
-        return NoAlias;
-
-      // FIXME: If the two pointers point to the same node, and the offsets are
-      // different, and the LinkIndex vector doesn't alias the section, then the
-      // two pointers do not alias.  We need access size information for the two
-      // accesses though!
-      //
-    }
-  }
-
-  // If we cannot determine alias properties based on our graph, fall back on
-  // some other AA implementation.
-  //
-  return getAnalysis<AliasAnalysis>().alias(V1, V1Size, V2, V2Size);
-}
diff --git a/poolalloc/lib/DSA/TopDownClosure.cpp b/poolalloc/lib/DSA/TopDownClosure.cpp
deleted file mode 100644
index 92a03ee..0000000
--- a/poolalloc/lib/DSA/TopDownClosure.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-//===- TopDownClosure.cpp - Compute the top-down interprocedure closure ---===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Module.h"
-#include "llvm/DerivedTypes.h"
-#include "Support/Debug.h"
-#include "Support/Statistic.h"
-#include "DSCallSiteIterator.h"
-
-namespace {
-  RegisterAnalysis<TDDataStructures>   // Register the pass
-  Y("tddatastructure", "Top-down Data Structure Analysis");
-
-  Statistic<> NumTDInlines("tddatastructures", "Number of graphs inlined");
-}
-
-/// FunctionHasCompleteArguments - This function returns true if it is safe not
-/// to mark arguments to the function complete.
-///
-/// FIXME: Need to check if all callers have been found, or rather if a
-/// funcpointer escapes!
-///
-static bool FunctionHasCompleteArguments(Function &F) {
-  return F.hasInternalLinkage();
-}
-
-// run - Calculate the top down data structure graphs for each function in the
-// program.
-//
-bool TDDataStructures::run(Module &M) {
-  BUDataStructures &BU = getAnalysis<BUDataStructures>();
-  GlobalsGraph = new DSGraph(BU.getGlobalsGraph());
-
-  // Figure out which functions must not mark their arguments complete because
-  // they are accessible outside this compilation unit.
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!FunctionHasCompleteArguments(*I))
-      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;
-  const BUDataStructures::ActualCalleesTy &ActualCallees = 
-    getAnalysis<BUDataStructures>().getActualCallees();
-
-  // Calculate top-down from main...
-  if (Function *F = M.getMainFunction())
-    ComputePostOrder(*F, VisitedGraph, PostOrder, ActualCallees);
-
-  // Next calculate the graphs for each unreachable function...
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-    ComputePostOrder(*I, VisitedGraph, PostOrder, ActualCallees);
-
-  VisitedGraph.clear();   // Release memory!
-
-  // Visit each of the graphs in reverse post-order now!
-  while (!PostOrder.empty()) {
-    inlineGraphIntoCallees(*PostOrder.back());
-    PostOrder.pop_back();
-  }
-
-  ArgsRemainIncomplete.clear();
-  return false;
-}
-
-
-DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) {
-  DSGraph *&G = DSInfo[&F];
-  if (G == 0) { // Not created yet?  Clone BU graph...
-    G = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F));
-    G->getAuxFunctionCalls().clear();
-    G->setPrintAuxCalls();
-    G->setGlobalsGraph(GlobalsGraph);
-  }
-  return *G;
-}
-
-
-void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
-                                        std::vector<DSGraph*> &PostOrder,
-                      const BUDataStructures::ActualCalleesTy &ActualCallees) {
-  if (F.isExternal()) return;
-  DSGraph &G = getOrCreateDSGraph(F);
-  if (Visited.count(&G)) return;
-  Visited.insert(&G);
-  
-  // Recursively traverse all of the callee graphs.
-  const std::vector<DSCallSite> &FunctionCalls = G.getFunctionCalls();
-
-  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
-    std::pair<BUDataStructures::ActualCalleesTy::const_iterator,
-      BUDataStructures::ActualCalleesTy::const_iterator>
-         IP = ActualCallees.equal_range(&FunctionCalls[i].getCallInst());
-
-    for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first;
-         I != IP.second; ++I)
-      ComputePostOrder(*I->second, Visited, PostOrder, ActualCallees);
-  }
-
-  PostOrder.push_back(&G);
-}
-
-
-
-
-
-// releaseMemory - If the pass pipeline is done with this pass, we can release
-// our memory... here...
-//
-// FIXME: This should be releaseMemory and will work fine, except that LoadVN
-// has no way to extend the lifetime of the pass, which screws up ds-aa.
-//
-void TDDataStructures::releaseMyMemory() {
-  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
-         E = DSInfo.end(); I != E; ++I) {
-    I->second->getReturnNodes().erase(I->first);
-    if (I->second->getReturnNodes().empty())
-      delete I->second;
-  }
-
-  // Empty map so next time memory is released, data structures are not
-  // re-deleted.
-  DSInfo.clear();
-  delete GlobalsGraph;
-  GlobalsGraph = 0;
-}
-
-void TDDataStructures::inlineGraphIntoCallees(DSGraph &Graph) {
-  // Recompute the Incomplete markers and eliminate unreachable nodes.
-  Graph.removeTriviallyDeadNodes();
-  Graph.maskIncompleteMarkers();
-
-  // If any of the functions has incomplete incoming arguments, don't mark any
-  // of them as complete.
-  bool HasIncompleteArgs = false;
-  const DSGraph::ReturnNodesTy &GraphReturnNodes = Graph.getReturnNodes();
-  for (DSGraph::ReturnNodesTy::const_iterator I = GraphReturnNodes.begin(),
-         E = GraphReturnNodes.end(); I != E; ++I)
-    if (ArgsRemainIncomplete.count(I->first)) {
-      HasIncompleteArgs = true;
-      break;
-    }
-
-  // Now fold in the necessary globals from the GlobalsGraph.  A global G
-  // must be folded in if it exists in the current graph (i.e., is not dead)
-  // and it was not inlined from any of my callers.  If it was inlined from
-  // a caller, it would have been fully consistent with the GlobalsGraph
-  // in the caller so folding in is not necessary.  Otherwise, this node came
-  // solely from this function's BU graph and so has to be made consistent.
-  // 
-  Graph.updateFromGlobalGraph();
-
-  // Recompute the Incomplete markers.  Depends on whether args are complete
-  unsigned Flags
-    = HasIncompleteArgs ? DSGraph::MarkFormalArgs : DSGraph::IgnoreFormalArgs;
-  Graph.markIncompleteNodes(Flags | DSGraph::IgnoreGlobals);
-
-  // Delete dead nodes.  Treat globals that are unreachable as dead also.
-  Graph.removeDeadNodes(DSGraph::RemoveUnreachableGlobals);
-
-  // We are done with computing the current TD Graph! Now move on to
-  // inlining the current graph into the graphs for its callees, if any.
-  // 
-  const std::vector<DSCallSite> &FunctionCalls = Graph.getFunctionCalls();
-  if (FunctionCalls.empty()) {
-    DEBUG(std::cerr << "  [TD] No callees for: " << Graph.getFunctionNames()
-                    << "\n");
-    return;
-  }
-
-  // Now that we have information about all of the callees, propagate the
-  // current graph into the callees.  Clone only the reachable subgraph at
-  // each call-site, not the entire graph (even though the entire graph
-  // would be cloned only once, this should still be better on average).
-  //
-  DEBUG(std::cerr << "  [TD] Inlining '" << Graph.getFunctionNames() <<"' into "
-                  << FunctionCalls.size() << " call nodes.\n");
-
-  const BUDataStructures::ActualCalleesTy &ActualCallees =
-    getAnalysis<BUDataStructures>().getActualCallees();
-
-  // Loop over all the call sites and all the callees at each call site.
-  // Clone and merge the reachable subgraph from the call into callee's graph.
-  // 
-  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
-    // For each function in the invoked function list at this call site...
-    std::pair<BUDataStructures::ActualCalleesTy::const_iterator,
-      BUDataStructures::ActualCalleesTy::const_iterator>
-          IP = ActualCallees.equal_range(&FunctionCalls[i].getCallInst());
-
-    // Multiple callees may have the same graph, so try to inline and merge
-    // only once for each <callSite,calleeGraph> pair, not once for each
-    // <callSite,calleeFunction> pair; the latter will be correct but slower.
-    hash_set<DSGraph*> GraphsSeen;
-
-    // Loop over each actual callee at this call site
-    for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first;
-         I != IP.second; ++I) {
-      DSGraph& CalleeGraph = getDSGraph(*I->second);
-      assert(&CalleeGraph != &Graph && "TD need not inline graph into self!");
-
-      // if this callee graph is already done at this site, skip this callee
-      if (GraphsSeen.find(&CalleeGraph) != GraphsSeen.end())
-        continue;
-      GraphsSeen.insert(&CalleeGraph);
-
-      // Get the root nodes for cloning the reachable subgraph into each callee:
-      // -- all global nodes that appear in both the caller and the callee
-      // -- return value at this call site, if any
-      // -- actual arguments passed at this call site
-      // -- callee node at this call site, if this is an indirect call (this may
-      //    not be needed for merging, but allows us to create CS and therefore
-      //    simplify the merging below).
-      hash_set<const DSNode*> RootNodeSet;
-      for (DSGraph::ScalarMapTy::const_iterator
-             SI = CalleeGraph.getScalarMap().begin(),
-             SE = CalleeGraph.getScalarMap().end(); SI != SE; ++SI)
-        if (GlobalValue* GV = dyn_cast<GlobalValue>(SI->first)) {
-          DSGraph::ScalarMapTy::const_iterator GI=Graph.getScalarMap().find(GV);
-          if (GI != Graph.getScalarMap().end())
-            RootNodeSet.insert(GI->second.getNode());
-        }
-
-      if (const DSNode* RetNode = FunctionCalls[i].getRetVal().getNode())
-        RootNodeSet.insert(RetNode);
-
-      for (unsigned j=0, N=FunctionCalls[i].getNumPtrArgs(); j < N; ++j)
-        if (const DSNode* ArgTarget = FunctionCalls[i].getPtrArg(j).getNode())
-          RootNodeSet.insert(ArgTarget);
-
-      if (FunctionCalls[i].isIndirectCall())
-        RootNodeSet.insert(FunctionCalls[i].getCalleeNode());
-
-      DEBUG(std::cerr << "     [TD] Resolving arguments for callee graph '"
-            << CalleeGraph.getFunctionNames()
-            << "': " << I->second->getFunctionType()->getNumParams()
-            << " args\n          at call site (DSCallSite*) 0x"
-            << &FunctionCalls[i] << "\n");
-      
-      DSGraph::NodeMapTy NodeMapInCallee; // map from nodes to clones in callee
-      DSGraph::NodeMapTy CompletedMap;    // unused map for nodes not to do
-      CalleeGraph.cloneReachableSubgraph(Graph, RootNodeSet,
-                                         NodeMapInCallee, CompletedMap,
-                                         DSGraph::StripModRefBits |
-                                         DSGraph::KeepAllocaBit);
-
-      // Transform our call site info into the cloned version for CalleeGraph
-      DSCallSite CS(FunctionCalls[i], NodeMapInCallee);
-
-      // Get the formal argument and return nodes for the called function
-      // and merge them with the cloned subgraph.  Global nodes were merged  
-      // already by cloneReachableSubgraph() above.
-      CalleeGraph.getCallSiteForArguments(*I->second).mergeWith(CS);
-
-      ++NumTDInlines;
-    }
-  }
-
-  DEBUG(std::cerr << "  [TD] Done inlining into callees for: "
-        << Graph.getFunctionNames() << " [" << Graph.getGraphSize() << "+"
-        << Graph.getFunctionCalls().size() << "]\n");
-}
-
diff --git a/poolalloc/lib/PoolAllocate/PoolAllocate.cpp b/poolalloc/lib/PoolAllocate/PoolAllocate.cpp
deleted file mode 100644
index 685071f..0000000
--- a/poolalloc/lib/PoolAllocate/PoolAllocate.cpp
+++ /dev/null
@@ -1,1191 +0,0 @@
-//===-- PoolAllocate.cpp - Pool Allocation Pass ---------------------------===//
-//
-// This transform changes programs so that disjoint data structures are
-// allocated out of different pools of memory, increasing locality.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "PoolAllocation"
-#include "llvm/Transforms/PoolAllocate.h"
-#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Analysis/DataStructure.h"
-#include "llvm/Analysis/DSGraph.h"
-#include "llvm/Module.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Support/InstVisitor.h"
-#include "Support/Debug.h"
-#include "Support/VectorExtras.h"
-using namespace PA;
-
-namespace {
-  const Type *VoidPtrTy = PointerType::get(Type::SByteTy);
-
-  // The type to allocate for a pool descriptor: { sbyte*, uint, uint }
-  // void *Data (the data)
-  // unsigned NodeSize  (size of an allocated node)
-  // unsigned FreeablePool (are slabs in the pool freeable upon calls to 
-  //                        poolfree?)
-  const Type *PoolDescType = 
-  StructType::get(make_vector<const Type*>(VoidPtrTy, Type::UIntTy, 
-                                           Type::UIntTy, 0));
-  
-  const PointerType *PoolDescPtr = PointerType::get(PoolDescType);
-  
-  RegisterOpt<PoolAllocate>
-  X("poolalloc", "Pool allocate disjoint data structures");
-}
-
-void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.addRequired<BUDataStructures>();
-  AU.addRequired<TDDataStructures>();
-  AU.addRequired<TargetData>();
-}
-
-// Prints out the functions mapped to the leader of the equivalence class they
-// belong to.
-void PoolAllocate::printFuncECs() {
-  std::map<Function*, Function*> &leaderMap = FuncECs.getLeaderMap();
-  std::cerr << "Indirect Function Map \n";
-  for (std::map<Function*, Function*>::iterator LI = leaderMap.begin(),
-	 LE = leaderMap.end(); LI != LE; ++LI) {
-    std::cerr << LI->first->getName() << ": leader is "
-	      << LI->second->getName() << "\n";
-  }
-}
-
-static void printNTOMap(std::map<Value*, const Value*> &NTOM) {
-  std::cerr << "NTOM MAP\n";
-  for (std::map<Value*, const Value *>::iterator I = NTOM.begin(), 
-	 E = NTOM.end(); I != E; ++I) {
-    if (!isa<Function>(I->first) && !isa<BasicBlock>(I->first))
-      std::cerr << *I->first << " to " << *I->second << "\n";
-  }
-}
-
-void PoolAllocate::buildIndirectFunctionSets(Module &M) {
-  // Iterate over the module looking for indirect calls to functions
-
-  // Get top down DSGraph for the functions
-  TDDS = &getAnalysis<TDDataStructures>();
-  
-  for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
-
-    DEBUG(std::cerr << "Processing indirect calls function:" <<  MI->getName() << "\n");
-
-    if (MI->isExternal())
-      continue;
-
-    DSGraph &TDG = TDDS->getDSGraph(*MI);
-
-    std::vector<DSCallSite> callSites = TDG.getFunctionCalls();
-
-    // For each call site in the function
-    // All the functions that can be called at the call site are put in the
-    // same equivalence class.
-    for (std::vector<DSCallSite>::iterator CSI = callSites.begin(), 
-	   CSE = callSites.end(); CSI != CSE ; ++CSI) {
-      if (CSI->isIndirectCall()) {
-	DSNode *DSN = CSI->getCalleeNode();
-	if (DSN->isIncomplete())
-	  std::cerr << "Incomplete node " << CSI->getCallInst();
-	// assert(DSN->isGlobalNode());
-	const std::vector<GlobalValue*> &Callees = DSN->getGlobals();
-	if (Callees.size() > 0) {
-	  Function *firstCalledF = dyn_cast<Function>(*Callees.begin());
-	  FuncECs.addElement(firstCalledF);
-	  CallInstTargets.insert(std::pair<CallInst*,Function*>
-				 (&CSI->getCallInst(),
-				  firstCalledF));
-	  if (Callees.size() > 1) {
-	    for (std::vector<GlobalValue*>::const_iterator CalleesI = 
-		   Callees.begin()+1, CalleesE = Callees.end(); 
-		 CalleesI != CalleesE; ++CalleesI) {
-	      Function *calledF = dyn_cast<Function>(*CalleesI);
-	      FuncECs.unionSetsWith(firstCalledF, calledF);
-	      CallInstTargets.insert(std::pair<CallInst*,Function*>
-				     (&CSI->getCallInst(), calledF));
-	    }
-	  }
-	} else {
-	  std::cerr << "No targets " << CSI->getCallInst();
-	}
-      }
-    }
-  }
-  
-  // Print the equivalence classes
-  DEBUG(printFuncECs());
-}
-
-bool PoolAllocate::run(Module &M) {
-  if (M.begin() == M.end()) return false;
-  CurModule = &M;
-  
-  AddPoolPrototypes();
-  BU = &getAnalysis<BUDataStructures>();
-
-  buildIndirectFunctionSets(M);
-
-  std::map<Function*, Function*> FuncMap;
-
-  // Loop over the functions in the original program finding the pool desc.
-  // arguments necessary for each function that is indirectly callable.
-  // For each equivalence class, make a list of pool arguments and update
-  // the PoolArgFirst and PoolArgLast values for each function.
-  Module::iterator LastOrigFunction = --M.end();
-  for (Module::iterator I = M.begin(); ; ++I) {
-    if (!I->isExternal())
-      FindFunctionPoolArgs(*I);
-    if (I == LastOrigFunction) break;
-  }
-
-  // Now clone a function using the pool arg list obtained in the previous
-  // pass over the modules.
-  // Loop over only the function initially in the program, don't traverse newly
-  // added ones.  If the function uses memory, make its clone.
-  for (Module::iterator I = M.begin(); ; ++I) {
-    if (!I->isExternal())
-      if (Function *R = MakeFunctionClone(*I))
-        FuncMap[I] = R;
-    if (I == LastOrigFunction) break;
-  }
-  
-  ++LastOrigFunction;
-
-  // Now that all call targets are available, rewrite the function bodies of the
-  // clones.
-  for (Module::iterator I = M.begin(); I != LastOrigFunction; ++I)
-    if (!I->isExternal()) {
-      std::map<Function*, Function*>::iterator FI = FuncMap.find(I);
-      ProcessFunctionBody(*I, FI != FuncMap.end() ? *FI->second : *I);
-    }
-
-  if (CollapseFlag)
-    std::cerr << "Pool Allocation successful! However all data structures may not be pool allocated\n";
-
-  return true;
-}
-
-
-// AddPoolPrototypes - Add prototypes for the pool functions to the specified
-// module and update the Pool* instance variables to point to them.
-//
-void PoolAllocate::AddPoolPrototypes() {
-  CurModule->addTypeName("PoolDescriptor", PoolDescType);
-  
-  // Get poolinit function...
-  FunctionType *PoolInitTy =
-    FunctionType::get(Type::VoidTy,
-                      make_vector<const Type*>(PoolDescPtr, Type::UIntTy, 0),
-                      false);
-  PoolInit = CurModule->getOrInsertFunction("poolinit", PoolInitTy);
-
-  // Get pooldestroy function...
-  std::vector<const Type*> PDArgs(1, PoolDescPtr);
-  FunctionType *PoolDestroyTy =
-    FunctionType::get(Type::VoidTy, PDArgs, false);
-  PoolDestroy = CurModule->getOrInsertFunction("pooldestroy", PoolDestroyTy);
-  
-  // Get the poolalloc function...
-  FunctionType *PoolAllocTy = FunctionType::get(VoidPtrTy, PDArgs, false);
-  PoolAlloc = CurModule->getOrInsertFunction("poolalloc", PoolAllocTy);
-  
-  // Get the poolfree function...
-  PDArgs.push_back(VoidPtrTy);       // Pointer to free
-  FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, PDArgs, false);
-  PoolFree = CurModule->getOrInsertFunction("poolfree", PoolFreeTy);
-  
-  // The poolallocarray function
-  FunctionType *PoolAllocArrayTy =
-    FunctionType::get(VoidPtrTy,
-                      make_vector<const Type*>(PoolDescPtr, Type::UIntTy, 0),
-                      false);
-  PoolAllocArray = CurModule->getOrInsertFunction("poolallocarray", 
-						  PoolAllocArrayTy);
-  
-}
-
-// Inline the DSGraphs of functions corresponding to the potential targets at
-// indirect call sites into the DS Graph of the callee.
-// This is required to know what pools to create/pass at the call site in the 
-// caller
-//
-void PoolAllocate::InlineIndirectCalls(Function &F, DSGraph &G, 
-                                       hash_set<Function*> &visited) {
-  std::vector<DSCallSite> callSites = G.getFunctionCalls();
-  
-  visited.insert(&F);
-
-  // For each indirect call site in the function, inline all the potential
-  // targets
-  for (std::vector<DSCallSite>::iterator CSI = callSites.begin(),
-         CSE = callSites.end(); CSI != CSE; ++CSI) {
-    if (CSI->isIndirectCall()) {
-      CallInst &CI = CSI->getCallInst();
-      std::pair<std::multimap<CallInst*, Function*>::iterator,
-        std::multimap<CallInst*, Function*>::iterator> Targets =
-        CallInstTargets.equal_range(&CI);
-      for (std::multimap<CallInst*, Function*>::iterator TFI = Targets.first,
-             TFE = Targets.second; TFI != TFE; ++TFI) {
-	DSGraph &TargetG = BU->getDSGraph(*TFI->second);
-        // Call the function recursively if the callee is not yet inlined
-        // and if it hasn't been visited in this sequence of calls
-        // The latter is dependent on the fact that the graphs of all functions
-        // in an SCC are actually the same
-        if (InlinedFuncs.find(TFI->second) == InlinedFuncs.end() && 
-            visited.find(TFI->second) == visited.end()) {
-          InlineIndirectCalls(*TFI->second, TargetG, visited);
-        }
-        G.mergeInGraph(*CSI, *TFI->second, TargetG, DSGraph::KeepModRefBits | 
-                       DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes |
-                       DSGraph::DontCloneAuxCallNodes); 
-      }
-    }
-  }
-  
-  // Mark this function as one whose graph is inlined with its indirect 
-  // function targets' DS Graphs.  This ensures that every function is inlined
-  // exactly once
-  InlinedFuncs.insert(&F);
-}
-
-void PoolAllocate::FindFunctionPoolArgs(Function &F) {
-
-  // The DSGraph is merged with the globals graph. 
-  DSGraph &G = BU->getDSGraph(F);
-  G.mergeInGlobalsGraph();
-
-  // Inline the potential targets of indirect calls
-  hash_set<Function*> visitedFuncs;
-  InlineIndirectCalls(F, G, visitedFuncs);
-
-  // At this point the DS Graphs have been modified in place including
-  // information about globals as well as indirect calls, making it useful
-  // for pool allocation
-  std::vector<DSNode*> &Nodes = G.getNodes();
-  if (Nodes.empty()) return ;  // No memory activity, nothing is required
-
-  FuncInfo &FI = FunctionInfo[&F];   // Create a new entry for F
-  
-  FI.Clone = 0;
-  
-  // Initialize the PoolArgFirst and PoolArgLast for the function depending
-  // on whether there have been other functions in the equivalence class
-  // that have pool arguments so far in the analysis.
-  if (!FuncECs.findClass(&F)) {
-    FI.PoolArgFirst = FI.PoolArgLast = 0;
-  } else {
-    if (EqClass2LastPoolArg.find(FuncECs.findClass(&F)) != 
-	EqClass2LastPoolArg.end())
-      FI.PoolArgFirst = FI.PoolArgLast = 
-	EqClass2LastPoolArg[FuncECs.findClass(&F)] + 1;
-    else
-      FI.PoolArgFirst = FI.PoolArgLast = 0;
-  }
-  
-  // Find DataStructure nodes which are allocated in pools non-local to the
-  // current function.  This set will contain all of the DSNodes which require
-  // pools to be passed in from outside of the function.
-  hash_set<DSNode*> &MarkedNodes = FI.MarkedNodes;
-  
-  // Mark globals and incomplete nodes as live... (this handles arguments)
-  if (F.getName() != "main")
-    for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
-      if (Nodes[i]->isGlobalNode() && !Nodes[i]->isIncomplete())
-        DEBUG(std::cerr << "Global node is not Incomplete\n");
-      if ((Nodes[i]->isIncomplete() || Nodes[i]->isGlobalNode()) && 
-	  Nodes[i]->isHeapNode())
-        Nodes[i]->markReachableNodes(MarkedNodes);
-    }
-
-  // Marked the returned node as alive...
-  if (DSNode *RetNode = G.getReturnNodeFor(F).getNode())
-    if (RetNode->isHeapNode())
-      RetNode->markReachableNodes(MarkedNodes);
-
-  if (MarkedNodes.empty())   // We don't need to clone the function if there
-    return;                  // are no incoming arguments to be added.
-
-  // Erase any marked node that is not a heap node
-
-  for (hash_set<DSNode*>::iterator I = MarkedNodes.begin(),
-	 E = MarkedNodes.end(); I != E; ) {
-    // erase invalidates hash_set iterators if the iterator points to the
-    // element being erased
-    if (!(*I)->isHeapNode())
-      MarkedNodes.erase(I++);
-    else
-      ++I;
-  }
-
-  FI.PoolArgLast += MarkedNodes.size();
-
-
-  if (FuncECs.findClass(&F)) {
-    // Update the equivalence class last pool argument information
-    // only if there actually were pool arguments to the function.
-    // Also, there is no entry for the Eq. class in EqClass2LastPoolArg
-    // if there are no functions in the equivalence class with pool arguments.
-    if (FI.PoolArgLast != FI.PoolArgFirst)
-      EqClass2LastPoolArg[FuncECs.findClass(&F)] = FI.PoolArgLast - 1;
-  }
-  
-}
-
-// MakeFunctionClone - If the specified function needs to be modified for pool
-// allocation support, make a clone of it, adding additional arguments as
-// neccesary, and return it.  If not, just return null.
-//
-Function *PoolAllocate::MakeFunctionClone(Function &F) {
-  
-  DSGraph &G = BU->getDSGraph(F);
-
-  std::vector<DSNode*> &Nodes = G.getNodes();
-  if (Nodes.empty())
-    return 0;
-    
-  FuncInfo &FI = FunctionInfo[&F];
-  
-  hash_set<DSNode*> &MarkedNodes = FI.MarkedNodes;
-  
-  if (!FuncECs.findClass(&F)) {
-    // Not in any equivalence class
-    if (MarkedNodes.empty())
-      return 0;
-  } else {
-    // No need to clone if there are no pool arguments in any function in the
-    // equivalence class
-    if (!EqClass2LastPoolArg.count(FuncECs.findClass(&F)))
-      return 0;
-  }
-      
-  // Figure out what the arguments are to be for the new version of the function
-  const FunctionType *OldFuncTy = F.getFunctionType();
-  std::vector<const Type*> ArgTys;
-  if (!FuncECs.findClass(&F)) {
-    ArgTys.reserve(OldFuncTy->getParamTypes().size() + MarkedNodes.size());
-    FI.ArgNodes.reserve(MarkedNodes.size());
-    for (hash_set<DSNode*>::iterator I = MarkedNodes.begin(),
-	   E = MarkedNodes.end(); I != E; ++I) {
-      ArgTys.push_back(PoolDescPtr);      // Add the appropriate # of pool descs
-      FI.ArgNodes.push_back(*I);
-    }
-    if (FI.ArgNodes.empty()) return 0;      // No nodes to be pool allocated!
-
-  }
-  else {
-    // This function is a member of an equivalence class and needs to be cloned 
-    ArgTys.reserve(OldFuncTy->getParamTypes().size() + 
-		   EqClass2LastPoolArg[FuncECs.findClass(&F)] + 1);
-    FI.ArgNodes.reserve(EqClass2LastPoolArg[FuncECs.findClass(&F)] + 1);
-    
-    for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i) {
-      ArgTys.push_back(PoolDescPtr);      // Add the appropriate # of pool 
-                                          // descs
-    }
-
-    for (hash_set<DSNode*>::iterator I = MarkedNodes.begin(),
-	   E = MarkedNodes.end(); I != E; ++I) {
-      FI.ArgNodes.push_back(*I);
-    }
-
-    assert ((FI.ArgNodes.size() == (unsigned) (FI.PoolArgLast - 
-					       FI.PoolArgFirst)) && 
-	    "Number of ArgNodes equal to the number of pool arguments used by this function");
-
-    if (FI.ArgNodes.empty()) return 0;
-  }
-      
-      
-  ArgTys.insert(ArgTys.end(), OldFuncTy->getParamTypes().begin(),
-                OldFuncTy->getParamTypes().end());
-
-
-  // Create the new function prototype
-  FunctionType *FuncTy = FunctionType::get(OldFuncTy->getReturnType(), ArgTys,
-                                           OldFuncTy->isVarArg());
-  // Create the new function...
-  Function *New = new Function(FuncTy, GlobalValue::InternalLinkage,
-                               F.getName(), F.getParent());
-
-  // Set the rest of the new arguments names to be PDa<n> and add entries to the
-  // pool descriptors map
-  std::map<DSNode*, Value*> &PoolDescriptors = FI.PoolDescriptors;
-  Function::aiterator NI = New->abegin();
-  
-  if (FuncECs.findClass(&F)) {
-    // If the function belongs to an equivalence class
-    for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i, 
-	   ++NI)
-      NI->setName("PDa");
-    
-    NI = New->abegin();
-    if (FI.PoolArgFirst > 0)
-      for (int i = 0; i < FI.PoolArgFirst; ++NI, ++i)
-	;
-
-    for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI)
-      PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI));
-
-    NI = New->abegin();
-    if (EqClass2LastPoolArg.count(FuncECs.findClass(&F)))
-      for (int i = 0; i <= EqClass2LastPoolArg[FuncECs.findClass(&F)]; ++i, ++NI)
-	;
-  } else {
-    // If the function does not belong to an equivalence class
-    if (FI.ArgNodes.size())
-      for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) {
-	NI->setName("PDa");  // Add pd entry
-	PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI));
-      }
-    NI = New->abegin();
-    if (FI.ArgNodes.size())
-      for (unsigned i = 0; i < FI.ArgNodes.size(); ++NI, ++i)
-	;
-  }
-
-  // Map the existing arguments of the old function to the corresponding
-  // arguments of the new function.
-  std::map<const Value*, Value*> ValueMap;
-  if (NI != New->aend()) 
-    for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++NI) {
-      ValueMap[I] = NI;
-      NI->setName(I->getName());
-    }
-
-  // Populate the value map with all of the globals in the program.
-  // FIXME: This should be unneccesary!
-  Module &M = *F.getParent();
-  for (Module::iterator I = M.begin(), E=M.end(); I!=E; ++I)    ValueMap[I] = I;
-  for (Module::giterator I = M.gbegin(), E=M.gend(); I!=E; ++I) ValueMap[I] = I;
-
-  // Perform the cloning.
-  std::vector<ReturnInst*> Returns;
-  CloneFunctionInto(New, &F, ValueMap, Returns);
-
-  // Invert the ValueMap into the NewToOldValueMap
-  std::map<Value*, const Value*> &NewToOldValueMap = FI.NewToOldValueMap;
-  for (std::map<const Value*, Value*>::iterator I = ValueMap.begin(),
-         E = ValueMap.end(); I != E; ++I)
-    NewToOldValueMap.insert(std::make_pair(I->second, I->first));
-  
-  return FI.Clone = New;
-}
-
-
-// processFunction - Pool allocate any data structures which are contained in
-// the specified function...
-//
-void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) {
-  DSGraph &G = BU->getDSGraph(F);
-
-  std::vector<DSNode*> &Nodes = G.getNodes();
-  if (Nodes.empty()) return;     // Quick exit if nothing to do...
-  
-  FuncInfo &FI = FunctionInfo[&F];   // Get FuncInfo for F
-  hash_set<DSNode*> &MarkedNodes = FI.MarkedNodes;
-  
-  DEBUG(std::cerr << "[" << F.getName() << "] Pool Allocate: ");
-  
-  // Loop over all of the nodes which are non-escaping, adding pool-allocatable
-  // ones to the NodesToPA vector.
-  std::vector<DSNode*> NodesToPA;
-  for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-    if (Nodes[i]->isHeapNode() &&   // Pick nodes with heap elems
-        !MarkedNodes.count(Nodes[i]))              // Can't be marked
-      NodesToPA.push_back(Nodes[i]);
-  
-  DEBUG(std::cerr << NodesToPA.size() << " nodes to pool allocate\n");
-  if (!NodesToPA.empty()) {
-    // Create pool construction/destruction code
-    std::map<DSNode*, Value*> &PoolDescriptors = FI.PoolDescriptors;
-    CreatePools(NewF, NodesToPA, PoolDescriptors);
-  }
-  
-  // Transform the body of the function now...
-  TransformFunctionBody(NewF, F, G, FI);
-}
-
-
-// CreatePools - This creates the pool initialization and destruction code for
-// the DSNodes specified by the NodesToPA list.  This adds an entry to the
-// PoolDescriptors map for each DSNode.
-//
-void PoolAllocate::CreatePools(Function &F,
-                               const std::vector<DSNode*> &NodesToPA,
-                               std::map<DSNode*, Value*> &PoolDescriptors) {
-  // Find all of the return nodes in the CFG...
-  std::vector<BasicBlock*> ReturnNodes;
-  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
-    if (isa<ReturnInst>(I->getTerminator()))
-      ReturnNodes.push_back(I);
-
-  TargetData &TD = getAnalysis<TargetData>();
-
-  // Loop over all of the pools, inserting code into the entry block of the
-  // function for the initialization and code in the exit blocks for
-  // destruction.
-  //
-  Instruction *InsertPoint = F.front().begin();
-  for (unsigned i = 0, e = NodesToPA.size(); i != e; ++i) {
-    DSNode *Node = NodesToPA[i];
-    
-    // Create a new alloca instruction for the pool...
-    Value *AI = new AllocaInst(PoolDescType, 0, "PD", InsertPoint);
-    
-    Value *ElSize;
-    
-    // Void types in DS graph are never used
-    if (Node->getType() != Type::VoidTy)
-      ElSize = ConstantUInt::get(Type::UIntTy, TD.getTypeSize(Node->getType()));
-    else {
-      DEBUG(std::cerr << "Potential node collapsing in " << F.getName() 
-		<< ". All Data Structures may not be pool allocated\n");
-      ElSize = ConstantUInt::get(Type::UIntTy, 0);
-    }
-	
-    // Insert the call to initialize the pool...
-    new CallInst(PoolInit, make_vector(AI, ElSize, 0), "", InsertPoint);
-      
-    // Update the PoolDescriptors map
-    PoolDescriptors.insert(std::make_pair(Node, AI));
-    
-    // Insert a call to pool destroy before each return inst in the function
-    for (unsigned r = 0, e = ReturnNodes.size(); r != e; ++r)
-      new CallInst(PoolDestroy, make_vector(AI, 0), "",
-		   ReturnNodes[r]->getTerminator());
-  }
-}
-
-
-namespace {
-  /// FuncTransform - This class implements transformation required of pool
-  /// allocated functions.
-  struct FuncTransform : public InstVisitor<FuncTransform> {
-    PoolAllocate &PAInfo;
-    DSGraph &G;      // The Bottom-up DS Graph
-    DSGraph &TDG;    // The Top-down DS Graph
-    FuncInfo &FI;
-
-    FuncTransform(PoolAllocate &P, DSGraph &g, DSGraph &tdg, FuncInfo &fi)
-      : PAInfo(P), G(g), TDG(tdg), FI(fi) {
-    }
-
-    void visitMallocInst(MallocInst &MI);
-    void visitFreeInst(FreeInst &FI);
-    void visitCallInst(CallInst &CI);
-    
-    // The following instructions are never modified by pool allocation
-    void visitBranchInst(BranchInst &I) { }
-    void visitBinaryOperator(Instruction &I) { }
-    void visitShiftInst (ShiftInst &I) { }
-    void visitSwitchInst (SwitchInst &I) { }
-    void visitCastInst (CastInst &I) { }
-    void visitAllocaInst(AllocaInst &I) { }
-    void visitLoadInst(LoadInst &I) { }
-    void visitGetElementPtrInst (GetElementPtrInst &I) { }
-
-    void visitReturnInst(ReturnInst &I);
-    void visitStoreInst (StoreInst &I);
-    void visitPHINode(PHINode &I);
-
-    void visitInstruction(Instruction &I) {
-      std::cerr << "PoolAllocate does not recognize this instruction\n";
-      abort();
-    }
-
-  private:
-    DSNodeHandle& getDSNodeHFor(Value *V) {
-      //      if (isa<Constant>(V))
-      //	return DSNodeHandle();
-
-      if (!FI.NewToOldValueMap.empty()) {
-        // If the NewToOldValueMap is in effect, use it.
-        std::map<Value*,const Value*>::iterator I = FI.NewToOldValueMap.find(V);
-        if (I != FI.NewToOldValueMap.end())
-          V = (Value*)I->second;
-      }
-
-      return G.getScalarMap()[V];
-    }
-
-    DSNodeHandle& getTDDSNodeHFor(Value *V) {
-      if (!FI.NewToOldValueMap.empty()) {
-        // If the NewToOldValueMap is in effect, use it.
-        std::map<Value*,const Value*>::iterator I = FI.NewToOldValueMap.find(V);
-        if (I != FI.NewToOldValueMap.end())
-          V = (Value*)I->second;
-      }
-
-      return TDG.getScalarMap()[V];
-    }
-
-    Value *getPoolHandle(Value *V) {
-      DSNode *Node = getDSNodeHFor(V).getNode();
-      // Get the pool handle for this DSNode...
-      std::map<DSNode*, Value*>::iterator I = FI.PoolDescriptors.find(Node);
-
-      if (I != FI.PoolDescriptors.end()) {
-	// Check that the node pointed to by V in the TD DS graph is not
-	// collapsed
-	DSNode *TDNode = getTDDSNodeHFor(V).getNode();
-	if (TDNode->getType() != Type::VoidTy)
-	  return I->second;
-	else {
-	  PAInfo.CollapseFlag = 1;
-	  return 0;
-	}
-      }
-      else
-	return 0;
-	  
-    }
-    
-    bool isFuncPtr(Value *V);
-
-    Function* getFuncClass(Value *V);
-
-    Value* retCloneIfFunc(Value *V);
-  };
-}
-
-void PoolAllocate::TransformFunctionBody(Function &F, Function &OldF,
-                                         DSGraph &G, FuncInfo &FI) {
-  FuncTransform(*this, G, TDDS->getDSGraph(OldF), FI).visit(F);
-}
-
-// Returns true if V is a function pointer
-bool FuncTransform::isFuncPtr(Value *V) {
-  if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
-     return isa<FunctionType>(PTy->getElementType());
-  return false;
-}
-
-// Given a function pointer, return the function eq. class if one exists
-Function* FuncTransform::getFuncClass(Value *V) {
-  // Look at DSGraph and see if the set of of functions it could point to
-  // are pool allocated.
-
-  if (!isFuncPtr(V))
-    return 0;
-
-  // Two cases: 
-  // if V is a constant
-  if (Function *theFunc = dyn_cast<Function>(V)) {
-    if (!PAInfo.FuncECs.findClass(theFunc))
-      // If this function does not belong to any equivalence class
-      return 0;
-    if (PAInfo.EqClass2LastPoolArg.count(PAInfo.FuncECs.findClass(theFunc)))
-      return PAInfo.FuncECs.findClass(theFunc);
-    else
-      return 0;
-  }
-
-  // if V is not a constant
-  DSNode *DSN = TDG.getNodeForValue(V).getNode();
-  if (!DSN) {
-    return 0;
-  }
-  const std::vector<GlobalValue*> &Callees = DSN->getGlobals();
-  if (Callees.size() > 0) {
-    Function *calledF = dyn_cast<Function>(*Callees.begin());
-    assert(PAInfo.FuncECs.findClass(calledF) && "should exist in some eq. class");
-    if (PAInfo.EqClass2LastPoolArg.count(PAInfo.FuncECs.findClass(calledF)))
-      return PAInfo.FuncECs.findClass(calledF);
-  }
-
-  return 0;
-}
-
-// Returns the clone if  V is a static function (not a pointer) and belongs 
-// to an equivalence class i.e. is pool allocated
-Value* FuncTransform::retCloneIfFunc(Value *V) {
-  if (Function *fixedFunc = dyn_cast<Function>(V))
-    if (getFuncClass(V))
-      return PAInfo.getFuncInfo(*fixedFunc)->Clone;
-  
-  return 0;
-}
-
-void FuncTransform::visitReturnInst (ReturnInst &RI) {
-  if (RI.getNumOperands())
-    if (Value *clonedFunc = retCloneIfFunc(RI.getOperand(0))) {
-      // Cast the clone of RI.getOperand(0) to the non-pool-allocated type
-      CastInst *CastI = new CastInst(clonedFunc, RI.getOperand(0)->getType(), 
-				     "tmp", &RI);
-      // Insert return instruction that returns the casted value
-      ReturnInst *RetI = new ReturnInst(CastI, &RI);
-
-      // Remove original return instruction
-      RI.getParent()->getInstList().erase(&RI);
-
-      if (!FI.NewToOldValueMap.empty()) {
-	std::map<Value*,const Value*>::iterator II =
-	  FI.NewToOldValueMap.find(&RI);
-	assert(II != FI.NewToOldValueMap.end() && 
-	       "RI not found in clone?");
-	FI.NewToOldValueMap.insert(std::make_pair(RetI, II->second));
-	FI.NewToOldValueMap.erase(II);
-      }
-    }
-}
-
-void FuncTransform::visitStoreInst (StoreInst &SI) {
-  // Check if a constant function is being stored
-  if (Value *clonedFunc = retCloneIfFunc(SI.getOperand(0))) {
-    CastInst *CastI = new CastInst(clonedFunc, SI.getOperand(0)->getType(), 
-				   "tmp", &SI);
-    StoreInst *StoreI = new StoreInst(CastI, SI.getOperand(1), &SI);
-    SI.getParent()->getInstList().erase(&SI);
-    
-    // Update the NewToOldValueMap if this is a clone
-    if (!FI.NewToOldValueMap.empty()) {
-      std::map<Value*,const Value*>::iterator II =
-	FI.NewToOldValueMap.find(&SI);
-      assert(II != FI.NewToOldValueMap.end() && 
-	     "SI not found in clone?");
-      FI.NewToOldValueMap.insert(std::make_pair(StoreI, II->second));
-      FI.NewToOldValueMap.erase(II);
-    }
-  }
-}
-
-void FuncTransform::visitPHINode(PHINode &PI) {
-  // If any of the operands of the PHI node is a constant function pointer
-  // that is cloned, the cast instruction has to be inserted at the end of the
-  // previous basic block
-  
-  if (isFuncPtr(&PI)) {
-    PHINode *V = new PHINode(PI.getType(), PI.getName(), &PI);
-    for (unsigned i = 0 ; i < PI.getNumIncomingValues(); ++i) {
-      if (Value *clonedFunc = retCloneIfFunc(PI.getIncomingValue(i))) {
-	// Insert CastInst at the end of  PI.getIncomingBlock(i)
-	BasicBlock::iterator BBI = --PI.getIncomingBlock(i)->end();
-	// BBI now points to the terminator instruction of the basic block.
-	CastInst *CastI = new CastInst(clonedFunc, PI.getType(), "tmp", BBI);
-	V->addIncoming(CastI, PI.getIncomingBlock(i));
-      } else {
-	V->addIncoming(PI.getIncomingValue(i), PI.getIncomingBlock(i));
-      }
-      
-    }
-    PI.replaceAllUsesWith(V);
-    PI.getParent()->getInstList().erase(&PI);
-    
-    DSGraph::ScalarMapTy &SM = G.getScalarMap();
-    DSGraph::ScalarMapTy::iterator PII = SM.find(&PI); 
-
-    // Update Scalar map of DSGraph if this is one of the original functions
-    // Otherwise update the NewToOldValueMap
-    if (PII != SM.end()) {
-      SM.insert(std::make_pair(V, PII->second));
-      SM.erase(PII);                     // Destroy the PHINode
-    } else {
-      std::map<Value*,const Value*>::iterator II =
-	FI.NewToOldValueMap.find(&PI);
-      assert(II != FI.NewToOldValueMap.end() && 
-	     "PhiI not found in clone?");
-      FI.NewToOldValueMap.insert(std::make_pair(V, II->second));
-      FI.NewToOldValueMap.erase(II);
-    }
-  }
-}
-
-void FuncTransform::visitMallocInst(MallocInst &MI) {
-  // Get the pool handle for the node that this contributes to...
-  Value *PH = getPoolHandle(&MI);
-  
-  // NB: PH is zero even if the node is collapsed
-  if (PH == 0) return;
-
-  // Insert a call to poolalloc
-  Value *V;
-  if (MI.isArrayAllocation()) 
-    V = new CallInst(PAInfo.PoolAllocArray, 
-		     make_vector(PH, MI.getOperand(0), 0),
-		     MI.getName(), &MI);
-  else
-    V = new CallInst(PAInfo.PoolAlloc, make_vector(PH, 0),
-		     MI.getName(), &MI);
-  
-  MI.setName("");  // Nuke MIs name
-  
-  Value *Casted = V;
-
-  // Cast to the appropriate type if necessary
-  if (V->getType() != MI.getType()) {
-    Casted = new CastInst(V, MI.getType(), V->getName(), &MI);
-  }
-    
-  // Update def-use info
-  MI.replaceAllUsesWith(Casted);
-
-  // Remove old malloc instruction
-  MI.getParent()->getInstList().erase(&MI);
-  
-  DSGraph::ScalarMapTy &SM = G.getScalarMap();
-  DSGraph::ScalarMapTy::iterator MII = SM.find(&MI);
-  
-  // If we are modifying the original function, update the DSGraph... 
-  if (MII != SM.end()) {
-    // V and Casted now point to whatever the original malloc did...
-    SM.insert(std::make_pair(V, MII->second));
-    if (V != Casted)
-      SM.insert(std::make_pair(Casted, MII->second));
-    SM.erase(MII);                     // The malloc is now destroyed
-  } else {             // Otherwise, update the NewToOldValueMap
-    std::map<Value*,const Value*>::iterator MII =
-      FI.NewToOldValueMap.find(&MI);
-    assert(MII != FI.NewToOldValueMap.end() && "MI not found in clone?");
-    FI.NewToOldValueMap.insert(std::make_pair(V, MII->second));
-    if (V != Casted)
-      FI.NewToOldValueMap.insert(std::make_pair(Casted, MII->second));
-    FI.NewToOldValueMap.erase(MII);
-  }
-}
-
-void FuncTransform::visitFreeInst(FreeInst &FrI) {
-  Value *Arg = FrI.getOperand(0);
-  Value *PH = getPoolHandle(Arg);  // Get the pool handle for this DSNode...
-  if (PH == 0) return;
-  // Insert a cast and a call to poolfree...
-  Value *Casted = Arg;
-  if (Arg->getType() != PointerType::get(Type::SByteTy))
-    Casted = new CastInst(Arg, PointerType::get(Type::SByteTy),
-				 Arg->getName()+".casted", &FrI);
-
-  CallInst *FreeI = new CallInst(PAInfo.PoolFree, make_vector(PH, Casted, 0), 
-				 "", &FrI);
-  // Delete the now obsolete free instruction...
-  FrI.getParent()->getInstList().erase(&FrI);
-  
-  // Update the NewToOldValueMap if this is a clone
-  if (!FI.NewToOldValueMap.empty()) {
-    std::map<Value*,const Value*>::iterator II =
-      FI.NewToOldValueMap.find(&FrI);
-    assert(II != FI.NewToOldValueMap.end() && 
-	   "FrI not found in clone?");
-    FI.NewToOldValueMap.insert(std::make_pair(FreeI, II->second));
-    FI.NewToOldValueMap.erase(II);
-  }
-}
-
-static void CalcNodeMapping(DSNodeHandle& Caller, DSNodeHandle& Callee,
-                            std::map<DSNode*, DSNode*> &NodeMapping) {
-  DSNode *CalleeNode = Callee.getNode();
-  DSNode *CallerNode = Caller.getNode();
-
-  unsigned CalleeOffset = Callee.getOffset();
-  unsigned CallerOffset = Caller.getOffset();
-
-  if (CalleeNode == 0) return;
-
-  // If callee has a node and caller doesn't, then a constant argument was
-  // passed by the caller
-  if (CallerNode == 0) {
-    NodeMapping.insert(NodeMapping.end(), std::make_pair(CalleeNode, 
-							 (DSNode *) 0));
-  }
-
-  // Map the callee node to the caller node. 
-  // NB: The callee node could be of a different type. Eg. if it points to the
-  // field of a struct that the caller points to
-  std::map<DSNode*, DSNode*>::iterator I = NodeMapping.find(CalleeNode);
-  if (I != NodeMapping.end()) {   // Node already in map...
-    assert(I->second == CallerNode && 
-	   "Node maps to different nodes on paths?");
-  } else {
-    NodeMapping.insert(I, std::make_pair(CalleeNode, CallerNode));
-    
-    if (CalleeNode->getType() != CallerNode->getType() && CallerOffset == 0) 
-      DEBUG(std::cerr << "NB: Mapping of nodes between different types\n");
-
-    // Recursively map the callee links to the caller links starting from the
-    // offset in the node into which they are mapped.
-    // Being a BU Graph, the callee ought to have smaller number of links unless
-    // there is collapsing in the caller
-    unsigned numCallerLinks = CallerNode->getNumLinks() - CallerOffset;
-    unsigned numCalleeLinks = CalleeNode->getNumLinks() - CalleeOffset;
-    
-    if (numCallerLinks > 0) {
-      if (numCallerLinks < numCalleeLinks) {
-	DEBUG(std::cerr << "Potential node collapsing in caller\n");
-	for (unsigned i = 0, e = numCalleeLinks; i != e; ++i)
-	  CalcNodeMapping(CallerNode->getLink(((i%numCallerLinks) << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping);
-      } else {
-	for (unsigned i = 0, e = numCalleeLinks; i != e; ++i)
-	  CalcNodeMapping(CallerNode->getLink((i << DS::PointerShift) + CallerOffset), CalleeNode->getLink((i << DS::PointerShift) + CalleeOffset), NodeMapping);
-      }
-    } else if (numCalleeLinks > 0) {
-      DEBUG(std::cerr << 
-	    "Caller has unexpanded node, due to indirect call perhaps!\n");
-    }
-  }
-}
-
-void FuncTransform::visitCallInst(CallInst &CI) {
-  Function *CF = CI.getCalledFunction();
-  
-  // optimization for function pointers that are basically gotten from a cast
-  // with only one use and constant expressions with casts in them
-  if (!CF) {
-    if (CastInst* CastI = dyn_cast<CastInst>(CI.getCalledValue())) {
-      if (isa<Function>(CastI->getOperand(0)) && 
-	  CastI->getOperand(0)->getType() == CastI->getType())
-	CF = dyn_cast<Function>(CastI->getOperand(0));
-    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(CI.getOperand(0))) {
-      if (CE->getOpcode() == Instruction::Cast) {
-	if (isa<ConstantPointerRef>(CE->getOperand(0)))
-	  return;
-	else
-	  assert(0 && "Function pointer cast not handled as called function\n");
-      }
-    }    
-
-  }
-
-  DSGraph &CallerG = G;
-
-  std::vector<Value*> Args;  
-  if (!CF) {   // Indirect call
-    DEBUG(std::cerr << "  Handling call: " << CI);
-    
-    std::map<unsigned, Value*> PoolArgs;
-    Function *FuncClass;
-    
-    std::pair<std::multimap<CallInst*, Function*>::iterator,
-              std::multimap<CallInst*, Function*>::iterator> Targets =
-      PAInfo.CallInstTargets.equal_range(&CI);
-    for (std::multimap<CallInst*, Function*>::iterator TFI = Targets.first,
-	   TFE = Targets.second; TFI != TFE; ++TFI) {
-      if (TFI == Targets.first) {
-	FuncClass = PAInfo.FuncECs.findClass(TFI->second);
-	// Nothing to transform if there are no pool arguments in this
-	// equivalence class of functions.
-	if (!PAInfo.EqClass2LastPoolArg.count(FuncClass))
-	  return;
-      }
-      
-      FuncInfo *CFI = PAInfo.getFuncInfo(*TFI->second);
-
-      if (!CFI->ArgNodes.size()) continue;  // Nothing to transform...
-      
-      DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(*TFI->second);  
-      std::map<DSNode*, DSNode*> NodeMapping;
-      
-      Function::aiterator AI = TFI->second->abegin(), AE = TFI->second->aend();
-      unsigned OpNum = 1;
-      for ( ; AI != AE; ++AI, ++OpNum) {
-	if (!isa<Constant>(CI.getOperand(OpNum)))
-	  CalcNodeMapping(getDSNodeHFor(CI.getOperand(OpNum)), 
-                          CG.getScalarMap()[AI], NodeMapping);
-      }
-      assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!");
-      
-      if (CI.getType() != Type::VoidTy)
-        CalcNodeMapping(getDSNodeHFor(&CI),
-                        CG.getReturnNodeFor(*TFI->second), NodeMapping);
-      
-      // Map the nodes that are pointed to by globals.
-      // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g)
-      for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(), 
-             SME = G.getScalarMap().end(); SMI != SME; ++SMI)
-        if (isa<GlobalValue>(SMI->first)) { 
-          CalcNodeMapping(SMI->second, 
-                          CG.getScalarMap()[SMI->first], NodeMapping);
-        }
-
-      unsigned idx = CFI->PoolArgFirst;
-
-      // The following loop determines the pool pointers corresponding to 
-      // CFI.
-      for (unsigned i = 0, e = CFI->ArgNodes.size(); i != e; ++i, ++idx) {
-        if (NodeMapping.count(CFI->ArgNodes[i])) {
-          assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!");
-          DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second;
-          if (LocalNode) {
-            assert(FI.PoolDescriptors.count(LocalNode) &&
-                   "Node not pool allocated?");
-            PoolArgs[idx] = FI.PoolDescriptors.find(LocalNode)->second;
-          }
-          else
-            // LocalNode is null when a constant is passed in as a parameter
-            PoolArgs[idx] = Constant::getNullValue(PoolDescPtr);
-        } else {
-          PoolArgs[idx] = Constant::getNullValue(PoolDescPtr);
-        }
-      }
-    }
-    
-    // Push the pool arguments into Args.
-    if (PAInfo.EqClass2LastPoolArg.count(FuncClass)) {
-      for (int i = 0; i <= PAInfo.EqClass2LastPoolArg[FuncClass]; ++i) {
-        if (PoolArgs.find(i) != PoolArgs.end())
-          Args.push_back(PoolArgs[i]);
-        else
-          Args.push_back(Constant::getNullValue(PoolDescPtr));
-      }
-    
-      assert(Args.size()== (unsigned) PAInfo.EqClass2LastPoolArg[FuncClass] + 1
-             && "Call has same number of pool args as the called function");
-    }
-
-    // Add the rest of the arguments (the original arguments of the function)...
-    Args.insert(Args.end(), CI.op_begin()+1, CI.op_end());
-    
-    std::string Name = CI.getName();
-    
-    Value *NewCall;
-    if (Args.size() > CI.getNumOperands() - 1) {
-      // If there are any pool arguments
-      CastInst *CastI = 
-	new CastInst(CI.getOperand(0), 
-		     PAInfo.getFuncInfo(*FuncClass)->Clone->getType(), "tmp", 
-		     &CI);
-      NewCall = new CallInst(CastI, Args, Name, &CI);
-    } else {
-      NewCall = new CallInst(CI.getOperand(0), Args, Name, &CI);
-    }
-
-    CI.replaceAllUsesWith(NewCall);
-    DEBUG(std::cerr << "  Result Call: " << *NewCall);
-      
-    if (CI.getType() != Type::VoidTy) {
-      // If we are modifying the original function, update the DSGraph... 
-      DSGraph::ScalarMapTy &SM = G.getScalarMap();
-      DSGraph::ScalarMapTy::iterator CII = SM.find(&CI); 
-      if (CII != SM.end()) {
-	SM.insert(std::make_pair(NewCall, CII->second));
-	SM.erase(CII);                     // Destroy the CallInst
-      } else { 
-	// Otherwise update the NewToOldValueMap with the new CI return value
-	std::map<Value*,const Value*>::iterator CII = 
-	  FI.NewToOldValueMap.find(&CI);
-	assert(CII != FI.NewToOldValueMap.end() && "CI not found in clone?");
-	FI.NewToOldValueMap.insert(std::make_pair(NewCall, CII->second));
-	FI.NewToOldValueMap.erase(CII);
-      }
-    } else if (!FI.NewToOldValueMap.empty()) {
-      std::map<Value*,const Value*>::iterator II =
-	FI.NewToOldValueMap.find(&CI);
-      assert(II != FI.NewToOldValueMap.end() && 
-	     "CI not found in clone?");
-      FI.NewToOldValueMap.insert(std::make_pair(NewCall, II->second));
-      FI.NewToOldValueMap.erase(II);
-    }
-  }
-  else {
-
-    FuncInfo *CFI = PAInfo.getFuncInfo(*CF);
-
-    if (CFI == 0 || CFI->Clone == 0) return;  // Nothing to transform...
-    
-    DEBUG(std::cerr << "  Handling call: " << CI);
-    
-    DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(*CF);  // Callee graph
-
-    // We need to figure out which local pool descriptors correspond to the pool
-    // descriptor arguments passed into the function call.  Calculate a mapping
-    // from callee DSNodes to caller DSNodes.  We construct a partial isomophism
-    // between the graphs to figure out which pool descriptors need to be passed
-    // in.  The roots of this mapping is found from arguments and return values.
-    //
-    std::map<DSNode*, DSNode*> NodeMapping;
-    
-    Function::aiterator AI = CF->abegin(), AE = CF->aend();
-    unsigned OpNum = 1;
-    for (; AI != AE; ++AI, ++OpNum) {
-      Value *callOp = CI.getOperand(OpNum);
-      if (!isa<Constant>(callOp))
-	CalcNodeMapping(getDSNodeHFor(callOp), CG.getScalarMap()[AI], 
-			NodeMapping);
-    }
-    assert(OpNum == CI.getNumOperands() && "Varargs calls not handled yet!");
-    
-    // Map the return value as well...
-    if (CI.getType() != Type::VoidTy)
-      CalcNodeMapping(getDSNodeHFor(&CI), CG.getReturnNodeFor(*CF),
-		      NodeMapping);
-
-    // Map the nodes that are pointed to by globals.
-    // For all globals map getDSNodeForGlobal(g)->CG.getDSNodeForGlobal(g)
-    for (DSGraph::ScalarMapTy::iterator SMI = G.getScalarMap().begin(), 
-	   SME = G.getScalarMap().end(); SMI != SME; ++SMI)
-      if (isa<GlobalValue>(SMI->first)) { 
-	CalcNodeMapping(SMI->second, 
-			CG.getScalarMap()[SMI->first], NodeMapping);
-      }
-
-    // Okay, now that we have established our mapping, we can figure out which
-    // pool descriptors to pass in...
-
-    // Add an argument for each pool which must be passed in...
-    if (CFI->PoolArgFirst != 0) {
-      for (int i = 0; i < CFI->PoolArgFirst; ++i)
-	Args.push_back(Constant::getNullValue(PoolDescPtr));  
-    }
-
-    for (unsigned i = 0, e = CFI->ArgNodes.size(); i != e; ++i) {
-      if (NodeMapping.count(CFI->ArgNodes[i])) {
-
-	DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second;
-	if (LocalNode) {
-	  assert(FI.PoolDescriptors.count(LocalNode) &&
-                 "Node not pool allocated?");
-	  Args.push_back(FI.PoolDescriptors.find(LocalNode)->second);
-	} else
-	  Args.push_back(Constant::getNullValue(PoolDescPtr));
-      } else {
-	Args.push_back(Constant::getNullValue(PoolDescPtr));
-      }
-    }
-
-    Function *FuncClass = PAInfo.FuncECs.findClass(CF);
-    
-    if (PAInfo.EqClass2LastPoolArg.count(FuncClass))
-      for (int i = CFI->PoolArgLast; 
-	   i <= PAInfo.EqClass2LastPoolArg[FuncClass]; ++i)
-	Args.push_back(Constant::getNullValue(PoolDescPtr));
-
-    // Add the rest of the arguments...
-    Args.insert(Args.end(), CI.op_begin()+1, CI.op_end());
-    
-    std::string Name = CI.getName(); 
-
-    std::map<Value*,const Value*>::iterator CNewII; 
-    
-    Value *NewCall = new CallInst(CFI->Clone, Args, Name, &CI);
-
-    CI.replaceAllUsesWith(NewCall);
-    DEBUG(std::cerr << "  Result Call: " << *NewCall);
-
-    if (CI.getType() != Type::VoidTy) {
-      // If we are modifying the original function, update the DSGraph... 
-      DSGraph::ScalarMapTy &SM = G.getScalarMap();
-      DSGraph::ScalarMapTy::iterator CII = SM.find(&CI); 
-      if (CII != SM.end()) {
-	SM.insert(std::make_pair(NewCall, CII->second));
-	SM.erase(CII);                     // Destroy the CallInst
-      } else { 
-	// Otherwise update the NewToOldValueMap with the new CI return value
-	std::map<Value*,const Value*>::iterator CNII = 
-	  FI.NewToOldValueMap.find(&CI);
-	assert(CNII != FI.NewToOldValueMap.end() && CNII->second && 
-	       "CI not found in clone?");
-	FI.NewToOldValueMap.insert(std::make_pair(NewCall, CNII->second));
-	FI.NewToOldValueMap.erase(CNII);
-      }
-    } else if (!FI.NewToOldValueMap.empty()) {
-      std::map<Value*,const Value*>::iterator II =
-	FI.NewToOldValueMap.find(&CI);
-      assert(II != FI.NewToOldValueMap.end() && "CI not found in clone?");
-      FI.NewToOldValueMap.insert(std::make_pair(NewCall, II->second));
-      FI.NewToOldValueMap.erase(II);
-    }
-  }
-
-  CI.getParent()->getInstList().erase(&CI);
-}
diff --git a/poolalloc/lib/PoolAllocate/PoolAllocate.h b/poolalloc/lib/PoolAllocate/PoolAllocate.h
deleted file mode 100644
index b6806c1..0000000
--- a/poolalloc/lib/PoolAllocate/PoolAllocate.h
+++ /dev/null
@@ -1,156 +0,0 @@
-//===-- PoolAllocate.h - Pool allocation pass -------------------*- C++ -*-===//
-//
-// This transform changes programs so that disjoint data structures are
-// allocated out of different pools of memory, increasing locality.  This header
-// file exposes information about the pool allocation itself so that follow-on
-// passes may extend or use the pool allocation for analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_POOLALLOCATE_H
-#define LLVM_TRANSFORMS_POOLALLOCATE_H
-
-#include "llvm/Pass.h"
-#include "Support/hash_set"
-#include "Support/EquivalenceClasses.h"
-class BUDataStructures;
-class TDDataStructures;
-class DSNode;
-class DSGraph;
-class CallInst;
-
-namespace PA {
-  /// FuncInfo - Represent the pool allocation information for one function in
-  /// the program.  Note that many functions must actually be cloned in order
-  /// for pool allocation to add arguments to the function signature.  In this
-  /// case, the Clone and NewToOldValueMap information identify how the clone
-  /// maps to the original function...
-  ///
-  struct FuncInfo {
-    /// MarkedNodes - The set of nodes which are not locally pool allocatable in
-    /// the current function.
-    ///
-    hash_set<DSNode*> MarkedNodes;
-
-    /// Clone - The cloned version of the function, if applicable.
-    Function *Clone;
-
-    /// ArgNodes - The list of DSNodes which have pools passed in as arguments.
-    /// 
-    std::vector<DSNode*> ArgNodes;
-
-    /// In order to handle indirect functions, the start and end of the 
-    /// arguments that are useful to this function. 
-    /// The pool arguments useful to this function are PoolArgFirst to 
-    /// PoolArgLast not inclusive.
-    int PoolArgFirst, PoolArgLast;
-    
-    /// PoolDescriptors - The Value* (either an argument or an alloca) which
-    /// defines the pool descriptor for this DSNode.  Pools are mapped one to
-    /// one with nodes in the DSGraph, so this contains a pointer to the node it
-    /// corresponds to.  In addition, the pool is initialized by calling the
-    /// "poolinit" library function with a chunk of memory allocated with an
-    /// alloca instruction.  This entry contains a pointer to that alloca if the
-    /// pool is locally allocated or the argument it is passed in through if
-    /// not.
-    /// Note: Does not include pool arguments that are passed in because of
-    /// indirect function calls that are not used in the function.
-    std::map<DSNode*, Value*> PoolDescriptors;
-
-    /// NewToOldValueMap - When and if a function needs to be cloned, this map
-    /// contains a mapping from all of the values in the new function back to
-    /// the values they correspond to in the old function.
-    ///
-    std::map<Value*, const Value*> NewToOldValueMap;
-  };
-}
-
-/// PoolAllocate - The main pool allocation pass
-///
-class PoolAllocate : public Pass {
-  Module *CurModule;
-  BUDataStructures *BU;
-
-  TDDataStructures *TDDS;
-
-  hash_set<Function*> InlinedFuncs;
-  
-  std::map<Function*, PA::FuncInfo> FunctionInfo;
-
-  void buildIndirectFunctionSets(Module &M);   
-
-  void FindFunctionPoolArgs(Function &F);   
-  
-  // Debug function to print the FuncECs
-  void printFuncECs();
-  
- public:
-  Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolAllocArray, *PoolFree;
-
-  // Equivalence class where functions that can potentially be called via
-  // the same function pointer are in the same class.
-  EquivalenceClasses<Function *> FuncECs;
-
-  // Map from an Indirect CallInst to the set of Functions that it can point to
-  std::multimap<CallInst *, Function *> CallInstTargets;
-
-  // This maps an equivalence class to the last pool argument number for that 
-  // class. This is used because the pool arguments for all functions within
-  // an equivalence class is passed to all the functions in that class.
-  // If an equivalence class does not require pool arguments, it is not
-  // on this map.
-  std::map<Function *, int> EqClass2LastPoolArg;
-
-  // Exception flags
-  // CollapseFlag set if all data structures are not pool allocated, due to
-  // collapsing of nodes in the DS graph
-  unsigned CollapseFlag;
-  
- public:
-  bool run(Module &M);
-  
-  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-  
-  BUDataStructures &getBUDataStructures() const { return *BU; }
-  
-  PA::FuncInfo *getFuncInfo(Function &F) {
-    std::map<Function*, PA::FuncInfo>::iterator I = FunctionInfo.find(&F);
-    return I != FunctionInfo.end() ? &I->second : 0;
-  }
-
-  Module *getCurModule() { return CurModule; }
-
- private:
-  
-  /// AddPoolPrototypes - Add prototypes for the pool functions to the
-  /// specified module and update the Pool* instance variables to point to
-  /// them.
-  ///
-  void AddPoolPrototypes();
-  
-  /// MakeFunctionClone - If the specified function needs to be modified for
-  /// pool allocation support, make a clone of it, adding additional arguments
-  /// as neccesary, and return it.  If not, just return null.
-  ///
-  Function *MakeFunctionClone(Function &F);
-  
-  /// ProcessFunctionBody - Rewrite the body of a transformed function to use
-  /// pool allocation where appropriate.
-  ///
-  void ProcessFunctionBody(Function &Old, Function &New);
-  
-  /// CreatePools - This creates the pool initialization and destruction code
-  /// for the DSNodes specified by the NodesToPA list.  This adds an entry to
-  /// the PoolDescriptors map for each DSNode.
-  ///
-  void CreatePools(Function &F, const std::vector<DSNode*> &NodesToPA,
-                   std::map<DSNode*, Value*> &PoolDescriptors);
-  
-  void TransformFunctionBody(Function &F, Function &OldF,
-                             DSGraph &G, PA::FuncInfo &FI);
-
-  void InlineIndirectCalls(Function &F, DSGraph &G, 
-			   hash_set<Function*> &visited);
-};
-
-#endif
diff --git a/poolalloc/runtime/PoolAllocator/PoolAllocatorBitMask.cpp b/poolalloc/runtime/PoolAllocator/PoolAllocatorBitMask.cpp
deleted file mode 100644
index b3a715f..0000000
--- a/poolalloc/runtime/PoolAllocator/PoolAllocatorBitMask.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#undef assert
-#define assert(X)
-
-
-/* In the current implementation, each slab in the pool has NODES_PER_SLAB
- * nodes unless the isSingleArray flag is set in which case it contains a
- * single array of size ArraySize. Small arrays (size <= NODES_PER_SLAB) are
- * still allocated in the slabs of size NODES_PER_SLAB
- */
-#define NODES_PER_SLAB 512 
-
-typedef struct PoolTy {
-  void    *Data;
-  unsigned NodeSize;
-  unsigned FreeablePool; /* Set to false if the memory from this pool cannot be
-			    freed before destroy*/
-  
-} PoolTy;
-
-/* PoolSlab Structure - Hold NODES_PER_SLAB objects of the current node type.
- *   Invariants: FirstUnused <= LastUsed+1
- */
-typedef struct PoolSlab {
-  unsigned FirstUnused;     /* First empty node in slab    */
-  int LastUsed;             /* Last allocated node in slab */
-  struct PoolSlab *Next;
-  unsigned char AllocatedBitVector[NODES_PER_SLAB/8];
-  unsigned char StartOfAllocation[NODES_PER_SLAB/8];
-
-  unsigned isSingleArray;   /* If this slab is used for exactly one array */
-  /* The array is allocated from the start to the end of the slab */
-  unsigned ArraySize;       /* The size of the array allocated */ 
-
-  char Data[1];   /* Buffer to hold data in this slab... variable sized */
-
-} PoolSlab;
-
-#define NODE_ALLOCATED(POOLSLAB, NODENUM) \
-   ((POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] & (1 << ((NODENUM) & 7)))
-#define MARK_NODE_ALLOCATED(POOLSLAB, NODENUM) \
-   (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7)
-#define MARK_NODE_FREE(POOLSLAB, NODENUM) \
-   (POOLSLAB)->AllocatedBitVector[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7))
-#define ALLOCATION_BEGINS(POOLSLAB, NODENUM) \
-   ((POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] & (1 << ((NODENUM) & 7)))
-#define SET_START_BIT(POOLSLAB, NODENUM) \
-   (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] |= 1 << ((NODENUM) & 7)
-#define CLEAR_START_BIT(POOLSLAB, NODENUM) \
-   (POOLSLAB)->StartOfAllocation[(NODENUM) >> 3] &= ~(1 << ((NODENUM) & 7))
-
-
-/* poolinit - Initialize a pool descriptor to empty
- */
-void poolinit(PoolTy *Pool, unsigned NodeSize) {
-  if (!Pool) {
-    printf("Null pool pointer passed into poolinit!\n");
-    exit(1);
-  }
-
-  Pool->NodeSize = NodeSize;
-  Pool->Data = 0;
-
-  Pool->FreeablePool = 1;
-
-}
-
-void poolmakeunfreeable(PoolTy *Pool) {
-  if (!Pool) {
-    printf("Null pool pointer passed in to poolmakeunfreeable!\n");
-    exit(1);
-  }
-
-  Pool->FreeablePool = 0;
-}
-
-/* pooldestroy - Release all memory allocated for a pool
- */
-void pooldestroy(PoolTy *Pool) {
-  PoolSlab *PS;
-  if (!Pool) {
-    printf("Null pool pointer passed in to pooldestroy!\n");
-    exit(1);
-  }
-
-  PS = (PoolSlab*)Pool->Data;
-  while (PS) {
-    PoolSlab *Next = PS->Next;
-    free(PS);
-    PS = Next;
-  }
-}
-
-static void *FindSlabEntry(PoolSlab *PS, unsigned NodeSize) {
-  /* Loop through all of the slabs looking for one with an opening */
-  for (; PS; PS = PS->Next) {
-
-    /* If the slab is a single array, go on to the next slab */
-    /* Don't allocate single nodes in a SingleArray slab */
-    if (PS->isSingleArray) 
-      continue;
-
-    /* Check to see if there are empty entries at the end of the slab... */
-    if (PS->LastUsed < NODES_PER_SLAB-1) {
-      /* Mark the returned entry used */
-      MARK_NODE_ALLOCATED(PS, PS->LastUsed+1);
-      SET_START_BIT(PS, PS->LastUsed+1);
-
-      /* If we are allocating out the first unused field, bump its index also */
-      if (PS->FirstUnused == PS->LastUsed+1)
-        PS->FirstUnused++;
-
-      /* Return the entry, increment LastUsed field. */
-      return &PS->Data[0] + ++PS->LastUsed * NodeSize;
-    }
-
-    /* If not, check to see if this node has a declared "FirstUnused" value that
-     * is less than the number of nodes allocated...
-     */
-    if (PS->FirstUnused < NODES_PER_SLAB) {
-      /* Successfully allocate out the first unused node */
-      unsigned Idx = PS->FirstUnused;
-
-      MARK_NODE_ALLOCATED(PS, Idx);
-      SET_START_BIT(PS, Idx);
-
-      /* Increment FirstUnused to point to the new first unused value... */
-      do {
-        ++PS->FirstUnused;
-      } while (PS->FirstUnused < NODES_PER_SLAB &&
-               NODE_ALLOCATED(PS, PS->FirstUnused));
-
-      return &PS->Data[0] + Idx*NodeSize;
-    }
-  }
-
-  /* No empty nodes available, must grow # slabs! */
-  return 0;
-}
-
-char *poolalloc(PoolTy *Pool) {
-  unsigned NodeSize;
-  PoolSlab *PS;
-  void *Result;
-
-  if (!Pool) {
-    printf("Null pool pointer passed in to poolalloc!\n");
-    exit(1);
-  }
-  
-  NodeSize = Pool->NodeSize;
-  // Return if this pool has size 0
-  if (NodeSize == 0)
-    return 0;
-
-  PS = (PoolSlab*)Pool->Data;
-
-  if ((Result = FindSlabEntry(PS, NodeSize)))
-    return Result;
-
-  /* Otherwise we must allocate a new slab and add it to the list */
-  PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1);
-
-  if (!PS) {
-    printf("poolalloc: Could not allocate memory!");
-    exit(1);
-  }
-
-  /* Initialize the slab to indicate that the first element is allocated */
-  PS->FirstUnused = 1;
-  PS->LastUsed = 0;
-  /* This is not a single array */
-  PS->isSingleArray = 0;
-  PS->ArraySize = 0;
-  
-  MARK_NODE_ALLOCATED(PS, 0);
-  SET_START_BIT(PS, 0);
-
-  /* Add the slab to the list... */
-  PS->Next = (PoolSlab*)Pool->Data;
-  Pool->Data = PS;
-  return &PS->Data[0];
-}
-
-void poolfree(PoolTy *Pool, char *Node) {
-  unsigned NodeSize, Idx;
-  PoolSlab *PS;
-  PoolSlab **PPS;
-  unsigned idxiter;
-
-  if (!Pool) {
-    printf("Null pool pointer passed in to poolfree!\n");
-    exit(1);
-  }
-
-  NodeSize = Pool->NodeSize;
-
-  // Return if this pool has size 0
-  if (NodeSize == 0)
-    return;
-
-  PS = (PoolSlab*)Pool->Data;
-  PPS = (PoolSlab**)&Pool->Data;
-
-  /* Search for the slab that contains this node... */
-  while (&PS->Data[0] > Node || &PS->Data[NodeSize*NODES_PER_SLAB-1] < Node) {
-    if (!PS) { 
-      printf("poolfree: node being free'd not found in allocation pool specified!\n");
-      exit(1);
-    }
-
-    PPS = &PS->Next;
-    PS = PS->Next;
-  }
-
-  /* PS now points to the slab where Node is */
-
-  Idx = (Node-&PS->Data[0])/NodeSize;
-  assert(Idx < NODES_PER_SLAB && "Pool slab searching loop broken!");
-
-  if (PS->isSingleArray) {
-
-    /* If this slab is a SingleArray */
-
-    if (Idx != 0) {
-      printf("poolfree: Attempt to free middle of allocated array\n");
-      exit(1);
-    }
-    if (!NODE_ALLOCATED(PS,0)) {
-      printf("poolfree: Attempt to free node that is already freed\n");
-      exit(1);
-    }
-    /* Mark this SingleArray slab as being free by just marking the first
-       entry as free*/
-    MARK_NODE_FREE(PS, 0);
-  } else {
-    
-    /* If this slab is not a SingleArray */
-    
-    if (!ALLOCATION_BEGINS(PS, Idx)) { 
-      printf("poolfree: Attempt to free middle of allocated array\n");
-    }
-
-    /* Free the first node */
-    if (!NODE_ALLOCATED(PS, Idx)) {
-      printf("poolfree: Attempt to free node that is already freed\n");
-      exit(1); 
-    }
-    CLEAR_START_BIT(PS, Idx);
-    MARK_NODE_FREE(PS, Idx);
-    
-    // Free all nodes 
-    idxiter = Idx + 1;
-    while (idxiter < NODES_PER_SLAB && (!ALLOCATION_BEGINS(PS,idxiter)) && 
-	   (NODE_ALLOCATED(PS, idxiter))) {
-      MARK_NODE_FREE(PS, idxiter);
-      ++idxiter;
-    }
-
-    /* Update the first free field if this node is below the free node line */
-    if (Idx < PS->FirstUnused) PS->FirstUnused = Idx;
-    
-    /* If we are not freeing the last element in a slab... */
-    if (idxiter - 1 != PS->LastUsed) {
-      return;
-    }
-
-    /* Otherwise we are freeing the last element in a slab... shrink the
-     * LastUsed marker down to last used node.
-     */
-    PS->LastUsed = Idx;
-    do {
-      --PS->LastUsed;
-      /* Fixme, this should scan the allocated array an entire byte at a time 
-       * for performance!
-       */
-    } while (PS->LastUsed >= 0 && (!NODE_ALLOCATED(PS, PS->LastUsed)));
-    
-    assert(PS->FirstUnused <= PS->LastUsed+1 &&
-	   "FirstUnused field was out of date!");
-  }
-    
-  /* Ok, if this slab is empty, we unlink it from the of slabs and either move
-   * it to the head of the list, or free it, depending on whether or not there
-   * is already an empty slab at the head of the list.
-   */
-  /* Do this only if the pool is freeable */
-  if (Pool->FreeablePool) {
-    if (PS->isSingleArray) {
-      /* If it is a SingleArray, just free it */
-      *PPS = PS->Next;
-      free(PS);
-    } else if (PS->LastUsed == -1) {   /* Empty slab? */
-      PoolSlab *HeadSlab;
-      *PPS = PS->Next;   /* Unlink from the list of slabs... */
-      
-      HeadSlab = (PoolSlab*)Pool->Data;
-      if (HeadSlab && HeadSlab->LastUsed == -1){/*List already has empty slab?*/
-	free(PS);                               /*Free memory for slab */
-      } else {
-	PS->Next = HeadSlab;                    /*No empty slab yet, add this*/
-	Pool->Data = PS;                        /*one to the head of the list */
-      }
-    }
-  } else {
-    /* Pool is not freeable for safety reasons */
-    /* Leave it in the list of PoolSlabs as an empty PoolSlab */
-    if (!PS->isSingleArray)
-      if (PS->LastUsed == -1) {
-	PS->FirstUnused = 0;
-	
-	/* Do not free the pool, but move it to the head of the list if there is
-	   no empty slab there already */
-	PoolSlab *HeadSlab;
-	HeadSlab = (PoolSlab*)Pool->Data;
-	if (HeadSlab && HeadSlab->LastUsed != -1) {
-	  PS->Next = HeadSlab;
-	  Pool->Data = PS;
-	}
-      }
-  }
-}
-
-/* The poolallocarray version of FindSlabEntry */
-static void *FindSlabEntryArray(PoolSlab *PS, unsigned NodeSize, 
-				unsigned Size) {
-  unsigned i;
-
-  /* Loop through all of the slabs looking for one with an opening */
-  for (; PS; PS = PS->Next) {
-    
-    /* For large array allocation */
-    if (Size > NODES_PER_SLAB) {
-      /* If this slab is a SingleArray that is free with size > Size, use it */
-      if (PS->isSingleArray && !NODE_ALLOCATED(PS,0) && PS->ArraySize >= Size) {
-	/* Allocate the array in this slab */
-	MARK_NODE_ALLOCATED(PS,0); /* In a single array, only the first node
-				      needs to be marked */
-	return &PS->Data[0];
-      } else
-	continue;
-    } else if (PS->isSingleArray)
-      continue; /* Do not allocate small arrays in SingleArray slabs */
-
-    /* For small array allocation */
-    /* Check to see if there are empty entries at the end of the slab... */
-    if (PS->LastUsed < NODES_PER_SLAB-Size) {
-      /* Mark the returned entry used and set the start bit*/
-      SET_START_BIT(PS, PS->LastUsed + 1);
-      for (i = PS->LastUsed + 1; i <= PS->LastUsed + Size; ++i)
-	MARK_NODE_ALLOCATED(PS, i);
-
-      /* If we are allocating out the first unused field, bump its index also */
-      if (PS->FirstUnused == PS->LastUsed+1)
-        PS->FirstUnused += Size;
-
-      /* Increment LastUsed */
-      PS->LastUsed += Size;
-
-      /* Return the entry */
-      return &PS->Data[0] + (PS->LastUsed - Size + 1) * NodeSize;
-    }
-
-    /* If not, check to see if this node has a declared "FirstUnused" value
-     * starting which Size nodes can be allocated
-     */
-    if (PS->FirstUnused < NODES_PER_SLAB - Size + 1 &&
-	(PS->LastUsed < PS->FirstUnused || 
-	 PS->LastUsed - PS->FirstUnused >= Size)) {
-      unsigned Idx = PS->FirstUnused, foundArray;
-      
-      /* Check if there is a continuous array of Size nodes starting 
-	 FirstUnused */
-      foundArray = 1;
-      for (i = Idx; (i < Idx + Size) && foundArray; ++i)
-	if (NODE_ALLOCATED(PS, i))
-	  foundArray = 0;
-
-      if (foundArray) {
-	/* Successfully allocate starting from the first unused node */
-	SET_START_BIT(PS, Idx);
-	for (i = Idx; i < Idx + Size; ++i)
-	  MARK_NODE_ALLOCATED(PS, i);
-	
-	PS->FirstUnused += Size;
-	while (PS->FirstUnused < NODES_PER_SLAB &&
-               NODE_ALLOCATED(PS, PS->FirstUnused)) {
-	  ++PS->FirstUnused;
-	}
-	return &PS->Data[0] + Idx*NodeSize;
-      }
-      
-    }
-  }
-
-  /* No empty nodes available, must grow # slabs! */
-  return 0;
-}
-
-char* poolallocarray(PoolTy* Pool, unsigned Size) {
-  unsigned NodeSize;
-  PoolSlab *PS;
-  void *Result;
-  unsigned i;
-
-  if (!Pool) {
-    printf("Null pool pointer passed to poolallocarray!\n");
-    exit(1);
-  }
-
-  NodeSize = Pool->NodeSize;
-
-  // Return if this pool has size 0
-  if (NodeSize == 0)
-    return 0;
-
-  PS = (PoolSlab*)Pool->Data;
-
-  if ((Result = FindSlabEntryArray(PS, NodeSize,Size)))
-    return Result;
-
-  /* Otherwise we must allocate a new slab and add it to the list */
-  if (Size > NODES_PER_SLAB) {
-    /* Allocate a new slab of size Size */
-    PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*Size-1);
-    if (!PS) {
-      printf("poolallocarray: Could not allocate memory!\n");
-      exit(1);
-    }
-    PS->isSingleArray = 1;
-    PS->ArraySize = Size;
-    MARK_NODE_ALLOCATED(PS, 0);
-  } else {
-    PS = (PoolSlab*)malloc(sizeof(PoolSlab)+NodeSize*NODES_PER_SLAB-1);
-    if (!PS) {
-      printf("poolallocarray: Could not allocate memory!\n");
-      exit(1);
-    }
-
-    /* Initialize the slab to indicate that the first element is allocated */
-    PS->FirstUnused = Size;
-    PS->LastUsed = Size - 1;
-    
-    PS->isSingleArray = 0;
-    PS->ArraySize = 0;
-
-    SET_START_BIT(PS, 0);
-    for (i = 0; i < Size; ++i) {
-      MARK_NODE_ALLOCATED(PS, i);
-    }
-  }
-
-  /* Add the slab to the list... */
-  PS->Next = (PoolSlab*)Pool->Data;
-  Pool->Data = PS;
-  return &PS->Data[0];
-}