aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-02-03 07:08:51 +0000
committerChris Lattner <sabre@nondot.org>2008-02-03 07:08:51 +0000
commit0fdf4edd2d64ee5d6bdb5d66beed0da325e5e117 (patch)
tree61e5dc9b4c480df97755d9a8b671d3c385b0c00d
parent9c980aa7364674c55978c4ee8f92cfeff71a57a7 (diff)
downloadexternal_llvm-0fdf4edd2d64ee5d6bdb5d66beed0da325e5e117.zip
external_llvm-0fdf4edd2d64ee5d6bdb5d66beed0da325e5e117.tar.gz
external_llvm-0fdf4edd2d64ee5d6bdb5d66beed0da325e5e117.tar.bz2
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
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp58
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h7
2 files changed, 34 insertions, 31 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index b614085..85a96a8 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 70f5c74..912747d 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);