Add a new HandleNode class, which is used to handle (haha) cases in the
dead node elim and dag combiner passes where the root is potentially updated.
This fixes a fixme in the dag combiner.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23634 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ed2af3c..26504df 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -274,6 +274,11 @@
// Add all the dag nodes to the worklist.
WorkList.insert(WorkList.end(), DAG.allnodes_begin(), DAG.allnodes_end());
+ // Create a dummy node (which is not added to allnodes), that adds a reference
+ // to the root node, preventing it from being deleted, and tracking any
+ // changes of the root.
+ HandleSDNode Dummy(DAG.getRoot());
+
// while the worklist isn't empty, inspect the node on the end of it and
// try and combine it.
while (!WorkList.empty()) {
@@ -281,15 +286,14 @@
WorkList.pop_back();
// If N has no uses, it is dead. Make sure to revisit all N's operands once
- // N is deleted from the DAG, since they too may now be dead.
- // FIXME: is there a better way to keep from deleting the dag root because
- // we think it has no uses? This works for now...
- if (N->use_empty() && N != DAG.getRoot().Val) {
+ // N is deleted from the DAG, since they too may now be dead or may have a
+ // reduced number of uses, allowing other xforms.
+ if (N->use_empty() && N != &Dummy) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
WorkList.push_back(N->getOperand(i).Val);
- DAG.DeleteNode(N);
removeFromWorkList(N);
+ DAG.DeleteNode(N);
continue;
}
@@ -319,6 +323,9 @@
}
}
}
+
+ // If the root changed (e.g. it was a dead load, update the root).
+ DAG.setRoot(Dummy.getValue());
}
SDOperand DAGCombiner::visit(SDNode *N) {