Add a method useful for updating DSA
[oota-llvm.git] / include / llvm / Analysis / DataStructure / DSNode.h
index 68b69ef7351146ddc20396be87a3ef2be23479cc..611293132bea15327f03d1fd5891012db693cef9 100644 (file)
@@ -42,6 +42,11 @@ class DSNode {
   /// null.
   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 class ilist_traits<DSNode>;
+
   /// Size - The current size of the node.  This should be equal to the size of
   /// the current type record.
   ///
@@ -154,12 +159,18 @@ public:
   DSNode *getForwardNode() const { return ForwardNH.getNode(); }
 
   /// isForwarding - Return true if this node is forwarding to another.
+  ///
   bool isForwarding() const { return !ForwardNH.isNull(); }
 
+  /// stopForwarding - When the last reference to this forwarding node has been
+  /// dropped, delete the node.
   void stopForwarding() {
-    assert(!ForwardNH.isNull() &&
+    assert(isForwarding() &&
            "Node isn't forwarding, cannot stopForwarding!");
     ForwardNH.setNode(0);
+    assert(ParentGraph == 0 &&
+           "Forwarding nodes must have been removed from graph!");
+    delete this;
   }
 
   /// hasLink - Return true if this memory object has a link in slot #LinkNo
@@ -313,7 +324,7 @@ public:
 
   void dropAllReferences() {
     Links.clear();
-    if (!ForwardNH.isNull())
+    if (isForwarding())
       ForwardNH.setNode(0);
   }
 
@@ -334,22 +345,46 @@ private:
   static void MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH);
 };
 
+//===----------------------------------------------------------------------===//
+// Define the ilist_traits specialization for the DSGraph ilist.
+//
+template<>
+struct ilist_traits<DSNode> {
+  static DSNode *getPrev(const DSNode *N) { return N->Prev; }
+  static DSNode *getNext(const DSNode *N) { return N->Next; }
+
+  static void setPrev(DSNode *N, DSNode *Prev) { N->Prev = Prev; }
+  static void setNext(DSNode *N, DSNode *Next) { N->Next = Next; }
+
+  static DSNode *createNode() { return new DSNode(0,0); }
+  //static DSNode *createNode(const DSNode &V) { return new DSNode(V); }
+
+
+  void addNodeToList(DSNode *NTy) {}
+  void removeNodeFromList(DSNode *NTy) {}
+  void transferNodesFromList(iplist<DSNode, ilist_traits> &L2,
+                             ilist_iterator<DSNode> first,
+                             ilist_iterator<DSNode> last) {}
+};
+
+template<>
+struct ilist_traits<const DSNode> : public ilist_traits<DSNode> {};
 
 //===----------------------------------------------------------------------===//
 // 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 == 0 || N->ForwardNH.isNull())
+          N->isForwarding()) && "Node handle offset out of range!");
+  if (N == 0 || !N->isForwarding())
     return N;
 
   return HandleForwarding();
 }
 
 inline void DSNodeHandle::setNode(DSNode *n) const {
-  assert(!n || !n->getForwardNode() && "Cannot set node to a forwarded node!");
-  if (N) N->NumReferrers--;
+  assert(!n || !n->isForwarding() && "Cannot set node to a forwarded node!");
+  if (N) getNode()->NumReferrers--;
   N = n;
   if (N) {
     N->NumReferrers++;
@@ -361,7 +396,7 @@ inline void DSNodeHandle::setNode(DSNode *n) const {
   }
   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!");
+          N->isForwarding()) && "Node handle offset out of range!");
 }
 
 inline bool DSNodeHandle::hasLink(unsigned Num) const {