diff options
author | Chris Lattner <sabre@nondot.org> | 2008-02-03 07:08:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-02-03 07:08:51 +0000 |
commit | 42bd25f8ec6f506fa40d3304de47ba8a2e306f96 (patch) | |
tree | 61e5dc9b4c480df97755d9a8b671d3c385b0c00d /lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | |
parent | d8cd3be37062747f1abbcdb6de4547574ceea603 (diff) |
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeTypes.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index b614085e30..85a96a8e26 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); - } - } } |