From 42bd25f8ec6f506fa40d3304de47ba8a2e306f96 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 3 Feb 2008 07:08:51 +0000 Subject: [PATCH] Use the new infrastructure for listening to node updates to 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 | 58 ++++++++++------------ lib/CodeGen/SelectionDAG/LegalizeTypes.h | 7 +++ 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index b614085e30c..85a96a8e265 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -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); - } - } } diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 70f5c74dfd5..912747df704 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -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);