From 814a6794ba78ad52da499c67792602873e43d4f8 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Wed, 5 Dec 2018 00:41:30 +0000 Subject: [SelectionDAG] Split very large token factors for loads into 64k chunks. There's a 64k limit on the number of SDNode operands, and some very large functions with 64k or more loads can cause crashes due to this limit being hit when a TokenFactor with this many operands is created. To fix this, create sub-tokenfactors if we've exceeded the limit. No test case as it requires a very large function. rdar://45196621 Differential Revision: https://reviews.llvm.org/D55073 llvm-svn: 348324 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp') diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 0aa21d03b4c..a6a8ebe1a47 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1032,8 +1032,19 @@ SDValue SelectionDAGBuilder::getRoot() { } // Otherwise, we have to make a token factor node. - SDValue Root = DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, - PendingLoads); + // If we have >= 2^16 loads then split across multiple token factors as + // there's a 64k limit on the number of SDNode operands. + SDValue Root; + size_t Limit = (1 << 16) - 1; + while (PendingLoads.size() > Limit) { + unsigned SliceIdx = PendingLoads.size() - Limit; + auto ExtractedTFs = ArrayRef(PendingLoads).slice(SliceIdx, Limit); + SDValue NewTF = + DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, ExtractedTFs); + PendingLoads.erase(PendingLoads.begin() + SliceIdx, PendingLoads.end()); + PendingLoads.emplace_back(NewTF); + } + Root = DAG.getNode(ISD::TokenFactor, getCurSDLoc(), MVT::Other, PendingLoads); PendingLoads.clear(); DAG.setRoot(Root); return Root; -- cgit v1.2.3