mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-09 13:33:17 +00:00
rewrite ShrinkDemandedOps to be faster and indent less,
no functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98511 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
700c71d2e8
commit
25e0ab9ae5
@ -446,12 +446,25 @@ namespace {
|
|||||||
/// nodes from the worklist.
|
/// nodes from the worklist.
|
||||||
class SDOPsWorkListRemover : public SelectionDAG::DAGUpdateListener {
|
class SDOPsWorkListRemover : public SelectionDAG::DAGUpdateListener {
|
||||||
SmallVector<SDNode*, 128> &Worklist;
|
SmallVector<SDNode*, 128> &Worklist;
|
||||||
|
SmallPtrSet<SDNode*, 128> &InWorklist;
|
||||||
public:
|
public:
|
||||||
SDOPsWorkListRemover(SmallVector<SDNode*, 128> &wl) : Worklist(wl) {}
|
SDOPsWorkListRemover(SmallVector<SDNode*, 128> &wl,
|
||||||
|
SmallPtrSet<SDNode*, 128> &inwl)
|
||||||
|
: Worklist(wl), InWorklist(inwl) {}
|
||||||
|
|
||||||
|
void RemoveFromWorklist(SDNode *N) {
|
||||||
|
if (!InWorklist.erase(N)) return;
|
||||||
|
|
||||||
|
SmallVector<SDNode*, 128>::iterator I =
|
||||||
|
std::find(Worklist.begin(), Worklist.end(), N);
|
||||||
|
assert(I != Worklist.end() && "Not in worklist");
|
||||||
|
|
||||||
|
*I = Worklist.back();
|
||||||
|
Worklist.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void NodeDeleted(SDNode *N, SDNode *E) {
|
virtual void NodeDeleted(SDNode *N, SDNode *E) {
|
||||||
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), N),
|
RemoveFromWorklist(N);
|
||||||
Worklist.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void NodeUpdated(SDNode *N) {
|
virtual void NodeUpdated(SDNode *N) {
|
||||||
@ -480,20 +493,20 @@ static bool TrivialTruncElim(SDValue Op,
|
|||||||
/// 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.
|
||||||
void SelectionDAGISel::ShrinkDemandedOps() {
|
void SelectionDAGISel::ShrinkDemandedOps() {
|
||||||
SmallVector<SDNode*, 128> Worklist;
|
SmallVector<SDNode*, 128> Worklist;
|
||||||
|
SmallPtrSet<SDNode*, 128> InWorklist;
|
||||||
|
|
||||||
// Add all the dag nodes to the worklist.
|
// Add all the dag nodes to the worklist.
|
||||||
Worklist.reserve(CurDAG->allnodes_size());
|
Worklist.reserve(CurDAG->allnodes_size());
|
||||||
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
|
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
|
||||||
E = CurDAG->allnodes_end(); I != E; ++I)
|
E = CurDAG->allnodes_end(); I != E; ++I) {
|
||||||
Worklist.push_back(I);
|
Worklist.push_back(I);
|
||||||
|
InWorklist.insert(I);
|
||||||
APInt Mask;
|
}
|
||||||
APInt KnownZero;
|
|
||||||
APInt KnownOne;
|
|
||||||
|
|
||||||
TargetLowering::TargetLoweringOpt TLO(*CurDAG, true);
|
TargetLowering::TargetLoweringOpt TLO(*CurDAG, true);
|
||||||
while (!Worklist.empty()) {
|
while (!Worklist.empty()) {
|
||||||
SDNode *N = Worklist.pop_back_val();
|
SDNode *N = Worklist.pop_back_val();
|
||||||
|
InWorklist.erase(N);
|
||||||
|
|
||||||
if (N->use_empty() && N != CurDAG->getRoot().getNode()) {
|
if (N->use_empty() && N != CurDAG->getRoot().getNode()) {
|
||||||
CurDAG->DeleteNode(N);
|
CurDAG->DeleteNode(N);
|
||||||
@ -501,49 +514,52 @@ void SelectionDAGISel::ShrinkDemandedOps() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run ShrinkDemandedOp on scalar binary operations.
|
// Run ShrinkDemandedOp on scalar binary operations.
|
||||||
if (N->getNumValues() == 1 &&
|
if (N->getNumValues() != 1 ||
|
||||||
N->getValueType(0).isSimple() && N->getValueType(0).isInteger()) {
|
!N->getValueType(0).isSimple() || !N->getValueType(0).isInteger())
|
||||||
unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits();
|
continue;
|
||||||
APInt Demanded = APInt::getAllOnesValue(BitWidth);
|
|
||||||
APInt KnownZero, KnownOne;
|
unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits();
|
||||||
if (TLI.SimplifyDemandedBits(SDValue(N, 0), Demanded,
|
APInt Demanded = APInt::getAllOnesValue(BitWidth);
|
||||||
KnownZero, KnownOne, TLO) ||
|
APInt KnownZero, KnownOne;
|
||||||
(N->getOpcode() == ISD::TRUNCATE &&
|
if (!TLI.SimplifyDemandedBits(SDValue(N, 0), Demanded,
|
||||||
TrivialTruncElim(SDValue(N, 0), TLO))) {
|
KnownZero, KnownOne, TLO) &&
|
||||||
// Revisit the node.
|
(N->getOpcode() != ISD::TRUNCATE ||
|
||||||
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), N),
|
!TrivialTruncElim(SDValue(N, 0), TLO)))
|
||||||
Worklist.end());
|
continue;
|
||||||
Worklist.push_back(N);
|
|
||||||
|
// Revisit the node.
|
||||||
|
assert(!InWorklist.count(N) && "Already in worklist");
|
||||||
|
Worklist.push_back(N);
|
||||||
|
InWorklist.insert(N);
|
||||||
|
|
||||||
// Replace the old value with the new one.
|
// Replace the old value with the new one.
|
||||||
DEBUG(errs() << "\nReplacing ";
|
DEBUG(errs() << "\nShrinkDemandedOps replacing ";
|
||||||
TLO.Old.getNode()->dump(CurDAG);
|
TLO.Old.getNode()->dump(CurDAG);
|
||||||
errs() << "\nWith: ";
|
errs() << "\nWith: ";
|
||||||
TLO.New.getNode()->dump(CurDAG);
|
TLO.New.getNode()->dump(CurDAG);
|
||||||
errs() << '\n');
|
errs() << '\n');
|
||||||
|
|
||||||
Worklist.push_back(TLO.New.getNode());
|
if (InWorklist.insert(TLO.New.getNode()))
|
||||||
|
Worklist.push_back(TLO.New.getNode());
|
||||||
|
|
||||||
SDOPsWorkListRemover DeadNodes(Worklist);
|
SDOPsWorkListRemover DeadNodes(Worklist, InWorklist);
|
||||||
CurDAG->ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &DeadNodes);
|
CurDAG->ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &DeadNodes);
|
||||||
|
|
||||||
if (TLO.Old.getNode()->use_empty()) {
|
if (!TLO.Old.getNode()->use_empty()) continue;
|
||||||
for (unsigned i = 0, e = TLO.Old.getNode()->getNumOperands();
|
|
||||||
i != e; ++i) {
|
for (unsigned i = 0, e = TLO.Old.getNode()->getNumOperands();
|
||||||
SDNode *OpNode = TLO.Old.getNode()->getOperand(i).getNode();
|
i != e; ++i) {
|
||||||
if (OpNode->hasOneUse()) {
|
SDNode *OpNode = TLO.Old.getNode()->getOperand(i).getNode();
|
||||||
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
|
if (OpNode->hasOneUse()) {
|
||||||
OpNode), Worklist.end());
|
// Add OpNode to the end of the list to revisit.
|
||||||
Worklist.push_back(OpNode);
|
DeadNodes.RemoveFromWorklist(OpNode);
|
||||||
}
|
Worklist.push_back(OpNode);
|
||||||
}
|
InWorklist.insert(OpNode);
|
||||||
|
|
||||||
Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
|
|
||||||
TLO.Old.getNode()), Worklist.end());
|
|
||||||
CurDAG->DeleteNode(TLO.Old.getNode());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeadNodes.RemoveFromWorklist(TLO.Old.getNode());
|
||||||
|
CurDAG->DeleteNode(TLO.Old.getNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user