forked from OSchip/llvm-project
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. llvm-svn: 23634
This commit is contained in:
parent
5fc3672722
commit
06f1d0f73a
|
@ -274,6 +274,11 @@ void DAGCombiner::Run(bool RunningAfterLegalize) {
|
|||
// 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 @@ void DAGCombiner::Run(bool RunningAfterLegalize) {
|
|||
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 @@ void DAGCombiner::Run(bool RunningAfterLegalize) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the root changed (e.g. it was a dead load, update the root).
|
||||
DAG.setRoot(Dummy.getValue());
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visit(SDNode *N) {
|
||||
|
|
|
@ -176,7 +176,7 @@ void SelectionDAG::RemoveDeadNodes(SDNode *N) {
|
|||
|
||||
// Create a dummy node (which is not added to allnodes), that adds a reference
|
||||
// to the root node, preventing it from being deleted.
|
||||
SDNode *DummyNode = new SDNode(ISD::EntryToken, getRoot());
|
||||
HandleSDNode Dummy(getRoot());
|
||||
|
||||
// If we have a hint to start from, use it.
|
||||
if (N) DeleteNodeIfDead(N, &AllNodeSet);
|
||||
|
@ -199,11 +199,7 @@ void SelectionDAG::RemoveDeadNodes(SDNode *N) {
|
|||
AllNodes.assign(AllNodeSet.begin(), AllNodeSet.end());
|
||||
|
||||
// If the root changed (e.g. it was a dead load, update the root).
|
||||
setRoot(DummyNode->getOperand(0));
|
||||
|
||||
// Now that we are done with the dummy node, delete it.
|
||||
DummyNode->getOperand(0).Val->removeUser(DummyNode);
|
||||
delete DummyNode;
|
||||
setRoot(Dummy.getValue());
|
||||
}
|
||||
|
||||
|
||||
|
@ -276,6 +272,7 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {
|
|||
void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
|
||||
bool Erased = false;
|
||||
switch (N->getOpcode()) {
|
||||
case ISD::HANDLENODE: return; // noop.
|
||||
case ISD::Constant:
|
||||
Erased = Constants.erase(std::make_pair(cast<ConstantSDNode>(N)->getValue(),
|
||||
N->getValueType(0)));
|
||||
|
@ -397,6 +394,8 @@ SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) {
|
|||
N->getValueType(0)))];
|
||||
if (L) return L;
|
||||
L = N;
|
||||
} else if (N->getOpcode() == ISD::HANDLENODE) {
|
||||
return 0; // never add it.
|
||||
} else if (N->getNumOperands() == 1) {
|
||||
SDNode *&U = UnaryOps[std::make_pair(N->getOpcode(),
|
||||
std::make_pair(N->getOperand(0),
|
||||
|
|
Loading…
Reference in New Issue