From: Chris Lattner Date: Fri, 4 Aug 2006 17:45:20 +0000 (+0000) Subject: Make SelectionDAG::RemoveDeadNodes iterative instead of recursive, which X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=190a418bf6b49a4ef1c1980229a2f0d516e8a2cd;p=oota-llvm.git Make SelectionDAG::RemoveDeadNodes iterative instead of recursive, which also make it simpler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29524 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index b053a3c25aa..f70403c9c9d 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -105,10 +105,8 @@ public: void Legalize(); /// RemoveDeadNodes - This method deletes all unreachable nodes in the - /// SelectionDAG, including nodes (like loads) that have uses of their token - /// chain but no other uses and no side effect. If a node is passed in as an - /// argument, it is used as the seed for node deletion. - void RemoveDeadNodes(SDNode *N = 0); + /// SelectionDAG. + void RemoveDeadNodes(); SDOperand getString(const std::string &Val); SDOperand getConstant(uint64_t Val, MVT::ValueType VT); @@ -447,7 +445,6 @@ private: SDNode **FindModifiedNodeSlot(SDNode *N, SDOperand Op1, SDOperand Op2); SDNode **FindModifiedNodeSlot(SDNode *N, const std::vector &Ops); - void DestroyDeadNode(SDNode *N); void DeleteNodeNotInCSEMaps(SDNode *N); void setNodeValueTypes(SDNode *N, std::vector &RetVals); void setNodeValueTypes(SDNode *N, MVT::ValueType VT1, MVT::ValueType VT2); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 9d0f6537046..4588ea4f4c3 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -349,7 +349,7 @@ void SelectionDAGLegalize::LegalizeDAG() { PackedNodes.clear(); // Remove dead nodes now. - DAG.RemoveDeadNodes(OldRoot.Val); + DAG.RemoveDeadNodes(); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 400b6fd942c..0a6c43e6268 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -23,6 +23,7 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include #include @@ -263,69 +264,50 @@ const TargetMachine &SelectionDAG::getTarget() const { //===----------------------------------------------------------------------===// /// RemoveDeadNodes - This method deletes all unreachable nodes in the -/// SelectionDAG, including nodes (like loads) that have uses of their token -/// chain but no other uses and no side effect. If a node is passed in as an -/// argument, it is used as the seed for node deletion. -void SelectionDAG::RemoveDeadNodes(SDNode *N) { +/// SelectionDAG. +void SelectionDAG::RemoveDeadNodes() { // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted. HandleSDNode Dummy(getRoot()); - bool MadeChange = false; + SmallVector DeadNodes; - // If we have a hint to start from, use it. - if (N && N->use_empty()) { - DestroyDeadNode(N); - MadeChange = true; - } - + // Add all obviously-dead nodes to the DeadNodes worklist. for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I) - if (I->use_empty() && I->getOpcode() != 65535) { - // Node is dead, recursively delete newly dead uses. - DestroyDeadNode(I); - MadeChange = true; - } - - // Walk the nodes list, removing the nodes we've marked as dead. - if (MadeChange) { - for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ) { - SDNode *N = I++; - if (N->use_empty()) - AllNodes.erase(N); + if (I->use_empty()) + DeadNodes.push_back(I); + + // Process the worklist, deleting the nodes and adding their uses to the + // worklist. + while (!DeadNodes.empty()) { + SDNode *N = DeadNodes.back(); + DeadNodes.pop_back(); + + // Take the node out of the appropriate CSE map. + RemoveNodeFromCSEMaps(N); + + // Next, brutally remove the operand list. This is safe to do, as there are + // no cycles in the graph. + for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { + SDNode *Operand = I->Val; + Operand->removeUser(N); + + // Now that we removed this operand, see if there are no uses of it left. + if (Operand->use_empty()) + DeadNodes.push_back(Operand); } + delete[] N->OperandList; + N->OperandList = 0; + N->NumOperands = 0; + + // Finally, remove N itself. + AllNodes.erase(N); } // If the root changed (e.g. it was a dead load, update the root). setRoot(Dummy.getValue()); } -/// DestroyDeadNode - We know that N is dead. Nuke it from the CSE maps for the -/// graph. If it is the last user of any of its operands, recursively process -/// them the same way. -/// -void SelectionDAG::DestroyDeadNode(SDNode *N) { - // Okay, we really are going to delete this node. First take this out of the - // appropriate CSE map. - RemoveNodeFromCSEMaps(N); - - // Next, brutally remove the operand list. This is safe to do, as there are - // no cycles in the graph. - for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { - SDNode *O = I->Val; - O->removeUser(N); - - // Now that we removed this operand, see if there are no uses of it left. - if (O->use_empty()) - DestroyDeadNode(O); - } - delete[] N->OperandList; - N->OperandList = 0; - N->NumOperands = 0; - - // Mark the node as dead. - N->MorphNodeTo(65535); -} - void SelectionDAG::DeleteNode(SDNode *N) { assert(N->use_empty() && "Cannot delete a node that is not dead!");