[SDAG] Refactor the code which deletes nodes in the DAG combiner to do

so using a single helper which adds operands back onto the worklist.

Several places didn't rigorously do this but a couple already did.
Factoring them together and doing it rigorously is important to delete
things recursively early on in the combiner and get a chance to see
accurate hasOneUse values. While no existing test cases change, an
upcoming patch to add DAG combining logic for PSHUFB requires this to
work correctly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214623 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2014-08-02 10:02:07 +00:00
parent ec6d4d8afb
commit 4e6635e7e6

View File

@ -153,6 +153,7 @@ namespace {
WorklistMap.erase(It);
}
void deleteAndRecombine(SDNode *N);
bool recursivelyDeleteUnusedNodes(SDNode *N);
SDValue CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
@ -451,6 +452,18 @@ CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) {
// Helper Functions
//===----------------------------------------------------------------------===//
void DAGCombiner::deleteAndRecombine(SDNode *N) {
removeFromWorklist(N);
// If the operands of this node are only used by the node, they will now be
// dead. Make sure to re-visit them and recursively delete dead nodes.
for (const SDValue &Op : N->ops())
if (Op->hasOneUse())
AddToWorklist(Op.getNode());
DAG.DeleteNode(N);
}
/// isNegatibleForFree - Return 1 if we can compute the negated form of the
/// specified expression for the same cost as the expression itself, or 2 if we
/// can compute the negated form more cheaply than the expression itself.
@ -754,14 +767,8 @@ SDValue DAGCombiner::CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
// Finally, if the node is now dead, remove it from the graph. The node
// may not be dead if the replacement process recursively simplified to
// something else needing this node.
if (N->use_empty()) {
// Nodes can be reintroduced into the worklist. Make sure we do not
// process a node that has been replaced.
removeFromWorklist(N);
// Finally, since the node is now dead, remove it from the graph.
DAG.DeleteNode(N);
}
if (N->use_empty())
deleteAndRecombine(N);
return SDValue(N, 0);
}
@ -779,17 +786,8 @@ CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) {
// Finally, if the node is now dead, remove it from the graph. The node
// may not be dead if the replacement process recursively simplified to
// something else needing this node.
if (TLO.Old.getNode()->use_empty()) {
removeFromWorklist(TLO.Old.getNode());
// If the operands of this node are only used by the node, they will now
// be dead. Make sure to visit them first to delete dead nodes early.
for (unsigned i = 0, e = TLO.Old.getNode()->getNumOperands(); i != e; ++i)
if (TLO.Old.getNode()->getOperand(i).getNode()->hasOneUse())
AddToWorklist(TLO.Old.getNode()->getOperand(i).getNode());
DAG.DeleteNode(TLO.Old.getNode());
}
if (TLO.Old.getNode()->use_empty())
deleteAndRecombine(TLO.Old.getNode());
}
/// SimplifyDemandedBits - Check the specified integer node value to see if
@ -829,8 +827,7 @@ void DAGCombiner::ReplaceLoadWithPromotedLoad(SDNode *Load, SDNode *ExtLoad) {
WorklistRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(SDValue(Load, 0), Trunc);
DAG.ReplaceAllUsesOfValueWith(SDValue(Load, 1), SDValue(ExtLoad, 1));
removeFromWorklist(Load);
DAG.DeleteNode(Load);
deleteAndRecombine(Load);
AddToWorklist(Trunc.getNode());
}
@ -1078,8 +1075,7 @@ bool DAGCombiner::PromoteLoad(SDValue Op) {
WorklistRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), NewLD.getValue(1));
removeFromWorklist(N);
DAG.DeleteNode(N);
deleteAndRecombine(N);
AddToWorklist(Result.getNode());
return true;
}
@ -1491,8 +1487,7 @@ SDValue DAGCombiner::visitMERGE_VALUES(SDNode *N) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
DAG.ReplaceAllUsesOfValueWith(SDValue(N, i), N->getOperand(i));
} while (!N->use_empty());
removeFromWorklist(N);
DAG.DeleteNode(N);
deleteAndRecombine(N);
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@ -6268,7 +6263,7 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) {
// Ideally this won't happen very often, because instcombine
// and the earlier dagcombine runs (where illegal nodes are
// permitted) should have folded most of them already.
DAG.DeleteNode(Res.getNode());
deleteAndRecombine(Res.getNode());
}
}
@ -7499,15 +7494,12 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
// will convert it back to (X & C1) >> C2.
CombineTo(N, NewBRCond, false);
// Truncate is dead.
if (Trunc) {
removeFromWorklist(Trunc);
DAG.DeleteNode(Trunc);
}
if (Trunc)
deleteAndRecombine(Trunc);
// Replace the uses of SRL with SETCC
WorklistRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(N1, SetCC);
removeFromWorklist(N1.getNode());
DAG.DeleteNode(N1.getNode());
deleteAndRecombine(N1.getNode());
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
}
@ -7536,8 +7528,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
dbgs() << '\n');
WorklistRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(N1, Tmp);
removeFromWorklist(TheXor);
DAG.DeleteNode(TheXor);
deleteAndRecombine(TheXor);
return DAG.getNode(ISD::BRCOND, SDLoc(N),
MVT::Other, Chain, Tmp, N2);
}
@ -7567,8 +7558,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
// Replace the uses of XOR with SETCC
WorklistRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(N1, SetCC);
removeFromWorklist(N1.getNode());
DAG.DeleteNode(N1.getNode());
deleteAndRecombine(N1.getNode());
return DAG.getNode(ISD::BRCOND, SDLoc(N),
MVT::Other, Chain, SetCC, N2);
}
@ -7812,7 +7802,7 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
}
// Finally, since the node is now dead, remove it from the graph.
DAG.DeleteNode(N);
deleteAndRecombine(N);
if (Swapped)
std::swap(BasePtr, Offset);
@ -7862,14 +7852,12 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
SDLoc(OtherUses[i]),
OtherUses[i]->getValueType(0), NewOp1, NewOp2);
DAG.ReplaceAllUsesOfValueWith(SDValue(OtherUses[i], 0), NewUse);
removeFromWorklist(OtherUses[i]);
DAG.DeleteNode(OtherUses[i]);
deleteAndRecombine(OtherUses[i]);
}
// Replace the uses of Ptr with uses of the updated base value.
DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0));
removeFromWorklist(Ptr.getNode());
DAG.DeleteNode(Ptr.getNode());
deleteAndRecombine(Ptr.getNode());
return true;
}
@ -7982,13 +7970,12 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
}
// Finally, since the node is now dead, remove it from the graph.
DAG.DeleteNode(N);
deleteAndRecombine(N);
// Replace the uses of Use with uses of the updated base value.
DAG.ReplaceAllUsesOfValueWith(SDValue(Op, 0),
Result.getValue(isLoad ? 1 : 0));
removeFromWorklist(Op);
DAG.DeleteNode(Op);
deleteAndRecombine(Op);
return true;
}
}
@ -8023,10 +8010,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
WorklistRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Chain);
if (N->use_empty()) {
removeFromWorklist(N);
DAG.DeleteNode(N);
}
if (N->use_empty())
deleteAndRecombine(N);
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
@ -8045,8 +8030,7 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1),
DAG.getUNDEF(N->getValueType(1)));
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 2), Chain);
removeFromWorklist(N);
DAG.DeleteNode(N);
deleteAndRecombine(N);
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
}
@ -9371,8 +9355,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
// Since we know that St is redundant, just iterate.
while (!St->use_empty())
DAG.ReplaceAllUsesWith(SDValue(St, 0), St->getChain());
removeFromWorklist(St);
DAG.DeleteNode(St);
deleteAndRecombine(St);
}
return true;
@ -9546,8 +9529,7 @@ bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
continue;
StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
DAG.ReplaceAllUsesOfValueWith(SDValue(St, 0), St->getChain());
removeFromWorklist(St);
DAG.DeleteNode(St);
deleteAndRecombine(St);
}
return true;