diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1801,8 +1801,19 @@ // Iterate through token factors. The TFs grows when new token factors are // encountered. for (unsigned i = 0; i < TFs.size(); ++i) { - SDNode *TF = TFs[i]; + // Limit number of nodes to inline, to avoid quadratic compile times. + // We have to add the outstanding tokenfactors to Ops, otherwise we might + // drop Ops from the resulting tokenfactor. + if (Ops.size() > 2048) { + for (unsigned j = i; j < TFs.size(); j++) + Ops.emplace_back(TFs[j], 0); + // Drop unprocessed tokenfactors from TFs, so we do not add them to the + // combiner worklist later. + TFs.resize(i); + break; + } + SDNode *TF = TFs[i]; // Check each of the operands. for (const SDValue &Op : TF->op_values()) { switch (Op.getOpcode()) { @@ -1816,8 +1827,6 @@ if (Op.hasOneUse() && !is_contained(TFs, Op.getNode())) { // Queue up for processing. TFs.push_back(Op.getNode()); - // Clean up in case the token factor is removed. - AddToWorklist(Op.getNode()); Changed = true; break; } @@ -1834,6 +1843,11 @@ } } + // Re-visit inlined tokenfactors, to clean them up in case they have been + // removed. Skip the first tokenfacto, as this is the current node. + for (unsigned i = 1, e = TFs.size(); i < e ; i++) + AddToWorklist(TFs[i]); + // Remove Nodes that are chained to another node in the list. Do so // by walking up chains breath-first stopping when we've seen // another operand. In general we must climb to the EntryNode, but we can exit