mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +00:00
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:
parent
7e5c373d07
commit
190a418bf6
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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!");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user