[llvm-commits] [poolalloc] r98062 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DSGraphTraits.h include/dsa/DSNode.h include/dsa/DSSupport.h lib/DSA/Basic.cpp lib/DSA/BottomUpClosure.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/Printer.cpp lib/DSA/TopDownClosure.cpp

alenhar2 at llvm.org alenhar2 at llvm.org
Tue Mar 9 08:48:35 PST 2010


Author: alenhar2
Date: Tue Mar  9 10:48:35 2010
New Revision: 98062

URL: http://llvm.org/viewvc/llvm-project?rev=98062&view=rev
Log:
Add byte offset based sets of types
Add byte offset links
add multiple entry points, WIP
get rid of stl/ext hash_
fix graph printer
api update to 2.7
handle malloc, sometimes (TODO: free, generalized allocator framework)
remove cruft
factor common operations out


Modified:
    poolalloc/trunk/include/dsa/DSGraph.h
    poolalloc/trunk/include/dsa/DSGraphTraits.h
    poolalloc/trunk/include/dsa/DSNode.h
    poolalloc/trunk/include/dsa/DSSupport.h
    poolalloc/trunk/lib/DSA/Basic.cpp
    poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
    poolalloc/trunk/lib/DSA/DataStructure.cpp
    poolalloc/trunk/lib/DSA/Local.cpp
    poolalloc/trunk/lib/DSA/Printer.cpp
    poolalloc/trunk/lib/DSA/TopDownClosure.cpp

Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Tue Mar  9 10:48:35 2010
@@ -24,7 +24,7 @@
 
 namespace llvm {
 
-
+class TargetData;
 class GlobalValue;
 
 //===----------------------------------------------------------------------===//

Modified: poolalloc/trunk/include/dsa/DSGraphTraits.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraphTraits.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraphTraits.h (original)
+++ poolalloc/trunk/include/dsa/DSGraphTraits.h Tue Mar  9 10:48:35 2010
@@ -34,7 +34,7 @@
   DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {}   // begin iterator
   DSNodeIterator(NodeTy *N, bool) : Node(N) {         // Create end iterator
     if (N != 0) {
-      Offset = N->getNumLinks();
+      Offset = N->getSize();
       if (Offset == 0 && Node->getForwardNode() &&
           Node->isDeadNode())        // Model Forward link
         Offset += 1;

Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Tue Mar  9 10:48:35 2010
@@ -15,6 +15,8 @@
 #define LLVM_ANALYSIS_DSNODE_H
 
 #include "dsa/DSSupport.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/ilist_node.h"
 
 #include <map>
@@ -24,7 +26,6 @@
 
 template<typename BaseType>
 class DSNodeIterator;          // Data structure graph traversal iterator
-class TargetData;
 
 //===----------------------------------------------------------------------===//
 /// DSNode - Data structure node class
@@ -34,9 +35,14 @@
 /// different types represented in this object.
 ///
 class DSNode : public ilist_node<DSNode> {
+public:
+  typedef std::map<unsigned, std::set<const Type*> > TyMapTy;
+  typedef std::map<unsigned, DSNodeHandle> LinkMapTy;
+
+private:
   friend struct ilist_sentinel_traits<DSNode>;
   //Sentinel
-  DSNode() : NumReferrers(0), Size(0), Ty(0), NodeType(0) {}
+  DSNode() : NumReferrers(0), Size(0), NodeType(0) {}
   
   /// NumReferrers - The number of DSNodeHandles pointing to this node... if
   /// this is a forwarding node, then this is the number of node handles which
@@ -51,12 +57,6 @@
   ///
   DSNodeHandle ForwardNH;
 
-  /// Next, Prev - These instance variables are used to keep the node on a
-  /// doubly-linked ilist in the DSGraph.
-  ///
-  //DSNode *Next, *Prev;
-  //friend struct ilist_traits<DSNode>;
-
   /// Size - The current size of the node.  This should be equal to the size of
   /// the current type record.
   ///
@@ -66,18 +66,14 @@
   ///
   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.
+  /// TyMap - Keep track of the loadable types and offsets those types are seen
+  // at.
+  TyMapTy TyMap;
+
+  /// Links - Contains one entry for every byte in this memory
+  /// object.  
   ///
-  std::vector<DSNodeHandle> Links;
+  LinkMapTy Links;
 
   /// Globals - The list of global values that are merged into this node.
   ///
@@ -100,13 +96,14 @@
     ReadNode        = 1 << 8,   // This node is read in this context
 
     ArrayNode       = 1 << 9,   // This node is treated like an array
-    ExternalNode    = 1 << 10,  // This node comes from an external source
-    IntToPtrNode    = 1 << 11,   // This node comes from an int cast
-    PtrToIntNode    = 1 << 12,  // This node excapes to an int cast
-    VAStartNode     = 1 << 13,  // This node excapes to an int cast
+    CollapsedNode   = 1 << 10,  // This node is collapsed
+    ExternalNode    = 1 << 11,  // This node comes from an external source
+    IntToPtrNode    = 1 << 12,   // This node comes from an int cast
+    PtrToIntNode    = 1 << 13,  // This node excapes to an int cast
+    VAStartNode     = 1 << 14,  // This node excapes to an int cast
 
     //#ifndef NDEBUG
-    DeadNode        = 1 << 14,   // This node is dead and should not be pointed to
+    DeadNode        = 1 << 15,   // This node is dead and should not be pointed to
     //#endif
 
     Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode
@@ -123,7 +120,7 @@
   /// DSNode ctor - Create a node of the specified type, inserting it into the
   /// specified graph.
   ///
-  DSNode(const Type *T, DSGraph *G);
+  explicit DSNode(DSGraph *G);
 
   /// DSNode "copy ctor" - Copy the specified node, inserting it into the
   /// specified graph.  If NullLinks is true, then null out all of the links,
@@ -149,6 +146,21 @@
   inline const_iterator begin() const;
   inline const_iterator end() const;
 
+  /// type_* - Provide iterators for accessing types.  Some types may be null
+  TyMapTy::iterator type_begin() { return TyMap.begin(); }
+  TyMapTy::iterator type_end()   { return TyMap.end(); }
+  TyMapTy::const_iterator type_begin() const { return TyMap.begin(); }
+  TyMapTy::const_iterator type_end()   const { return TyMap.end(); }
+
+  /// edge_* - Provide iterators for accessing outgoing edges.  Some outgoing
+  /// edges may be null.
+  typedef LinkMapTy::iterator edge_iterator;
+  typedef LinkMapTy::const_iterator const_edge_iterator;
+  edge_iterator edge_begin() { return Links.begin(); }
+  edge_iterator edge_end() { return Links.end(); }
+  const_edge_iterator edge_begin() const { return Links.begin(); }
+  const_edge_iterator edge_end() const { return Links.end(); }
+
   //===--------------------------------------------------
   // Accessors
 
@@ -156,12 +168,6 @@
   ///
   unsigned getSize() const { return Size; }
 
-  /// getType - Return the node type of this object...
-  ///
-  const Type *getType() const { return Ty; }
-
-  bool isArray() const { return NodeType & ArrayNode; }
-
   /// hasNoReferrers - Return true if nothing is pointing to this node at all.
   ///
   bool hasNoReferrers() const { return getNumReferrers() == 0; }
@@ -171,14 +177,10 @@
   /// 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; }
 
-
-  /// getTargetData - Get the target data object used to construct this node.
-  ///
-  const TargetData &getTargetData() const;
-
   /// getForwardNode - This method returns the node that this node is forwarded
   /// to, if any.
   ///
@@ -200,38 +202,30 @@
     delete this;
   }
 
+  void growSize(unsigned NSize) {
+    assert(NSize > Size && "Cannot shrink");
+    assert(!isCollapsedNode() && "growing a collapsed node");
+    Size = NSize;
+  }
+
   /// hasLink - Return true if this memory object has a link in slot LinkNo
   ///
   bool hasLink(unsigned Offset) const {
-    assert(Offset < Links.size() && "Link index is out of range!");
-    return Links[Offset].getNode();
+    assert(Offset < getSize() && "Link index is out of range!");
+    return Links.find(Offset) != Links.end();
   }
 
   /// getLink - Return the link at the specified offset.
   ///
   DSNodeHandle &getLink(unsigned Offset) {
-    assert(Offset < Links.size() && "Link index is out of range!");
+    assert(Offset < getSize() && "Link index is out of range!");
     return Links[Offset];
   }
   const DSNodeHandle &getLink(unsigned Offset) const {
-    assert(Offset < Links.size() && "Link index is out of range!");
-    return Links[Offset];
+    assert(hasLink(Offset) && "No Link");
+    return Links.find(Offset)->second;
   }
 
-  /// getNumLinks - Return the number of links in a node...
-  ///
-  unsigned getNumLinks() const { return Links.size(); }
-
-  /// edge_* - Provide iterators for accessing outgoing edges.  Some outgoing
-  /// edges may be null.
-  typedef std::vector<DSNodeHandle>::iterator edge_iterator;
-  typedef std::vector<DSNodeHandle>::const_iterator const_edge_iterator;
-  edge_iterator edge_begin() { return Links.begin(); }
-  edge_iterator edge_end() { return Links.end(); }
-  const_edge_iterator edge_begin() const { return Links.begin(); }
-  const_edge_iterator edge_end() const { return Links.end(); }
-
-
   /// 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
@@ -239,12 +233,10 @@
   /// 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);
-
+  /// FIXME: description
+  void mergeTypeInfo(const Type *Ty, unsigned Offset);
+  void mergeTypeInfo(TyMapTy::const_iterator TyIt, unsigned Offset = 0);
+ 
   /// 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
@@ -263,7 +255,7 @@
   /// instead one of the higher level methods should be used, below.
   ///
   void setLink(unsigned Offset, const DSNodeHandle &NH) {
-    assert(Offset < Links.size() && "Link index is out of range!");
+    assert(Offset < getSize() && "Link index is out of range!");
     Links[Offset] = NH;
   }
 
@@ -341,6 +333,7 @@
   bool isModifiedNode()   const { return NodeType & ModifiedNode;  }
   bool isReadNode()       const { return NodeType & ReadNode;      }
   bool isArrayNode()      const { return NodeType & ArrayNode;     }
+  bool isCollapsedNode()  const { return NodeType & CollapsedNode; }
   bool isIncompleteNode() const { return NodeType & IncompleteNode;}
   bool isCompleteNode()   const { return !isIncompleteNode();      }
   bool isDeadNode()       const { return NodeType & DeadNode;      }
@@ -358,6 +351,7 @@
   DSNode* setModifiedMarker()   { NodeType |= ModifiedNode;   return this; }
   DSNode* setReadMarker()       { NodeType |= ReadNode;       return this; }
   DSNode* setArrayMarker()      { NodeType |= ArrayNode;      return this; }
+  DSNode* setCollapsedMarker()  { NodeType |= CollapsedNode;  return this; }
   DSNode* setIncompleteMarker() { NodeType |= IncompleteNode; return this; }
   DSNode* setExternalMarker()   { NodeType |= ExternalNode;   return this; }
   DSNode* setIntToPtrMarker()   { NodeType |= IntToPtrNode;   return this; }
@@ -395,7 +389,7 @@
   /// 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(std::set<const DSNode*> &ReachableNodes) const;
+  void markReachableNodes(llvm::DenseSet<const DSNode*> &ReachableNodes) const;
 
 private:
   friend class DSNodeHandle;

Modified: poolalloc/trunk/include/dsa/DSSupport.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSSupport.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSSupport.h (original)
+++ poolalloc/trunk/include/dsa/DSSupport.h Tue Mar  9 10:48:35 2010
@@ -19,6 +19,7 @@
 #include <map>
 #include <set>
 
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/Support/CallSite.h"
 
 namespace llvm {
@@ -54,8 +55,11 @@
   mutable unsigned Offset;
   void operator==(const DSNode *N);  // DISALLOW, use to promote N to nodehandle
 public:
+
+  DSNodeHandle() : N(0), Offset(0) {}
+
   // Allow construction, destruction, and assignment...
-  DSNodeHandle(DSNode *n = 0, unsigned offs = 0) : N(0), Offset(0) {
+  DSNodeHandle(DSNode *n, unsigned offs = 0) : N(0), Offset(0) {
     setTo(n, offs);
   }
   DSNodeHandle(const DSNodeHandle &H) : N(0), Offset(0) {
@@ -292,7 +296,7 @@
   /// 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(std::set<const DSNode*> &Nodes) const;
+  void markReachableNodes(DenseSet<const DSNode*> &Nodes) const;
 
   bool operator<(const DSCallSite &CS) const {
     if (isDirectCall()) {      // This must sort by callee first!

Modified: poolalloc/trunk/lib/DSA/Basic.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Basic.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Basic.cpp (original)
+++ poolalloc/trunk/lib/DSA/Basic.cpp Tue Mar  9 10:48:35 2010
@@ -38,11 +38,9 @@
   //
   // Create a void pointer type.  This is simply a pointer to an 8 bit value.
   //
-  const IntegerType * IT = IntegerType::getInt8Ty(M.getContext());
-  const PointerType * VoidPtrTy = PointerType::getUnqual(IT);
 
-  DSNode * GVNodeInternal = new DSNode(VoidPtrTy, GlobalsGraph);
-  DSNode * GVNodeExternal = new DSNode(VoidPtrTy, GlobalsGraph);
+  DSNode * GVNodeInternal = new DSNode(GlobalsGraph);
+  DSNode * GVNodeExternal = new DSNode(GlobalsGraph);
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I) {
     if (I->isDeclaration()) {
@@ -64,7 +62,7 @@
   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
     if (!F->isDeclaration()) {
       DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
-      DSNode * Node = new DSNode(VoidPtrTy, G);
+      DSNode * Node = new DSNode(G);
           
       if (!F->hasInternalLinkage())
         Node->setExternalMarker();

Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Mar  9 10:48:35 2010
@@ -56,15 +56,13 @@
 
   for (std::vector<const Function*>::iterator ii = EntryPoints.begin(),
           ee = EntryPoints.end(); ii != ee; ++ii)
-    if (!hasDSGraph(**ii))
+    if (!hasDSGraph(**ii)) {
+      errs() << debugname << ": Main Function: " << (*ii)->getName() << "\n";
       calculateGraphs(*ii, Stack, NextID, ValMap);
+      CloneAuxIntoGlobal(getDSGraph(**ii));
+    }
 
-   for (std::vector<const Function*>::iterator ii = EntryPoints.begin(),
-          ee = EntryPoints.end(); ii != ee; ++ii) {
-    cloneGlobalsInto(getDSGraph(**ii));
-    calculateGraph(getDSGraph(**ii));
-    CloneAuxIntoGlobal(getDSGraph(**ii));
-  }
+  //errs() << "done main Funcs\n";
 
   // Calculate the graphs for any functions that are unreachable from main...
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
@@ -78,6 +76,8 @@
       CloneAuxIntoGlobal(getDSGraph(*I));
     }
 
+  //errs() << "done unreachable Funcs\n";
+
   // If we computed any temporary indcallgraphs, free them now.
   for (std::map<std::vector<const Function*>,
          std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I =
@@ -133,7 +133,7 @@
       BadCalls.insert(*ii);
     else
       GoodCalls.insert(*ii);
-  std::set<const DSNode*> reachable;
+  DenseSet<const DSNode*> reachable;
   for (std::set<DSCallSite>::iterator ii = BadCalls.begin(),
          ee = BadCalls.end(); ii != ee; ++ii) {
     ii->getRetVal().getNode()->markReachableNodes(reachable);
@@ -142,7 +142,7 @@
   }
   for (std::set<DSCallSite>::iterator ii = GoodCalls.begin(),
          ee = GoodCalls.end(); ii != ee; ++ii)
-    if (reachable.find(ii->getCalleeNode()) == reachable.end())
+    if (reachable.count(ii->getCalleeNode()))
       GlobalsGraph->getAuxFunctionCalls()
         .erase(std::find(GlobalsGraph->getAuxFunctionCalls().begin(),
                          GlobalsGraph->getAuxFunctionCalls().end(),
@@ -341,6 +341,25 @@
 void BUDataStructures::calculateGraph(DSGraph* Graph) {
   DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
 
+  // If this graph contains the main function, clone the globals graph into this
+  // graph before we inline callees and other fun stuff.
+  bool ContainsMain = false;
+  DSGraph::ReturnNodesTy &ReturnNodes = Graph->getReturnNodes();
+
+  for (DSGraph::ReturnNodesTy::iterator I = ReturnNodes.begin(),
+       E = ReturnNodes.end(); I != E; ++I)
+    if (EP->isEntryPoint(I->first)) {
+      ContainsMain = true;
+      break;
+    }
+
+   // If this graph contains main, copy the contents of the globals graph over.
+   // Note that this is *required* for correctness.  If a callee contains a use
+   // of a global, we have to make sure to link up nodes due to global-argument
+   // bindings.
+   if (ContainsMain)
+     cloneGlobalsInto(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::list<DSCallSite> TempFCs;

Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Mar  9 10:48:35 2010
@@ -15,6 +15,7 @@
 #include "dsa/DataStructure.h"
 #include "dsa/DSGraph.h"
 #include "dsa/DSSupport.h"
+#include "dsa/DSNode.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
@@ -43,9 +44,6 @@
   STATISTIC (NumDNE            , "Number of nodes removed by reachability");
 //  STATISTIC (NumTrivialDNE     , "Number of nodes trivially removed");
 //  STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed");
-#ifdef LLVA_KERNEL
-  STATISTIC (LostPools         , "Number of pools lost to DSNode Merge");
-#endif
   static cl::opt<unsigned>
   DSAFieldLimit("dsa-field-limit", cl::Hidden,
                 cl::desc("Number of fields to track before collapsing a node"),
@@ -82,8 +80,12 @@
 
   N = Next;
   N->NumReferrers++;
-  if (N->Size <= Offset) {
-    assert(N->Size <= 1 && "Forwarded to shrunk but not collapsed node?");
+
+  if (N->isArrayNode())
+    Offset %= N->getSize();
+
+  if (N->getSize() <= Offset) {
+    assert(N->getSize() <= 1 && "Forwarded to shrunk but not collapsed node?");
     Offset = 0;
   }
   return N;
@@ -120,22 +122,20 @@
 // DSNode Implementation
 //===----------------------------------------------------------------------===//
 
-DSNode::DSNode(const Type *T, DSGraph *G)
-: NumReferrers(0), Size(0), ParentGraph(G), Ty(0), NodeType(0) {
+DSNode::DSNode(DSGraph *G)
+: NumReferrers(0), Size(0), ParentGraph(G), NodeType(0) {
   // Add the type entry if it is specified...
-  if (T) mergeTypeInfo(T, 0);
   if (G) G->addNode(this);
   ++NumNodeAllocated;
 }
 
 // DSNode copy constructor... do not copy over the referrers list!
 DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks)
-  : NumReferrers(0), Size(N.Size), ParentGraph(G),
-    Ty(N.Ty), Globals(N.Globals), NodeType(N.NodeType) {
+  : NumReferrers(0), Size(N.Size), ParentGraph(G), TyMap(N.TyMap),
+    Globals(N.Globals), NodeType(N.NodeType) {
   if (!NullLinks) {
     Links = N.Links;
-  } else
-    Links.resize(N.Links.size()); // Create the appropriate number of null links
+  }
   G->addNode(this);
   ++NumNodeAllocated;
 }
@@ -143,30 +143,13 @@
 DSNode::~DSNode() {
   dropAllReferences();
   assert(hasNoReferrers() && "Referrers to dead node exist!");
-
-#ifdef LLVA_KERNEL
-  //
-  // Remove all references to this node from the Pool Descriptor Map.
-  //
-  DEBUG(errs() << "LLVA: Removing " << this << "\n");
-  if (ParentGraph) {
-    hash_map<const DSNode *, MetaPoolHandle*> &pdm=ParentGraph->getPoolDescriptorsMap();
-    pdm.erase (this);
-  }
-#endif
-}
-
-/// getTargetData - Get the target data object used to construct this node.
-///
-const TargetData &DSNode::getTargetData() const {
-  return ParentGraph->getTargetData();
 }
 
 void DSNode::assertOK() const {
-  assert(((Ty && Ty->getTypeID() != Type::VoidTyID) ||
-         ((!Ty || Ty->getTypeID() == Type::VoidTyID) && (Size == 0 ||
-         (NodeType & DSNode::ArrayNode)))) &&
-         "Node not OK!");
+//  assert(((Ty && Ty->getTypeID() != Type::VoidTyID) ||
+//         ((!Ty || Ty->getTypeID() == Type::VoidTyID) && (Size == 0 ||
+//         (NodeType & DSNode::ArrayNode)))) &&
+//         "Node not OK!");
 
   assert(ParentGraph && "Node has no parent?");
   const DSScalarMap &SM = ParentGraph->getScalarMap();
@@ -188,7 +171,6 @@
   ForwardNH.setTo(To, Offset);
   NodeType = DeadNode;
   Size = 0;
-  Ty = 0;
 
   // Remove this node from the parent graph's Nodes list.
   ParentGraph->unlinkNode(this);
@@ -230,55 +212,45 @@
 void DSNode::foldNodeCompletely() {
   if (isNodeCompletelyFolded()) return;  // If this node is already folded...
 
+//  assert(0 && "Folding is happening");
+
   ++NumFolds;
 
   // If this node has a size that is <= 1, we don't need to create a forwarding
   // node.
   if (getSize() <= 1) {
-    NodeType |= DSNode::ArrayNode;
-    Ty = 0;
+    setCollapsedMarker();
     Size = 1;
     assert(Links.size() <= 1 && "Size is 1, but has more links?");
-    Links.resize(1);
   } else {
     // Create the node we are going to forward to.  This is required because
     // some referrers may have an offset that is > 0.  By forcing them to
     // forward, the forwarder has the opportunity to correct the offset.
-    DSNode *DestNode = new DSNode(0, ParentGraph);
-    DestNode->NodeType = NodeType|DSNode::ArrayNode;
-    DestNode->Ty = 0;
+    DSNode *DestNode = new DSNode(ParentGraph);
+    DestNode->NodeType = NodeType;
+    DestNode->setCollapsedMarker();
     DestNode->Size = 1;
     DestNode->Globals.swap(Globals);
-    
-    //    DOUT << "LLVA: foldNode: " << this << " becomes " << DestNode << "\n";
-#ifdef LLVA_KERNEL
-    //Again we have created a new DSNode, we need to fill in the
-    // pool desc map appropriately
-    assert(ParentGraph && "parent graph is not null \n"); 
-    hash_map<const DSNode *, MetaPoolHandle*> &pdm = ParentGraph->getPoolDescriptorsMap();
-    if (pdm.count(this) > 0) {
-      pdm[DestNode] = pdm[this];
-    } else {
-      //do nothing 
-    }
-#endif    
 
+    DSNodeHandle NH(DestNode);
+    
     // Start forwarding to the destination node...
     forwardNode(DestNode, 0);
 
-
     if (!Links.empty()) {
-      DestNode->Links.reserve(1);
-
-      DSNodeHandle NH(DestNode);
-      DestNode->Links.push_back(Links[0]);
 
       // If we have links, merge all of our outgoing links together...
-      for (unsigned i = Links.size()-1; i != 0; --i)
-        NH.getNode()->Links[0].mergeWith(Links[i]);
+      for (LinkMapTy::iterator ii = edge_begin(), ee = edge_end();
+           ii != ee; ++ii)
+        NH.getNode()->Links[0].mergeWith(ii->second);
       Links.clear();
-    } else {
-      DestNode->Links.resize(1);
+    }
+    //Merge types
+    if (!TyMap.empty()) {
+      for (TyMapTy::iterator ii = type_begin(), ee = type_end();
+           ii != ee; ++ii)
+        NH.getNode()->mergeTypeInfo(ii);
+      TyMap.clear();
     }
   }
 }
@@ -288,8 +260,7 @@
 /// all of the field sensitivity that may be present in the node.
 ///
 bool DSNode::isNodeCompletelyFolded() const {
-  return getSize() == 1 && (!Ty || Ty->getTypeID() == Type::VoidTyID)
-          && isArray();
+  return  isCollapsedNode();
 }
 
 /// addFullGlobalsList - Compute the full set of global values that are
@@ -330,179 +301,6 @@
   }
 }
 
-namespace {
-  /// TypeElementWalker Class - Used for implementation of physical subtyping...
-  ///
-  class TypeElementWalker {
-    struct StackState {
-      const Type *Ty;
-      unsigned Offset;
-      unsigned Idx;
-      StackState(const Type *T, unsigned Off = 0)
-        : Ty(T), Offset(Off), Idx(0) {}
-    };
-
-    std::vector<StackState> Stack;
-    const TargetData &TD;
-  public:
-    TypeElementWalker(const Type *T, const TargetData &td) : TD(td) {
-      Stack.push_back(T);
-      StepToLeaf();
-    }
-
-    bool isDone() const { return Stack.empty(); }
-    const Type *getCurrentType()   const { return Stack.back().Ty;     }
-    unsigned    getCurrentOffset() const { return Stack.back().Offset; }
-
-    void StepToNextType() {
-      PopStackAndAdvance();
-      StepToLeaf();
-    }
-
-  private:
-    /// PopStackAndAdvance - Pop the current element off of the stack and
-    /// advance the underlying element to the next contained member.
-    void PopStackAndAdvance() {
-      assert(!Stack.empty() && "Cannot pop an empty stack!");
-      Stack.pop_back();
-      while (!Stack.empty()) {
-        StackState &SS = Stack.back();
-        if (const StructType *ST = dyn_cast<StructType>(SS.Ty)) {
-          ++SS.Idx;
-          if (SS.Idx != ST->getNumElements()) {
-            const StructLayout *SL = TD.getStructLayout(ST);
-            SS.Offset +=
-               unsigned(SL->getElementOffset(SS.Idx)-SL->getElementOffset(SS.Idx-1));
-            return;
-          }
-          Stack.pop_back();  // At the end of the structure
-        } else {
-          const ArrayType *AT = cast<ArrayType>(SS.Ty);
-          ++SS.Idx;
-          if (SS.Idx != AT->getNumElements()) {
-            SS.Offset += unsigned(TD.getTypeAllocSize(AT->getElementType()));
-            return;
-          }
-          Stack.pop_back();  // At the end of the array
-        }
-      }
-    }
-
-    /// StepToLeaf - Used by physical subtyping to move to the first leaf node
-    /// on the type stack.
-    void StepToLeaf() {
-      if (Stack.empty()) return;
-      while (!Stack.empty() && !Stack.back().Ty->isFirstClassType()) {
-        StackState &SS = Stack.back();
-        if (const StructType *ST = dyn_cast<StructType>(SS.Ty)) {
-          if (ST->getNumElements() == 0) {
-            assert(SS.Idx == 0);
-            PopStackAndAdvance();
-          } else {
-            // Step into the structure...
-            assert(SS.Idx < ST->getNumElements());
-            const StructLayout *SL = TD.getStructLayout(ST);
-            Stack.push_back(StackState(ST->getElementType(SS.Idx),
-                            SS.Offset+unsigned(SL->getElementOffset(SS.Idx))));
-          }
-        } else {
-          const ArrayType *AT = cast<ArrayType>(SS.Ty);
-          if (AT->getNumElements() == 0) {
-            assert(SS.Idx == 0);
-            PopStackAndAdvance();
-          } else {
-            // Step into the array...
-            assert(SS.Idx < AT->getNumElements());
-            Stack.push_back(StackState(AT->getElementType(),
-                                       SS.Offset+SS.Idx*
-                             unsigned(TD.getTypeAllocSize(AT->getElementType()))));
-          }
-        }
-      }
-    }
-  };
-} // end anonymous namespace
-
-/// ElementTypesAreCompatible - Check to see if the specified types are
-/// "physically" compatible.  If so, return true, else return false.  We only
-/// have to check the fields in T1: T2 may be larger than T1.  If AllowLargerT1
-/// is true, then we also allow a larger T1.
-///
-static bool ElementTypesAreCompatible(const Type *T1, const Type *T2,
-                                      bool AllowLargerT1, const TargetData &TD){
-  TypeElementWalker T1W(T1, TD), T2W(T2, TD);
-
-  while (!T1W.isDone() && !T2W.isDone()) {
-    if (T1W.getCurrentOffset() != T2W.getCurrentOffset())
-      return false;
-
-    const Type *T1 = T1W.getCurrentType();
-    const Type *T2 = T2W.getCurrentType();
-    if (T1 != T2 && !T1->canLosslesslyBitCastTo(T2))
-      return false;
-
-    T1W.StepToNextType();
-    T2W.StepToNextType();
-  }
-
-  return AllowLargerT1 || T1W.isDone();
-}
-
-//
-// Function: getElementAtOffsetWithPadding()
-//
-// Description:
-//  Take a byte offset into a structure and return the type at that byte
-//  offset that *includes* any padding that occurs after the structure element.
-//
-static inline const Type *
-getElementAtOffsetWithPadding (const TargetData & TD,
-                               const StructLayout & SL,
-                               const StructType * STy,
-                               unsigned index) {
-  //
-  // Get the type of the element at the specified type index.
-  //
-  const Type * SubType = STy->getElementType(index);
-
-  //
-  // If this is the last element in the structure, just return the subtype;
-  // there is no padding after the last element.
-  //
-  if (index == (STy->getNumElements() - 1))
-    return SubType;
-
-  //
-  // Get the byte offset of this element and its successor element.
-  //
-  unsigned int thisOffset = (unsigned) SL.getElementOffset(index);
-  unsigned int nextOffset = (unsigned) SL.getElementOffset(index + 1);
-
-  //
-  // If the size of the current element is less than the distance between
-  // the offset at this index and the offset at the next index, then there is
-  // some padding in between this element and the next.  Create a structure
-  // type that contains this element *and* the padding.
-  //
-  if ((TD.getTypeAllocSize (SubType)) < (nextOffset - thisOffset)) {
-    //
-    // Create an array type that fits the padding size.
-    //
-    const Type * Int8Type = IntegerType::getInt8Ty(SubType->getContext());
-    const Type * paddingType = ArrayType::get (Int8Type, nextOffset-thisOffset);
-
-    //
-    // Create a structure type that contains the element and the padding array.
-    //
-    std::vector<const Type *> elementTypes;
-    elementTypes.push_back (SubType);
-    elementTypes.push_back (paddingType);
-    return (StructType::get (SubType->getContext(), elementTypes, true));
-  } else {
-    return SubType;
-  }
-}
-
 /// 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
@@ -511,322 +309,28 @@
 ///
 /// This method returns true if the node is completely folded, otherwise false.
 ///
-bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset,
-                           bool FoldIfIncompatible) {
-  //DOUT << "merging " << *NewTy << " at " << Offset << " with " << *Ty << "\n";
-  if (!Ty) Ty = Type::getVoidTy(NewTy->getContext());
-
-  const TargetData &TD = getTargetData();
-  // 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
-  //
-  const Type * VoidType = Type::getVoidTy(NewTy->getContext());
-  assert(((Size == 0 && Ty == VoidType && !isArray()) ||
-          (Size == 0 && !Ty->isSized() && !isArray()) ||
-          (Size == 1 && Ty == VoidType && isArray()) ||
-          (Size == 0 && !Ty->isSized() && !isArray()) ||
-          (TD.getTypeAllocSize(Ty) == Size)) &&
-         "Size member of DSNode doesn't match the type structure!");
-  assert(NewTy != VoidType && "Cannot merge void type into DSNode!");
-
-  if (Offset == 0 && NewTy == Ty)
-    return false;  // This should be a common case, handle it efficiently
-
-  // Return true immediately if the node is completely folded.
-  if (isNodeCompletelyFolded()) return true;
-
-  // If this is an array type, eliminate the outside arrays because they won't
-  // be used anyway.  This greatly reduces the size of large static arrays used
-  // as global variables, for example.
-  //
-  bool WillBeArray = false;
-  while (const ArrayType *AT = dyn_cast<ArrayType>(NewTy)) {
-    // FIXME: we might want to keep small arrays, but must be careful about
-    // things like: [2 x [10000 x int*]]
-    NewTy = AT->getElementType();
-    WillBeArray = true;
-  }
-
-  // Figure out how big the new type we're merging in is...
-  unsigned NewTySize = NewTy->isSized() ? (unsigned)TD.getTypeAllocSize(NewTy) : 0;
-
-  // Otherwise check to see if we can fold this type into the current node.  If
-  // we can't, we fold the node completely, if we can, we potentially update our
-  // internal state.
-  //
-  if (Ty == VoidType) {
-    // If this is the first type that this node has seen, just accept it without
-    // question....
-    assert(Offset == 0 && !isArray() &&
-           "Cannot have an offset into a void node!");
-
-    // If this node would have to have an unreasonable number of fields, just
-    // collapse it.  This can occur for fortran common blocks, which have stupid
-    // things like { [100000000 x double], [1000000 x double] }.
-    unsigned NumFields = NewTySize;
-    if (NumFields > DSAFieldLimit) {
-      foldNodeCompletely();
-      return true;
-    }
-
-    Ty = NewTy;
-    NodeType &= ~ArrayNode;
-    if (WillBeArray) NodeType |= ArrayNode;
-    Size = NewTySize;
-
-    // Calculate the number of outgoing links from this node.
-    Links.resize(NumFields);
-    return false;
-  }
-
-  // Handle node expansion case here...
-  if (Offset+NewTySize > Size) {
-    // It is illegal to grow this node if we have treated it as an array of
-    // objects...
-    if (isArray()) {
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-    }
-
-    // If this node would have to have an unreasonable number of fields, just
-    // collapse it.  This can occur for fortran common blocks, which have stupid
-    // things like { [100000000 x double], [1000000 x double] }.
-    unsigned NumFields = NewTySize+Offset;
-    if (NumFields > DSAFieldLimit) {
-      foldNodeCompletely();
-      return true;
-    }
-
-    if (Offset) {
-      //handle some common cases:
-      // Ty:    struct { t1, t2, t3, t4, ..., tn}
-      // NewTy: struct { offset, stuff...}
-      // try merge with NewTy: struct {t1, t2, stuff...} if offset lands exactly
-      // on a field in Ty
-      if (isa<StructType>(NewTy) && isa<StructType>(Ty)) {
-        DEBUG(errs() << "Ty: " << *Ty << "\nNewTy: " << *NewTy << "@" << Offset << "\n");
-        const StructType *STy = cast<StructType>(Ty);
-        const StructLayout &SL = *TD.getStructLayout(STy);
-        unsigned i = SL.getElementContainingOffset(Offset);
-        //Either we hit it exactly or give up
-        if (SL.getElementOffset(i) != Offset) {
-          if (FoldIfIncompatible) foldNodeCompletely();
-          return true;
-        }
-        std::vector<const Type*> nt;
-        for (unsigned x = 0; x < i; ++x)
-          nt.push_back(STy->getElementType(x));
-        STy = cast<StructType>(NewTy);
-        nt.insert(nt.end(), STy->element_begin(), STy->element_end());
-        //and merge
-        STy = StructType::get(STy->getContext(), nt);
-        DEBUG(errs() << "Trying with: " << *STy << "\n");
-        return mergeTypeInfo(STy, 0);
-      }
-
-      //Ty: struct { t1, t2, t3 ... tn}
-      //NewTy T offset x
-      //try merge with NewTy: struct : {t1, t2, T} if offset lands on a field
-      //in Ty
-      if (isa<StructType>(Ty)) {
-        DEBUG(errs() << "Ty: " << *Ty << "\nNewTy: " << *NewTy << "@" << Offset << "\n");
-        const StructType *STy = cast<StructType>(Ty);
-        const StructLayout &SL = *TD.getStructLayout(STy);
-        unsigned i = SL.getElementContainingOffset(Offset);
-        //Either we hit it exactly or give up
-        if (SL.getElementOffset(i) != Offset) {
-          if (FoldIfIncompatible) foldNodeCompletely();
-          return true;
-        }
-        std::vector<const Type*> nt;
-        for (unsigned x = 0; x < i; ++x)
-          nt.push_back(STy->getElementType(x));
-        nt.push_back(NewTy);
-        //and merge
-        STy = StructType::get(STy->getContext(), nt);
-        DEBUG(errs() << "Trying with: " << *STy << "\n");
-        return mergeTypeInfo(STy, 0);
-      }
-
-      assert(0 &&
-             "UNIMP: Trying to merge a growth type into "
-             "offset != 0: Collapsing!");
-      abort();
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-
-    }
-
-
-    // Okay, the situation is nice and simple, we are trying to merge a type in
-    // at offset 0 that is bigger than our current type.  Implement this by
-    // switching to the new type and then merge in the smaller one, which should
-    // hit the other code path here.  If the other code path decides it's not
-    // ok, it will collapse the node as appropriate.
-    //
-
-    const Type *OldTy = Ty;
-    Ty = NewTy;
-    NodeType &= ~ArrayNode;
-    if (WillBeArray) NodeType |= ArrayNode;
-    Size = NewTySize;
-
-    // Must grow links to be the appropriate size...
-    Links.resize(NumFields);
-
-    // Merge in the old type now... which is guaranteed to be smaller than the
-    // "current" type.
-    return mergeTypeInfo(OldTy, 0);
-  }
-
-  assert(Offset <= Size &&
-         "Cannot merge something into a part of our type that doesn't exist!");
-
-  // Find the section of Ty that NewTy overlaps with... first we find the
-  // type that starts at offset Offset.
-  //
-  unsigned O = 0;
-  const Type *SubType = Ty;
-  while (O < Offset) {
-    assert(Offset-O < TD.getTypeAllocSize(SubType) && "Offset out of range!");
-
-    switch (SubType->getTypeID()) {
-    case Type::StructTyID: {
-      const StructType *STy = cast<StructType>(SubType);
-      const StructLayout &SL = *TD.getStructLayout(STy);
-
-      unsigned i = SL.getElementContainingOffset(Offset-O);
-
-      //
-      // The offset we are looking for must be in the i'th element...
-      // However, be careful!  It is possible that the offset lands in a
-      // padding area of the structure.  Use a special methods that will either
-      // return us the type of the element we seek or a structure that contains
-      // an explicit element representing the padding.
-      //
-      SubType = getElementAtOffsetWithPadding (TD, SL, STy, i);
-      O += (unsigned)SL.getElementOffset(i);
-      break;
-    }
-    case Type::ArrayTyID: {
-      SubType = cast<ArrayType>(SubType)->getElementType();
-      unsigned ElSize = (unsigned)TD.getTypeAllocSize(SubType);
-      unsigned Remainder = (Offset-O) % ElSize;
-      O = Offset-Remainder;
-      break;
-    }
-    default:
-      if (FoldIfIncompatible) foldNodeCompletely();
-      return true;
-    }
-  }
-
-  assert(O == Offset && "Could not achieve the correct offset!");
-
-  // If we found our type exactly, early exit
-  if (SubType == NewTy) return false;
+void DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset) {
 
-  // Differing function types don't require us to merge.  They are not values
-  // anyway.
-  if (isa<FunctionType>(SubType) &&
-      isa<FunctionType>(NewTy)) return false;
-
-  unsigned SubTypeSize = SubType->isSized() ?
-       (unsigned)TD.getTypeAllocSize(SubType) : 0;
-
-  // Ok, we are getting desperate now.  Check for physical subtyping, where we
-  // just require each element in the node to be compatible.
-  if (NewTySize <= SubTypeSize && NewTySize && NewTySize < 256 &&
-      SubTypeSize && SubTypeSize < 256 &&
-      ElementTypesAreCompatible(NewTy, SubType, !isArray(), TD))
-    return false;
-
-  // Okay, so we found the leader type at the offset requested.  Search the list
-  // of types that starts at this offset.  If SubType is currently an array or
-  // structure, the type desired may actually be the first element of the
-  // composite type...
-  //
-  unsigned PadSize = SubTypeSize; // Size, including pad memory which is ignored
-  while (SubType != NewTy) {
-    const Type *NextSubType = 0;
-    unsigned NextSubTypeSize = 0;
-    unsigned NextPadSize = 0;
-    switch (SubType->getTypeID()) {
-    case Type::StructTyID: {
-      const StructType *STy = cast<StructType>(SubType);
-      const StructLayout &SL = *TD.getStructLayout(STy);
-      if (STy->getNumElements() > 1)
-        NextPadSize = (unsigned)SL.getElementOffset(1);
-      else
-        NextPadSize = SubTypeSize;
-      NextSubType = STy->getElementType(0);
-      NextSubTypeSize = (unsigned)TD.getTypeAllocSize(NextSubType);
-      break;
-    }
-    case Type::ArrayTyID:
-      NextSubType = cast<ArrayType>(SubType)->getElementType();
-      NextSubTypeSize = (unsigned)TD.getTypeAllocSize(NextSubType);
-      NextPadSize = NextSubTypeSize;
-      break;
-    default: ;
-      // fall out
-    }
+  if (!NewTy || NewTy->isVoidTy()) return;
 
-    if (NextSubType == 0)
-      break;   // In the default case, break out of the loop
+  if (isCollapsedNode()) Offset = 0;
+  if (isArrayNode()) Offset %= getSize();
 
-    if (NextPadSize < NewTySize)
-      break;   // Don't allow shrinking to a smaller type than NewTySize
-    SubType = NextSubType;
-    SubTypeSize = NextSubTypeSize;
-    PadSize = NextPadSize;
-  }
+  if (Offset >= getSize()) growSize(Offset+1);
 
-  // If we found the type exactly, return it...
-  if (SubType == NewTy)
-    return false;
+  TyMap[Offset].insert(NewTy);
+}
 
-  // Check to see if we have a compatible, but different type...
-  if (NewTySize == SubTypeSize) {
-    // Check to see if this type is obviously convertible... int -> uint f.e.
-    if (NewTy->canLosslesslyBitCastTo(SubType))
-      return false;
+void DSNode::mergeTypeInfo(TyMapTy::const_iterator TyIt, unsigned Offset) {
+  Offset += TyIt->first;
+  if (isCollapsedNode()) Offset = 0;
+  if (isArrayNode()) Offset %= getSize();
 
-    // Check to see if we have a pointer & integer mismatch going on here,
-    // loading a pointer as a long, for example.
-    //
-    if ((SubType->isIntegerTy() && NewTy->isPointerTy()) ||
-        (NewTy->isIntegerTy() && SubType->isPointerTy()))
-      return false;
-  } else if (NewTySize > SubTypeSize && NewTySize <= PadSize) {
-    // We are accessing the field, plus some structure padding.  Ignore the
-    // structure padding.
-    return false;
-  }
-
-  const Module *M = 0;
-  if (getParentGraph()->retnodes_begin() != getParentGraph()->retnodes_end())
-    M = getParentGraph()->retnodes_begin()->first->getParent();
-
-  DEBUG(errs() << "MergeTypeInfo Folding OrigTy: ");
-  raw_stderr_ostream stream;
-  DEBUG(WriteTypeSymbolic(stream, Ty, M);
-        stream << "\n due to:";
-        WriteTypeSymbolic(stream, NewTy, M);
-        stream << " @ " << Offset << "!\n" << "SubType: ";
-        WriteTypeSymbolic(stream, SubType, M);
-        stream << "\n\n");
+  if (Offset >= getSize()) growSize(Offset+1);
 
-  if (FoldIfIncompatible) foldNodeCompletely();
-  return true;
+  TyMap[Offset].insert(TyIt->second.begin(), TyIt->second.end());
 }
 
-
-
 /// addEdgeTo - Add an edge from the current node to the specified node.  This
 /// can cause merging of nodes in the graph.
 ///
@@ -855,6 +359,16 @@
   Globals.swap(Temp);
 }
 
+static unsigned gcd(unsigned m, unsigned n) {
+  if (m < n) return gcd(n,m);
+  unsigned r = m % n;
+  if (r == 0) {
+    return n;
+  } else {
+    return gcd(n, r);
+  }
+}
+
 // 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
@@ -891,62 +405,11 @@
     }
 #endif
   }
-#ifdef LLVA_KERNEL
-  DSNode *currNode  = CurNodeH.getNode();
-  DSNode *NNode  = NH.getNode();
-  DSGraph *pGraph =  currNode->getParentGraph();
-  assert((pGraph == NNode->getParentGraph()) && "LLVA_KERNEL : merging nodes in two different graphs?");
-  //get the pooldescriptor map
-  hash_map<const DSNode *, MetaPoolHandle*> &pdm = pGraph->getPoolDescriptorsMap();
-  if (pdm.count(currNode) == 0) {
-    if (pdm.count(NNode) == 0) {
-      //do nothing  (common case)
-    } else {
-      if (pdm[NNode]) {
-        DEBUG(errs() << "LLVA: 1: currNode (" << currNode << ") becomes " << pdm[NNode]->getName() << "(" << NNode << ")\n");
-        pdm[currNode] = pdm[NNode];
-      }
-    }
-  } else {
-    if (pdm.count(NNode) == 0) {
-#if 1
-      //
-      // FIXME:
-      //  Verify that this is correct.  I believe it is; it seems to make sense
-      //  since either node can be used after the merge.
-      //
-      DEBUG(errs() << "LLVA: MergeNodes: currnode has something, newnode has nothing\n"
-            << "LLVA: 2: currNode (" << currNode << ") becomes <no name>"
-            << "(" << NNode << ")\n");
-      pdm[NNode] = pdm[currNode];
-#endif
-      //do nothing 
-    } else {
-      if (pdm[currNode] != pdm[NNode]) {
-	//The following is commented because pdm[..] could be null!
-	//std::cerr << "LLVA: OldPool: " << pdm[currNode]->getName() << "("
-        //                       << pdm[currNode] << ") "
-	//          << " NewPool: "      << pdm[NNode]->getName() << "("
-	//                               << pdm[NNode] << ")" << std::endl;
-        pdm[NNode]->merge(pdm[currNode]);
-        /*
-        Value *currN = pdm[currNode]->getMetaPoolValue();
-        Value *NN = pdm[NNode]->getMetaPoolValue();
-        if (currN != NN) {
-          std::cerr << "LLVA: Two Pools for one DSNode\n";
-          currN->replaceAllUsesWith(NN);
-          pdm[currNode]->merge(pdm[NNode]);
-        } else {
-          //The nodes are same
-        }
-        */
-      }
-    }
-  }
-#endif  
+
   // Merge the type entries of the two nodes together...
-  if (NH.getNode()->Ty && NH.getNode()->Ty->getTypeID() != Type::VoidTyID)
-    CurNodeH.getNode()->mergeTypeInfo(NH.getNode()->Ty, NOffset);
+  for (TyMapTy::iterator ii = NH.getNode()->TyMap.begin(),
+      ee = NH.getNode()->TyMap.end(); ii != ee; ++ii)
+    CurNodeH.getNode()->mergeTypeInfo(ii, NOffset);
   assert(!CurNodeH.getNode()->isDeadNode());
 
   // If we are merging a node with a completely folded node, then both nodes are
@@ -970,6 +433,8 @@
     assert(NOffset == 0 && NSize == 1);
   }
 
+
+
   DSNode *N = NH.getNode();
   if (CurNodeH.getNode() == N || N == 0) return;
   assert(!CurNodeH.getNode()->isDeadNode());
@@ -983,9 +448,9 @@
 
   // Make all of the outgoing links of N now be outgoing links of CurNodeH.
   //
-  for (unsigned i = 0; i < N->getNumLinks(); ++i) {
-    DSNodeHandle &Link = N->getLink(i);
-    if (Link.getNode()) {
+  for (LinkMapTy::iterator ii = N->Links.begin(), ee = N->Links.end();
+       ii != ee; ++ii)
+    if (ii->second.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
@@ -995,10 +460,9 @@
       unsigned MergeOffset = 0;
       DSNode *CN = CurNodeH.getNode();
       if (CN->Size != 1)
-        MergeOffset = (i+NOffset) % CN->getSize();
-      CN->addEdgeTo(MergeOffset, Link);
+        MergeOffset = (ii->first+NOffset) % CN->getSize();
+      CN->addEdgeTo(MergeOffset, ii->second);
     }
-  }
 
   // Now that there are no outgoing edges, all of the Links are dead.
   N->Links.clear();
@@ -1103,26 +567,15 @@
   DN->maskNodeTypes(BitsToKeep);
   NH = DN;
   //DOUT << "getClonedNH: " << SN << " becomes " << DN << "\n";
-#if 1
-#ifdef LLVA_KERNEL
-    //Again we have created a new DSNode, we need to fill in the
-    // pool desc map appropriately
-    hash_map<const DSNode *, MetaPoolHandle*> &pdm = Dest.getPoolDescriptorsMap();
-    if (pdm.count(SN) > 0) {
-      pdm[DN] = pdm[SN];
-    } else {
-      //do nothing 
-    }
-#endif    
-#endif
 
   // Next, recursively clone all outgoing links as necessary.  Note that
   // adding these links can cause the node to collapse itself at any time, and
   // the current node may be merged with arbitrary other nodes.  For this
   // reason, we must always go through NH.
   DN = 0;
-  for (unsigned i = 0, e = SN->getNumLinks(); i != e; ++i) {
-    const DSNodeHandle &SrcEdge = SN->getLink(i);
+  for (DSNode::LinkMapTy::const_iterator ii = SN->edge_begin(),
+          ee = SN->edge_end(); ii != ee; ++ii) {
+    const DSNodeHandle &SrcEdge = ii->second;
     if (!SrcEdge.isNull()) {
       const DSNodeHandle &DestEdge = getClonedNH(SrcEdge);
       // Compute the offset into the current node at which to
@@ -1134,7 +587,7 @@
       unsigned MergeOffset = 0;
       DSNode *CN = NH.getNode();
       if (CN->getSize() != 1)
-        MergeOffset = (i + NH.getOffset()) % CN->getSize();
+        MergeOffset = (ii->first + NH.getOffset()) % CN->getSize();
       CN->addEdgeTo(MergeOffset, DestEdge);
     }
   }
@@ -1206,12 +659,15 @@
 #endif
       }
 
+      if (DN->getSize() < SN->getSize())
+        DN->growSize(SN->getSize());
+
       // Merge the type entries of the two nodes together...
-      if ((SN->getType() && SN->getType()->getTypeID() != Type::VoidTyID)
-              && !DN->isNodeCompletelyFolded()) {
-        DN->mergeTypeInfo(SN->getType(), NH.getOffset() - SrcNH.getOffset());
-        DN = NH.getNode();
-      }
+      if (!DN->isNodeCompletelyFolded())
+        for (DSNode::TyMapTy::const_iterator ii = SN->type_begin(),
+             ee = SN->type_end(); ii != ee; ++ii)
+          DN->mergeTypeInfo(ii, NH.getOffset() - SrcNH.getOffset());
+
     }
 
     assert(!DN->isDeadNode());
@@ -1276,59 +732,14 @@
 
   //  DOUT << "LLVA: mergeWith: " << SN << " becomes " << DN << "\n";
 
-#ifdef LLVA_KERNEL
-  //Here some merge is going on just like in DSNode::merge
-  //I think because of the inplace merging we don't update the pool desc maps
-  //This is modification from DSNode::MergeNodes
-  //Here DN and SN may belong to different graphs
- DN = NH.getNode(); 
-#if 0
-  DSGraph *destGraph =  DN->getParentGraph();
-  DSGraph *srcGraph =  SN->getParentGraph();
-#else
-  DSGraph *destGraph = NH.getNode()->getParentGraph();
-  DSGraph *srcGraph =  SN->getParentGraph();
-#endif
-  if (destGraph && srcGraph) {
-    //get the pooldescriptor map
-    hash_map<const DSNode *, MetaPoolHandle*> &destpdm = destGraph->getPoolDescriptorsMap();
-    hash_map<const DSNode *, MetaPoolHandle*> &srcpdm = srcGraph->getPoolDescriptorsMap();
-    if (destpdm.count(DN) == 0) {
-      if (srcpdm.count(SN) == 0) {
-        //do nothing  (common case)
-      } else {
-        if (srcpdm[SN]) {
-          DEBUG(errs() << "DN becomes " << srcpdm[SN]->getName() << std::endl);
-          destpdm[DN] = srcpdm[SN];
-        }
-      }
-    } else {
-      if (srcpdm.count(SN) == 0) {
-        srcpdm[SN] = destpdm[DN];
-      } else {
-        if (destpdm[DN] != srcpdm[SN]) {
-          srcpdm[SN]->merge(destpdm[DN]);
-          /*
-          Value *dnv = destpdm[DN]->getMetaPoolValue();
-          Value *snv = srcpdm[SN]->getMetaPoolValue();
-          if (dnv != snv) {
-            DEBUG(std::cerr << "LLVA: Two Pools for one DSNode\n");
-            dnv->replaceAllUsesWith(snv);
-            destpdm[DN]->setMetaPoolValue(snv);
-          }
-          */
-        }
-      }
-    }
-  }
-#endif  
   // Next, recursively merge all outgoing links as necessary.  Note that
   // adding these links can cause the destination node to collapse itself at
   // any time, and the current node may be merged with arbitrary other nodes.
   // For this reason, we must always go through NH.
   DN = 0;
-  for (unsigned i = 0, e = SN->getNumLinks(); i != e; ++i) {
-    const DSNodeHandle &SrcEdge = SN->getLink(i);
+  for (DSNode::LinkMapTy::const_iterator ii = SN->edge_begin(),
+          ee = SN->edge_end(); ii != ee; ++ii) {
+    const DSNodeHandle &SrcEdge = ii->second;
     if (!SrcEdge.isNull()) {
       // Compute the offset into the current node at which to
       // merge this link.  In the common case, this is a linear
@@ -1337,8 +748,7 @@
       // recursive merging, we must make sure to merge in all remaining
       // links at offset zero.
       DSNode *CN = SCNH.getNode();
-      unsigned MergeOffset =
-        (i+SCNH.getOffset()) % CN->getSize();
+      unsigned MergeOffset = (ii->first+SCNH.getOffset()) % CN->getSize();
 
       DSNodeHandle Tmp = CN->getLink(MergeOffset);
       if (!Tmp.isNull()) {
@@ -1353,7 +763,7 @@
 
         unsigned MergeOffset = 0;
         CN = SCNH.getNode();
-        MergeOffset = (i + SCNH.getOffset()) %CN->getSize();
+        MergeOffset = (ii->first + SCNH.getOffset()) % CN->getSize();
         CN->getLink(MergeOffset).mergeWith(Tmp);
       }
     }
@@ -1405,53 +815,6 @@
   NH = RC.getClonedNH(Src);
 }
 
-#ifdef LLVA_KERNEL
-// MetaPoolHandle Implementation
-  //The following should go in a cpp file later
-   MetaPoolHandle::MetaPoolHandle(MetaPool *mp, Instruction * Maker) {
-    Rep = mp;
-    Rep->insert(this);
-    Creator = Maker;
-  }
-  const std::string& MetaPoolHandle::getName() {
-    assert(Rep != 0 && "Null meta pool ??\n");
-    return Rep->getName();
-  }
-  Value *MetaPoolHandle::getMetaPoolValue() {
-    assert(Rep != 0 && "Null meta pool ??\n");
-    return Rep->getMetaPoolValue();
-  }
-  void MetaPoolHandle::merge(MetaPoolHandle *other) {
-    //after this operation other points to what this points to .
-    //first replace all uses 
-     Value *dest = getMetaPoolValue();
-     Value *curr = other->getMetaPoolValue();
-     if (dest != curr) {
-       std::cerr << "LLVA: Merging metapools: " << this->Creator->getParent()->getParent()->getName() << " : " << other->Creator->getParent()->getParent()->getName() << "\n"
-                 << "LLVA:   " << *(this->Creator) << "\n"
-                 << "LLVA:   " << *(other->Creator) << "\n";
-       curr->replaceAllUsesWith(dest);
-     }
-   
-     //merge the hash sets in to other
-     hash_set<MetaPoolHandle *> &otherHandleSet = other->getMetaPool()->getHandleSet();
-     hash_set<MetaPoolHandle *>::iterator ohsI = otherHandleSet.begin(), ohsE = otherHandleSet.end();
-     for (; ohsI != ohsE; ++ohsI) {
-     MetaPoolHandle *omph = *ohsI;
-     //now make sure that this omph points to what we point to
-     omph->setMetaPool(Rep);
-     Rep->insert(omph);
-     }
-
-     //now delete others MetaPool
-     //gd     delete other->getMetaPool(); 
-
-     //Assign our metapool to other 
-     other->setMetaPool(Rep);
-}
-
-#endif
-
 //===----------------------------------------------------------------------===//
 // DSGraph Implementation
 //===----------------------------------------------------------------------===//
@@ -1502,12 +865,13 @@
 /// specified mapping.
 ///
 void DSNode::remapLinks(DSGraph::NodeMapTy &OldNodeMap) {
-  for (unsigned i = 0, e = Links.size(); i != e; ++i)
-    if (DSNode *N = Links[i].getNode()) {
+  for (LinkMapTy::iterator ii = edge_begin(), ee = edge_end();
+       ii != ee; ++ii)
+    if (DSNode *N = ii->second.getNode()) {
       DSGraph::NodeMapTy::const_iterator ONMI = OldNodeMap.find(N);
       if (ONMI != OldNodeMap.end()) {
         DSNode *ONMIN = ONMI->second.getNode();
-        Links[i].setTo(ONMIN, Links[i].getOffset()+ONMI->second.getOffset());
+        ii->second.setTo(ONMIN, ii->second.getOffset()+ONMI->second.getOffset());
       }
     }
 }
@@ -1534,8 +898,7 @@
 /// and does not point to any other objects in the graph.
 DSNode *DSGraph::addObjectToGraph(Value *Ptr, bool UseDeclaredType) {
   assert(isa<PointerType>(Ptr->getType()) && "Ptr is not a pointer!");
-  const Type *Ty = cast<PointerType>(Ptr->getType())->getElementType();
-  DSNode *N = new DSNode(UseDeclaredType ? Ty : 0, this);
+  DSNode *N = new DSNode(this);
   assert(ScalarMap[Ptr].isNull() && "Object already in this graph!");
   ScalarMap[Ptr] = N;
 
@@ -1758,7 +1121,7 @@
   bool AnyDirectSuccessorsReachClonedNodes = false;
   for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
        EI != EE; ++EI)
-    if (DSNode *Succ = EI->getNode()) {
+    if (DSNode *Succ = EI->second.getNode()) {
       std::pair<unsigned, bool> &SuccInfo = VisitForSCCs(Succ);
       if (SuccInfo.first < Min) Min = SuccInfo.first;
       AnyDirectSuccessorsReachClonedNodes |= SuccInfo.second;
@@ -1778,7 +1141,7 @@
     for (unsigned i = SCCStack.size()-1; SCCStack[i] != N; --i)
       for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
            EI != EE; ++EI)
-        if (DSNode *N = EI->getNode())
+        if (DSNode *N = EI->second.getNode())
           if (NodeInfo[N].second) {
             AnyDirectSuccessorsReachClonedNodes = true;
             goto OutOfLoop;
@@ -1872,7 +1235,7 @@
     DSNode *GlobalNode = Graph.getNodeForValue(*GI).getNode();
     for (DSNode::edge_iterator EI = GlobalNode->edge_begin(),
            EE = GlobalNode->edge_end(); EI != EE; ++EI)
-      if (SCCFinder.PathExistsToClonedNode(EI->getNode())) {
+      if (SCCFinder.PathExistsToClonedNode(EI->second.getNode())) {
         GlobalsToCopy.push_back(*GI);
         break;
       }
@@ -1961,7 +1324,7 @@
 
   // Recursively process children...
   for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
-    if (DSNode *DSN = I->getNode())
+    if (DSNode *DSN = I->second.getNode())
       markIncompleteNode(DSN);
 }
 
@@ -2037,9 +1400,9 @@
   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::IncompleteNode) == 0 &&
-          (!N->getType() || N->getType()->getTypeID() == Type::VoidTyID)
-              && !N->isNodeCompletelyFolded())
+      if ((N->getNodeFlags() & ~DSNode::IncompleteNode) == 0
+          && N->type_begin() == N->type_end()
+          && !N->isNodeCompletelyFolded())
         Edge.setTo(0, 0);  // Kill the edge!
 }
 
@@ -2288,16 +1651,16 @@
 /// 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(std::set<const DSNode*> &ReachableNodes) const {
+void DSNode::markReachableNodes(DenseSet<const DSNode*> &ReachableNodes) const {
   if (this == 0) return;
   assert(getForwardNode() == 0 && "Cannot mark a forwarded node!");
   if (ReachableNodes.insert(this).second)        // Is newly reachable?
     for (DSNode::const_edge_iterator I = edge_begin(), E = edge_end();
          I != E; ++I)
-      I->getNode()->markReachableNodes(ReachableNodes);
+      I->second.getNode()->markReachableNodes(ReachableNodes);
 }
 
-void DSCallSite::markReachableNodes(std::set<const DSNode*> &Nodes) const {
+void DSCallSite::markReachableNodes(DenseSet<const DSNode*> &Nodes) const {
   getRetVal().getNode()->markReachableNodes(Nodes);
   if (isIndirectCall()) getCalleeNode()->markReachableNodes(Nodes);
 
@@ -2310,8 +1673,8 @@
 // true, otherwise return false.  If an alive node is reachable, this node is
 // marked as alive...
 //
-static bool CanReachAliveNodes(DSNode *N, std::set<const DSNode*> &Alive,
-                               std::set<const DSNode*> &Visited,
+static bool CanReachAliveNodes(DSNode *N, DenseSet<const DSNode*> &Alive,
+                               DenseSet<const DSNode*> &Visited,
                                bool IgnoreGlobals) {
   if (N == 0) return false;
   assert(N->getForwardNode() == 0 && "Cannot mark a forwarded node!");
@@ -2329,7 +1692,7 @@
   Visited.insert(N);   // No recursion, insert into Visited...
 
   for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
-    if (CanReachAliveNodes(I->getNode(), Alive, Visited, IgnoreGlobals)) {
+    if (CanReachAliveNodes(I->second.getNode(), Alive, Visited, IgnoreGlobals)) {
       N->markReachableNodes(Alive);
       return true;
     }
@@ -2340,8 +1703,8 @@
 // alive nodes.
 //
 static bool CallSiteUsesAliveArgs(const DSCallSite &CS,
-                                  std::set<const DSNode*> &Alive,
-                                  std::set<const DSNode*> &Visited,
+                                  DenseSet<const DSNode*> &Alive,
+                                  DenseSet<const DSNode*> &Visited,
                                   bool IgnoreGlobals) {
   if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited,
                          IgnoreGlobals))
@@ -2372,7 +1735,7 @@
   // FIXME: Merge non-trivially identical call nodes...
 
   // Alive - a set that holds all nodes found to be reachable/alive.
-  std::set<const DSNode*> Alive;
+  DenseSet<const DSNode*> Alive;
   std::vector<std::pair<const Value*, DSNode*> > GlobalNodes;
 
   // Copy and merge all information about globals to the GlobalsGraph if this is
@@ -2420,7 +1783,7 @@
   // value (which makes them live in turn), and continue till no more are found.
   //
   bool Iterate;
-  std::set<const DSNode*> Visited;
+  DenseSet<const DSNode*> Visited;
   std::set<const DSCallSite*> AuxFCallsAlive;
   do {
     Visited.clear();
@@ -2849,7 +2212,7 @@
   bool MadeChange = false;
   for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
        GI != E; ) {
-    const GlobalValue *GV = *GI++;
+    const GlobalValue *GV = *GI; ++GI;
     if (!ECGlobals.count(GV)) continue;
 
     const DSNodeHandle &GVNH = SM[GV];

Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Tue Mar  9 10:48:35 2010
@@ -18,6 +18,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Intrinsics.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Target/TargetData.h"
@@ -28,7 +29,6 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/DenseSet.h"
 
-#include <iostream>
 #include <fstream>
 
 // FIXME: This should eventually be a FunctionPass that is automatically
@@ -56,6 +56,7 @@
     DSGraph &G;
     Function* FB;
     DataStructures* DS;
+    const TargetData& TD;
 
     ////////////////////////////////////////////////////////////////////////////
     // Helper functions used to implement the visitation functions...
@@ -65,9 +66,9 @@
     /// createNode - Create a new DSNode, ensuring that it is properly added to
     /// the graph.
     ///
-    DSNode *createNode(const Type *Ty = 0) 
+    DSNode *createNode() 
     {   
-      DSNode* ret = new DSNode(Ty, &G);
+      DSNode* ret = new DSNode(&G);
       assert(ret->getParentGraph() && "No parent?");
       return ret;
     }
@@ -92,6 +93,17 @@
     // Visitor functions, used to handle each instruction type we encounter...
     friend class InstVisitor<GraphBuilder>;
 
+    //TODO: generalize
+    bool visitAllocation(CallSite CS) {
+      if (Function* F = CS.getCalledFunction()) {
+        if (F->hasName() && F->getName() == "malloc") {
+          setDestTo(*CS.getInstruction(), createNode()->setHeapMarker());
+          return true;
+        }
+      }
+      return false;
+    }
+
     //FIXME: implement in stdlib pass
 //    void visitMallocInst(MallocInst &MI)
 //    { setDestTo(MI, createNode()->setHeapMarker()); }
@@ -130,7 +142,7 @@
 
   public:
     GraphBuilder(Function &f, DSGraph &g, DataStructures& DSi)
-      : G(g), FB(&f), DS(&DSi) {
+      : G(g), FB(&f), DS(&DSi), TD(g.getTargetData()) {
       // Create scalar nodes for all pointer arguments...
       for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end();
            I != E; ++I) {
@@ -172,7 +184,7 @@
 
     // GraphBuilder ctor for working on the globals graph
     explicit GraphBuilder(DSGraph& g)
-      :G(g), FB(0)
+      :G(g), FB(0), TD(g.getTargetData())
     {}
 
     void mergeInGlobalInitializer(GlobalVariable *GV);
@@ -196,8 +208,8 @@
       visited.insert(N);
       N->setUnknownMarker();
       for (DSNode::edge_iterator I = N->edge_begin(), E = N->edge_end(); I != E; ++I)
-        if (!I->isNull())
-          workList.push_back(I->getNode());
+        if (!I->second.isNull())
+          workList.push_back(I->second.getNode());
     }
   }
 }
@@ -224,7 +236,7 @@
   DSNode* N;
   if (GlobalVariable* GV = dyn_cast<GlobalVariable>(V)) {
     // Create a new global node for this global variable.
-    N = createNode(GV->getType()->getElementType());
+    N = createNode();
     N->addGlobal(GV);
     if (GV->isDeclaration())
       N->setExternGlobalMarker();
@@ -247,7 +259,7 @@
         NH = G.getNodeForValue(CE);
       } else {
         // This returns a conservative unknown node for any unhandled ConstExpr
-        return NH = createNode()->setUnknownMarker();
+        NH = createNode()->setUnknownMarker();
       }
       if (NH.isNull()) {  // (getelementptr null, X) returns null
         G.eraseNodeForValue(V);
@@ -263,7 +275,7 @@
       // not handle the aliases of parameters correctly. Here is only a quick
       // fix for some special cases.
       NH = getValueDest(cast<GlobalAlias>(C)->getAliasee());
-      return 0;
+      return NH;
     } else {
       errs() << "Unknown constant: " << *C << "\n";
       assert(0 && "Unknown constant type!");
@@ -340,7 +352,7 @@
   Ptr.getNode()->setReadMarker();
 
   // Ensure a typerecord exists...
-  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
+  Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset());
 
   if (isa<PointerType>(LI.getType()))
     setDestTo(LI, getLink(Ptr));
@@ -377,7 +389,7 @@
 
   // Ensure a type record exists.
   DSNode *PtrN = Ptr.getNode();
-  PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset(), false);
+  PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset());
 
   if (isa<PointerType>(I.getType()))
     setDestTo(I, getLink(Ptr));
@@ -433,7 +445,7 @@
 
   // Ensure a typerecord exists...
   // FIXME: calculate offset
-  Ptr.getNode()->mergeTypeInfo(I.getType(), 0, false);
+  Ptr.getNode()->mergeTypeInfo(I.getType(), 0);
 
   if (isa<PointerType>(I.getType()))
     setDestTo(I, getLink(Ptr));
@@ -464,18 +476,11 @@
     return;
   }
 
-
-  const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
+  //Make sure the uncollapsed node has a large enough size for the struct type
+  const PointerType *PTy = cast<PointerType > (GEP.getOperand(0)->getType());
   const Type *CurTy = PTy->getElementType();
-
-  if (Value.getNode()->mergeTypeInfo(CurTy, Value.getOffset())) {
-    // If the node had to be folded... exit quickly
-    setDestTo(GEP, Value);  // GEP result points to folded node
-
-    return;
-  }
-
-  const TargetData &TD = Value.getNode()->getTargetData();
+  if (TD.getTypeAllocSize(CurTy) + Value.getOffset() > Value.getNode()->getSize())
+    Value.getNode()->growSize(TD.getTypeAllocSize(CurTy) + Value.getOffset());
 
 #if 0
   // Handle the pointer index specially...
@@ -511,12 +516,7 @@
        I != E; ++I)
     if (const StructType *STy = dyn_cast<StructType>(*I)) {
       const ConstantInt* CUI = cast<ConstantInt>(I.getOperand());
-#if 0
-      unsigned FieldNo = 
-        CUI->getType()->isSigned() ? CUI->getSExtValue() : CUI->getZExtValue();
-#else
       int FieldNo = CUI->getSExtValue();
-#endif
       Offset += (unsigned)TD.getStructLayout(STy)->getElementOffset(FieldNo);
     } else if (isa<PointerType>(*I)) {
       if (!isa<Constant>(I.getOperand()) ||
@@ -556,7 +556,7 @@
 #endif
 
   // Add in the offset calculated...
-  Value.setOffset(Value.getOffset()+Offset);
+ Value.setOffset(Value.getOffset()+Offset);
 
   // Check the offset
   DSNode *N = Value.getNode();
@@ -577,20 +577,6 @@
 
   // Value is now the pointer we want to GEP to be...  
   setDestTo(GEP, Value);
-#if 0
-  if (debug && (isa<Instruction>(GEP))) {
-    Instruction * IGEP = (Instruction *)(&GEP);
-    DSNode * N = Value.getNode();
-    if (IGEP->getParent()->getParent()->getName() == "alloc_vfsmnt")
-    {
-      if (G.getPoolDescriptorsMap().count(N) != 0)
-        if (G.getPoolDescriptorsMap()[N]) {
-	  DEBUG(errs() << "LLVA: GEP[" << 0 << "]: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[N]->getName() << "\n");
-	}
-    }
-  }
-#endif
-
 }
 
 
@@ -753,6 +739,16 @@
     if (F->isIntrinsic() && visitIntrinsic(CS, F))
       return;
 
+  if (visitAllocation(CS))
+    return;
+
+  if (isa<InlineAsm>(CS.getCalledValue())) return;
+//  if (InlineAsm* IASM = dyn_cast<InlineAsm>(CS.getCalledValue())) {
+//    if (IASM->hasSideEffects())
+//      errs() << ASM w/ Side Effects\n";
+//    return;
+//  }
+
   // Set up the return value...
   DSNodeHandle RetVal;
   Instruction *I = CS.getInstruction();
@@ -826,8 +822,6 @@
 
   if (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy()) return;
 
-  const TargetData &TD = NH.getNode()->getTargetData();
-
   if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
     for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
       // We don't currently do any indexing for arrays...

Modified: poolalloc/trunk/lib/DSA/Printer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Printer.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Tue Mar  9 10:48:35 2010
@@ -60,11 +60,20 @@
   if (N->isNodeCompletelyFolded())
     OS << "COLLAPSED";
   else {
-    if (N->getType())
-      WriteTypeSymbolic(OS, N->getType(), M);
+    if (N->type_begin() != N->type_end())
+      for (DSNode::TyMapTy::const_iterator ii = N->type_begin(),
+           ee = N->type_end(); ii != ee; ++ii) {
+        OS << ii->first << ": ";
+        for (DSNode::TyMapTy::mapped_type::iterator ni = ii->second.begin(),
+                ne = ii->second.end(); ni != ne; ++ni) {
+          WriteTypeSymbolic(OS, *ni, M);
+          OS << ", ";
+        }
+        OS << " ";
+      }
     else
       OS << "VOID";
-    if (N->isArray())
+    if (N->isArrayNode())
       OS << " array";
   }
   if (unsigned NodeType = N->getNodeFlags()) {
@@ -137,6 +146,11 @@
     return O != 0;
   }
 
+  static std::string getEdgeSourceLabel(const void* Node,
+                                        DSNode::const_iterator I) {
+    return "*";
+  }
+
   static DSNode::const_iterator getEdgeTarget(const DSNode *Node,
                                               DSNode::const_iterator I) {
     unsigned O = I.getNode()->getLink(I.getOffset()).getOffset();

Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Tue Mar  9 10:48:35 2010
@@ -58,8 +58,9 @@
   if (!N || Visited.count(N)) return;
   Visited.insert(N);
 
-  for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
-    DSNodeHandle &NH = N->getLink(i);
+  for (DSNode::LinkMapTy::iterator ii = N->edge_begin(),
+          ee = N->edge_end(); ii != ee; ++ii) {
+    DSNodeHandle &NH = ii->second;
     if (DSNode *NN = NH.getNode()) {
       std::vector<const Function*> Functions;
       NN->addFullFunctionList(Functions);





More information about the llvm-commits mailing list