mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Dan pointed out checking whether a node is dead by comparing its opcode to ISD::DELETED_NODE is not safe. Use a DAGUpdateListener to remove dead nodes from work list instead.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93031 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
87563b3937
commit
54e146b935
@ -438,6 +438,25 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
|
|||||||
SDB->clear();
|
SDB->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
/// WorkListRemover - This class is a DAGUpdateListener that removes any deleted
|
||||||
|
/// nodes from the worklist.
|
||||||
|
class SDOPsWorkListRemover : public SelectionDAG::DAGUpdateListener {
|
||||||
|
SmallVector<SDNode*, 128> &Worklist;
|
||||||
|
public:
|
||||||
|
SDOPsWorkListRemover(SmallVector<SDNode*, 128> &wl) : Worklist(wl) {}
|
||||||
|
|
||||||
|
virtual void NodeDeleted(SDNode *N, SDNode *E) {
|
||||||
|
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), N),
|
||||||
|
Worklist.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void NodeUpdated(SDNode *N) {
|
||||||
|
// Ignore updates.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// ShrinkDemandedOps - A late transformation pass that shrink expressions
|
/// ShrinkDemandedOps - A late transformation pass that shrink expressions
|
||||||
/// using TargetLowering::TargetLoweringOpt::ShrinkDemandedOp. It converts
|
/// using TargetLowering::TargetLoweringOpt::ShrinkDemandedOp. It converts
|
||||||
/// x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
|
/// x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
|
||||||
@ -459,8 +478,7 @@ void SelectionDAGISel::ShrinkDemandedOps() {
|
|||||||
SDNode *N = Worklist.pop_back_val();
|
SDNode *N = Worklist.pop_back_val();
|
||||||
|
|
||||||
if (N->use_empty() && N != CurDAG->getRoot().getNode()) {
|
if (N->use_empty() && N != CurDAG->getRoot().getNode()) {
|
||||||
if (N->getOpcode() != ISD::DELETED_NODE)
|
CurDAG->DeleteNode(N);
|
||||||
CurDAG->DeleteNode(N);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +503,9 @@ void SelectionDAGISel::ShrinkDemandedOps() {
|
|||||||
errs() << '\n');
|
errs() << '\n');
|
||||||
|
|
||||||
Worklist.push_back(TLO.New.getNode());
|
Worklist.push_back(TLO.New.getNode());
|
||||||
CurDAG->ReplaceAllUsesOfValueWith(TLO.Old, TLO.New);
|
|
||||||
|
SDOPsWorkListRemover DeadNodes(Worklist);
|
||||||
|
CurDAG->ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &DeadNodes);
|
||||||
|
|
||||||
if (TLO.Old.getNode()->use_empty()) {
|
if (TLO.Old.getNode()->use_empty()) {
|
||||||
for (unsigned i = 0, e = TLO.Old.getNode()->getNumOperands();
|
for (unsigned i = 0, e = TLO.Old.getNode()->getNumOperands();
|
||||||
@ -493,15 +513,13 @@ void SelectionDAGISel::ShrinkDemandedOps() {
|
|||||||
SDNode *OpNode = TLO.Old.getNode()->getOperand(i).getNode();
|
SDNode *OpNode = TLO.Old.getNode()->getOperand(i).getNode();
|
||||||
if (OpNode->hasOneUse()) {
|
if (OpNode->hasOneUse()) {
|
||||||
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
|
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
|
||||||
OpNode),
|
OpNode), Worklist.end());
|
||||||
Worklist.end());
|
Worklist.push_back(OpNode);
|
||||||
Worklist.push_back(TLO.Old.getNode()->getOperand(i).getNode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
|
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
|
||||||
TLO.Old.getNode()),
|
TLO.Old.getNode()), Worklist.end());
|
||||||
Worklist.end());
|
|
||||||
CurDAG->DeleteNode(TLO.Old.getNode());
|
CurDAG->DeleteNode(TLO.Old.getNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user