Use the new infrastructure for listening to node updates to
authorChris Lattner <sabre@nondot.org>
Sun, 3 Feb 2008 07:08:51 +0000 (07:08 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 3 Feb 2008 07:08:51 +0000 (07:08 +0000)
keep the LegalizeTypes node flags up to date when doing a RAUW.
This fixes a nasty bug that Duncan ran into and makes the
previous (nonbuggy case) more efficent.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46679 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
lib/CodeGen/SelectionDAG/LegalizeTypes.h

index b614085e30ccb794f500c62374d864a8944be44c..85a96a8e265d1bac1cc5126ee92bfaff33af833b 100644 (file)
@@ -217,6 +217,29 @@ void DAGTypeLegalizer::MarkNewNodes(SDNode *N) {
     Worklist.push_back(N);
 }
 
+namespace {
+  /// NodeUpdateListener - This class is a DAGUpdateListener that listens for
+  /// updates to nodes and recomputes their ready state.
+  class VISIBILITY_HIDDEN NodeUpdateListener : 
+    public SelectionDAG::DAGUpdateListener {
+    DAGTypeLegalizer &DTL;
+  public:
+    NodeUpdateListener(DAGTypeLegalizer &dtl) : DTL(dtl) {}
+    
+    virtual void NodeDeleted(SDNode *N) {
+      // Ignore deletes.
+    }
+    
+    virtual void NodeUpdated(SDNode *N) {
+      // Node updates can mean pretty much anything.  It is possible that an
+      // operand was set to something already processed (f.e.) in which case
+      // this node could become ready.  Recompoute its flags.
+      DTL.ReanalyzeNodeFlags(N);
+    }
+  };
+}
+
+
 /// ReplaceValueWith - The specified value was legalized to the specified other
 /// value.  If they are different, update the DAG and NodeIDs replacing any uses
 /// of From to use To instead.
@@ -229,26 +252,12 @@ void DAGTypeLegalizer::ReplaceValueWith(SDOperand From, SDOperand To) {
   
   // Anything that used the old node should now use the new one.  Note that this
   // can potentially cause recursive merging.
-  DAG.ReplaceAllUsesOfValueWith(From, To);
+  NodeUpdateListener NUL(*this);
+  DAG.ReplaceAllUsesOfValueWith(From, To, &NUL);
 
   // The old node may still be present in ExpandedNodes or PromotedNodes.
   // Inform them about the replacement.
   ReplacedNodes[From] = To;
-
-  // Since we just made an unstructured update to the DAG, which could wreak
-  // general havoc on anything that once used From and now uses To, walk all
-  // users of the result, updating their flags.
-  for (SDNode::use_iterator I = To.Val->use_begin(), E = To.Val->use_end();
-       I != E; ++I) {
-    SDNode *User = *I;
-    // If the node isn't already processed or in the worklist, mark it as new,
-    // then use MarkNewNodes to recompute its ID.
-    int NodeId = User->getNodeId();
-    if (NodeId != ReadyToProcess && NodeId != Processed) {
-      User->setNodeId(NewNode);
-      MarkNewNodes(User);
-    }
-  }
 }
 
 /// ReplaceNodeWith - Replace uses of the 'from' node's results with the 'to'
@@ -264,7 +273,8 @@ void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
   
   // Anything that used the old node should now use the new one.  Note that this
   // can potentially cause recursive merging.
-  DAG.ReplaceAllUsesWith(From, To);
+  NodeUpdateListener NUL(*this);
+  DAG.ReplaceAllUsesWith(From, To, &NUL);
   
   // The old node may still be present in ExpandedNodes or PromotedNodes.
   // Inform them about the replacement.
@@ -273,20 +283,6 @@ void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
            "Node results don't match");
     ReplacedNodes[SDOperand(From, i)] = SDOperand(To, i);
   }
-  
-  // Since we just made an unstructured update to the DAG, which could wreak
-  // general havoc on anything that once used From and now uses To, walk all
-  // users of the result, updating their flags.
-  for (SDNode::use_iterator I = To->use_begin(), E = To->use_end();I != E; ++I){
-    SDNode *User = *I;
-    // If the node isn't already processed or in the worklist, mark it as new,
-    // then use MarkNewNodes to recompute its ID.
-    int NodeId = User->getNodeId();
-    if (NodeId != ReadyToProcess && NodeId != Processed) {
-      User->setNodeId(NewNode);
-      MarkNewNodes(User);
-    }
-  }
 }
 
 
index 70f5c74dfd5ec24f6bd4c7b47def6bcb301c0436..912747df704631d17ca30e5ed519e42ab410cf76 100644 (file)
@@ -117,6 +117,13 @@ public:
   
   void run();
   
+  /// ReanalyzeNodeFlags - Recompute the NodeID flags for the specified node,
+  /// adding it to the worklist if ready.
+  void ReanalyzeNodeFlags(SDNode *N) {
+    N->setNodeId(NewNode);
+    MarkNewNodes(N);
+  }
+  
 private:
   void MarkNewNodes(SDNode *N);