mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
[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:
parent
ec6d4d8afb
commit
4e6635e7e6
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user