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
This commit is contained in:
Chris Lattner 2006-08-04 17:45:20 +00:00
parent 7e5c373d07
commit 190a418bf6
3 changed files with 35 additions and 56 deletions

View File

@ -105,10 +105,8 @@ public:
void Legalize(); void Legalize();
/// RemoveDeadNodes - This method deletes all unreachable nodes in the /// RemoveDeadNodes - This method deletes all unreachable nodes in the
/// SelectionDAG, including nodes (like loads) that have uses of their token /// SelectionDAG.
/// chain but no other uses and no side effect. If a node is passed in as an void RemoveDeadNodes();
/// argument, it is used as the seed for node deletion.
void RemoveDeadNodes(SDNode *N = 0);
SDOperand getString(const std::string &Val); SDOperand getString(const std::string &Val);
SDOperand getConstant(uint64_t Val, MVT::ValueType VT); 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, SDOperand Op1, SDOperand Op2);
SDNode **FindModifiedNodeSlot(SDNode *N, const std::vector<SDOperand> &Ops); SDNode **FindModifiedNodeSlot(SDNode *N, const std::vector<SDOperand> &Ops);
void DestroyDeadNode(SDNode *N);
void DeleteNodeNotInCSEMaps(SDNode *N); void DeleteNodeNotInCSEMaps(SDNode *N);
void setNodeValueTypes(SDNode *N, std::vector<MVT::ValueType> &RetVals); void setNodeValueTypes(SDNode *N, std::vector<MVT::ValueType> &RetVals);
void setNodeValueTypes(SDNode *N, MVT::ValueType VT1, MVT::ValueType VT2); void setNodeValueTypes(SDNode *N, MVT::ValueType VT1, MVT::ValueType VT2);

View File

@ -349,7 +349,7 @@ void SelectionDAGLegalize::LegalizeDAG() {
PackedNodes.clear(); PackedNodes.clear();
// Remove dead nodes now. // Remove dead nodes now.
DAG.RemoveDeadNodes(OldRoot.Val); DAG.RemoveDeadNodes();
} }

View File

@ -23,6 +23,7 @@
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include <iostream> #include <iostream>
#include <set> #include <set>
@ -263,69 +264,50 @@ const TargetMachine &SelectionDAG::getTarget() const {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// RemoveDeadNodes - This method deletes all unreachable nodes in the /// RemoveDeadNodes - This method deletes all unreachable nodes in the
/// SelectionDAG, including nodes (like loads) that have uses of their token /// SelectionDAG.
/// chain but no other uses and no side effect. If a node is passed in as an void SelectionDAG::RemoveDeadNodes() {
/// argument, it is used as the seed for node deletion.
void SelectionDAG::RemoveDeadNodes(SDNode *N) {
// Create a dummy node (which is not added to allnodes), that adds a reference // Create a dummy node (which is not added to allnodes), that adds a reference
// to the root node, preventing it from being deleted. // to the root node, preventing it from being deleted.
HandleSDNode Dummy(getRoot()); HandleSDNode Dummy(getRoot());
bool MadeChange = false; SmallVector<SDNode*, 128> DeadNodes;
// If we have a hint to start from, use it. // Add all obviously-dead nodes to the DeadNodes worklist.
if (N && N->use_empty()) {
DestroyDeadNode(N);
MadeChange = true;
}
for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I) for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I)
if (I->use_empty() && I->getOpcode() != 65535) { if (I->use_empty())
// Node is dead, recursively delete newly dead uses. DeadNodes.push_back(I);
DestroyDeadNode(I);
MadeChange = true; // Process the worklist, deleting the nodes and adding their uses to the
} // worklist.
while (!DeadNodes.empty()) {
// Walk the nodes list, removing the nodes we've marked as dead. SDNode *N = DeadNodes.back();
if (MadeChange) { DeadNodes.pop_back();
for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ) {
SDNode *N = I++; // Take the node out of the appropriate CSE map.
if (N->use_empty()) RemoveNodeFromCSEMaps(N);
AllNodes.erase(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). // If the root changed (e.g. it was a dead load, update the root).
setRoot(Dummy.getValue()); 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) { void SelectionDAG::DeleteNode(SDNode *N) {
assert(N->use_empty() && "Cannot delete a node that is not dead!"); assert(N->use_empty() && "Cannot delete a node that is not dead!");