mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-09 21:50:38 +00:00
Re-apply "SDAG: Update ChainNodesMatched as nodes are deleted"
My first attempt at this had an overly aggressive assert - chain nodes will only be removed, but we could hit the assert if a non-chain node was CSE'd (NodeToMatch, for instance). This reapplies r271706 by reverting r271713 and fixing an assert. Original message: Avoid relying on UB by looking into deleted nodes for a marker value. Instead, update the list of chain nodes as we go. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271733 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ca03c97596
commit
78cd7cbf25
@ -249,6 +249,14 @@ public:
|
||||
virtual void NodeUpdated(SDNode *N);
|
||||
};
|
||||
|
||||
struct DAGNodeDeletedListener : public DAGUpdateListener {
|
||||
std::function<void(SDNode *, SDNode *)> Callback;
|
||||
DAGNodeDeletedListener(SelectionDAG &DAG,
|
||||
std::function<void(SDNode *, SDNode *)> Callback)
|
||||
: DAGUpdateListener(DAG), Callback(Callback) {}
|
||||
void NodeDeleted(SDNode *N, SDNode *E) override { Callback(N, E); }
|
||||
};
|
||||
|
||||
/// When true, additional steps are taken to
|
||||
/// ensure that getConstant() and similar functions return DAG nodes that
|
||||
/// have legal types. This is important after type legalization since
|
||||
|
@ -2163,10 +2163,8 @@ void SelectionDAGISel::UpdateChains(
|
||||
// Replace all the chain results with the final chain we ended up with.
|
||||
for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
|
||||
SDNode *ChainNode = ChainNodesMatched[i];
|
||||
|
||||
// If this node was already deleted, don't look at it.
|
||||
if (ChainNode->getOpcode() == ISD::DELETED_NODE)
|
||||
continue;
|
||||
assert(ChainNode->getOpcode() != ISD::DELETED_NODE &&
|
||||
"Deleted node left in chain");
|
||||
|
||||
// Don't replace the results of the root node if we're doing a
|
||||
// MorphNodeTo.
|
||||
@ -3368,6 +3366,13 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
|
||||
} else {
|
||||
assert(NodeToMatch->getOpcode() != ISD::DELETED_NODE &&
|
||||
"NodeToMatch was removed partway through selection");
|
||||
SelectionDAG::DAGNodeDeletedListener NDL(*CurDAG, [&](SDNode *N,
|
||||
SDNode *E) {
|
||||
auto &Chain = ChainNodesMatched;
|
||||
assert((!E || llvm::find(Chain, N) == Chain.end()) &&
|
||||
"Chain node replaced during MorphNode");
|
||||
Chain.erase(std::remove(Chain.begin(), Chain.end(), N), Chain.end());
|
||||
});
|
||||
Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops, EmitNodeInfo);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user