diff options
author | Chris Lattner <sabre@nondot.org> | 2006-08-04 17:45:20 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-08-04 17:45:20 +0000 |
commit | 190a418bf6b49a4ef1c1980229a2f0d516e8a2cd (patch) | |
tree | 2147802917bd7685dec7f1d1d2dcdc326483d494 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 7e5c373d07beec83264944d542dd4717fe01483c (diff) | |
download | external_llvm-190a418bf6b49a4ef1c1980229a2f0d516e8a2cd.zip external_llvm-190a418bf6b49a4ef1c1980229a2f0d516e8a2cd.tar.gz external_llvm-190a418bf6b49a4ef1c1980229a2f0d516e8a2cd.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 82 |
1 files changed, 32 insertions, 50 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 400b6fd..0a6c43e 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 <iostream> #include <set> @@ -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<SDNode*, 128> 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!"); |