Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -115,6 +115,11 @@ "combiner-tokenfactor-inline-limit", cl::Hidden, cl::init(2048), cl::desc("Limit the number of operands to inline for Token Factors")); +static cl::opt StoreMergeLimit( + "store-merge-limit", cl::Hidden, cl::init(10), + cl::desc("Limit the number of times for a store being considered for " + "merging from the same root. ")); + namespace { class DAGCombiner { @@ -152,6 +157,11 @@ /// which have not yet been combined to the worklist. SmallPtrSet CombinedNodes; + /// Store how many times StoreNode is added to store merge candidates + /// because it is chained to RootNode. This is used to prevent a StoreNode + /// from being considered for merging too many times for very large Block. + DenseMap, unsigned> RootStorePairCountMap; + // AA - Used for DAG load/store alias analysis. AliasAnalysis *AA; @@ -15446,6 +15456,11 @@ unsigned NumNodesExplored = 0; if (LoadSDNode *Ldn = dyn_cast(RootNode)) { RootNode = Ldn->getChain().getNode(); + // Limit the number of times for a store being considered for + // merging from the same root. + if (RootStorePairCountMap[{RootNode, St}] > StoreMergeLimit) + return; + for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E && NumNodesExplored < 1024; ++I, ++NumNodesExplored) if (I.getOperandNo() == 0 && isa(*I)) // walk down chain @@ -15454,19 +15469,29 @@ if (StoreSDNode *OtherST = dyn_cast(*I2)) { BaseIndexOffset Ptr; int64_t PtrDiff; - if (CandidateMatch(OtherST, Ptr, PtrDiff)) + if (CandidateMatch(OtherST, Ptr, PtrDiff)) { + RootStorePairCountMap[{RootNode, OtherST}]++; StoreNodes.push_back(MemOpLink(OtherST, PtrDiff)); + } } - } else + } else { + // Limit the number of times for a store being considered for + // merging from the same root. + if (RootStorePairCountMap[{RootNode, St}] > StoreMergeLimit) + return; + for (auto I = RootNode->use_begin(), E = RootNode->use_end(); I != E && NumNodesExplored < 1024; ++I, ++NumNodesExplored) if (I.getOperandNo() == 0) if (StoreSDNode *OtherST = dyn_cast(*I)) { BaseIndexOffset Ptr; int64_t PtrDiff; - if (CandidateMatch(OtherST, Ptr, PtrDiff)) + if (CandidateMatch(OtherST, Ptr, PtrDiff)) { + RootStorePairCountMap[{RootNode, OtherST}]++; StoreNodes.push_back(MemOpLink(OtherST, PtrDiff)); + } } + } } // We need to check that merging these stores does not cause a loop in