llvm.org GIT mirror llvm / f0704e6
SDAG: Update ChainNodesMatched as nodes are deleted 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@271706 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Bogner 4 years ago
2 changed file(s) with 17 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
246246
247247 /// The node N that was updated.
248248 virtual void NodeUpdated(SDNode *N);
249 };
250
251 struct DAGNodeDeletedListener : public DAGUpdateListener {
252 std::function Callback;
253 DAGNodeDeletedListener(SelectionDAG &DAG,
254 std::function Callback)
255 : DAGUpdateListener(DAG), Callback(Callback) {}
256 void NodeDeleted(SDNode *N, SDNode *E) override { Callback(N, E); }
249257 };
250258
251259 /// When true, additional steps are taken to
21622162 // Replace all the chain results with the final chain we ended up with.
21632163 for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
21642164 SDNode *ChainNode = ChainNodesMatched[i];
2165
2166 // If this node was already deleted, don't look at it.
2167 if (ChainNode->getOpcode() == ISD::DELETED_NODE)
2168 continue;
2165 assert(ChainNode->getOpcode() != ISD::DELETED_NODE &&
2166 "Deleted node left in chain");
21692167
21702168 // Don't replace the results of the root node if we're doing a
21712169 // MorphNodeTo.
33673365 } else {
33683366 assert(NodeToMatch->getOpcode() != ISD::DELETED_NODE &&
33693367 "NodeToMatch was removed partway through selection");
3368 SelectionDAG::DAGNodeDeletedListener NDL(*CurDAG, [&](SDNode *N,
3369 SDNode *E) {
3370 assert(!E && "Unexpected node replacement in MorphNode");
3371 ChainNodesMatched.erase(std::remove(ChainNodesMatched.begin(),
3372 ChainNodesMatched.end(), N),
3373 ChainNodesMatched.end());
3374 });
33703375 Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops, EmitNodeInfo);
33713376 }
33723377