From: Chris Lattner Date: Wed, 5 Oct 2005 06:35:28 +0000 (+0000) Subject: Add a new HandleNode class, which is used to handle (haha) cases in the X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9503859c545496838165a340b1e1730dc1b83736;p=oota-llvm.git 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 ed2af3c590b..26504df265e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 61fa31959c1..d861e15fcbc 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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(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),