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:
Chris Lattner 2010-03-14 19:43:04 +00:00
parent 700c71d2e8
commit 25e0ab9ae5

View File

@ -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());
} }
} }