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 @@ -1764,6 +1764,12 @@ } SDValue DAGCombiner::visitTokenFactor(SDNode *N) { + // Limit the number of nodes to explore, to avoid quadratic compile times. + // The limit helps to limit compile time for basic blocks with a large number + // of stores. + if (N->getNumOperands() > 1000) + return SDValue(); + // If N has two operands, where one has an input chain equal to the other, // the 'other' chain is redundant. if (N->getNumOperands() == 2) { @@ -14837,9 +14843,15 @@ RootNode = St->getChain().getNode(); + // Limit the number of nodes to explore, to avoid quadratic compile times. + // The limit helps to limit compile time for basic blocks with a large number + // of stores. + unsigned MaxNumberOfNodesToCheck = 1000; if (LoadSDNode *Ldn = dyn_cast(RootNode)) { RootNode = Ldn->getChain().getNode(); - for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E; ++I) + for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E; ++I) { + if (!MaxNumberOfNodesToCheck--) + break; if (I.getOperandNo() == 0 && isa(*I)) // walk down chain for (auto I2 = (*I)->use_begin(), E2 = (*I)->use_end(); I2 != E2; ++I2) if (I2.getOperandNo() == 0) @@ -14849,15 +14861,21 @@ if (CandidateMatch(OtherST, Ptr, PtrDiff)) StoreNodes.push_back(MemOpLink(OtherST, PtrDiff)); } - } else - for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E; ++I) - if (I.getOperandNo() == 0) + } + } else { + for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E; ++I) { + if (!MaxNumberOfNodesToCheck--) + break; + if (I.getOperandNo() == 0) { if (StoreSDNode *OtherST = dyn_cast(*I)) { BaseIndexOffset Ptr; int64_t PtrDiff; if (CandidateMatch(OtherST, Ptr, PtrDiff)) StoreNodes.push_back(MemOpLink(OtherST, PtrDiff)); } + } + } + } } // We need to check that merging these stores does not cause a loop in @@ -19978,7 +19996,13 @@ // Add ST's interval. Intervals.insert(0, (St->getMemoryVT().getSizeInBits() + 7) / 8, Unit); + // Limit the number of chains to explore, to avoid quadratic compile times. + // The limit helps to limit compile time for basic blocks with a large number + // of stores. + unsigned MaxNumberOfChains = 1000; while (StoreSDNode *Chain = dyn_cast(STChain->getChain())) { + if (!MaxNumberOfChains--) + break; // If the chain has more than one use, then we can't reorder the mem ops. if (!SDValue(Chain, 0)->hasOneUse()) break;