forked from OSchip/llvm-project
Clean up RemoveDeadNodes significantly, by eliminating the need for a temporary
set and eliminating the need to iterate whenever something is removed (which can be really slow in some cases). Thx to Jim for pointing out something silly I was getting stuck on. :) llvm-svn: 24241
This commit is contained in:
parent
88e234dd49
commit
aba48dd34c
|
@ -167,41 +167,47 @@ const TargetMachine &SelectionDAG::getTarget() const {
|
||||||
/// chain but no other uses and no side effect. If a node is passed in as an
|
/// 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.
|
/// argument, it is used as the seed for node deletion.
|
||||||
void SelectionDAG::RemoveDeadNodes(SDNode *N) {
|
void SelectionDAG::RemoveDeadNodes(SDNode *N) {
|
||||||
std::set<SDNode*> AllNodeSet(AllNodes.begin(), AllNodes.end());
|
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
// If we have a hint to start from, use it.
|
// If we have a hint to start from, use it.
|
||||||
if (N) DeleteNodeIfDead(N, &AllNodeSet);
|
if (N && N->use_empty()) {
|
||||||
|
DestroyDeadNode(N);
|
||||||
Restart:
|
MadeChange = true;
|
||||||
unsigned NumNodes = AllNodeSet.size();
|
|
||||||
for (std::set<SDNode*>::iterator I = AllNodeSet.begin(), E = AllNodeSet.end();
|
|
||||||
I != E; ++I) {
|
|
||||||
// Try to delete this node.
|
|
||||||
DeleteNodeIfDead(*I, &AllNodeSet);
|
|
||||||
|
|
||||||
// If we actually deleted any nodes, do not use invalid iterators in
|
|
||||||
// AllNodeSet.
|
|
||||||
if (AllNodeSet.size() != NumNodes)
|
|
||||||
goto Restart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore AllNodes.
|
for (unsigned i = 0, e = AllNodes.size(); i != e; ++i) {
|
||||||
if (AllNodes.size() != NumNodes)
|
// Try to delete this node.
|
||||||
AllNodes.assign(AllNodeSet.begin(), AllNodeSet.end());
|
SDNode *N = AllNodes[i];
|
||||||
|
if (N->use_empty() && N->getOpcode() != 65535) {
|
||||||
|
DestroyDeadNode(N);
|
||||||
|
MadeChange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk the nodes list, removing the nodes we've marked as dead.
|
||||||
|
if (MadeChange) {
|
||||||
|
for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
|
||||||
|
if (AllNodes[i]->use_empty()) {
|
||||||
|
delete AllNodes[i];
|
||||||
|
AllNodes[i] = AllNodes.back();
|
||||||
|
AllNodes.pop_back();
|
||||||
|
--i; --e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
|
/// graph. If it is the last user of any of its operands, recursively process
|
||||||
if (!N->use_empty())
|
/// them the same way.
|
||||||
return;
|
///
|
||||||
|
void SelectionDAG::DestroyDeadNode(SDNode *N) {
|
||||||
// Okay, we really are going to delete this node. First take this out of the
|
// Okay, we really are going to delete this node. First take this out of the
|
||||||
// appropriate CSE map.
|
// appropriate CSE map.
|
||||||
RemoveNodeFromCSEMaps(N);
|
RemoveNodeFromCSEMaps(N);
|
||||||
|
@ -214,16 +220,12 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
|
||||||
O->removeUser(N);
|
O->removeUser(N);
|
||||||
|
|
||||||
// Now that we removed this operand, see if there are no uses of it left.
|
// Now that we removed this operand, see if there are no uses of it left.
|
||||||
DeleteNodeIfDead(O, NodeSet);
|
if (O->use_empty())
|
||||||
|
DestroyDeadNode(O);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the node from the nodes set and delete it.
|
// Mark the node as dead.
|
||||||
std::set<SDNode*> &AllNodeSet = *(std::set<SDNode*>*)NodeSet;
|
N->MorphNodeTo(65535);
|
||||||
AllNodeSet.erase(N);
|
|
||||||
|
|
||||||
// Now that the node is gone, check to see if any of the operands of this node
|
|
||||||
// are dead now.
|
|
||||||
delete N;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionDAG::DeleteNode(SDNode *N) {
|
void SelectionDAG::DeleteNode(SDNode *N) {
|
||||||
|
|
Loading…
Reference in New Issue