@@ -15231,20 +15231,28 @@ ScalarEvolution::LoopGuards::collect(const Loop *L, ScalarEvolution &SE) {
1523115231
1523215232void ScalarEvolution::LoopGuards::collectFromPHI(
1523315233 ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15234- const PHINode &Phi, SmallPtrSet<const BasicBlock *, 8> &VisitedBlocks,
15234+ const PHINode &Phi, SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks,
15235+ SmallDenseMap<const BasicBlock *, LoopGuards> &IncomingGuards,
1523515236 unsigned Depth) {
1523615237 if (!SE.isSCEVable(Phi.getType()))
1523715238 return;
1523815239
1523915240 using MinMaxPattern = std::pair<const SCEVConstant *, SCEVTypes>;
1524015241 auto GetMinMaxConst = [&](unsigned In) -> MinMaxPattern {
15241- if (!VisitedBlocks.insert(Phi.getIncomingBlock(In)).second)
15242+ const BasicBlock *InBlock = Phi.getIncomingBlock(In);
15243+ if (!VisitedBlocks.insert(InBlock).second)
1524215244 return {nullptr, scCouldNotCompute};
15243- LoopGuards G(SE);
15244- collectFromBlock(SE, G, Phi.getParent(), Phi.getIncomingBlock(In),
15245- VisitedBlocks, Depth + 1);
15246- const SCEV *S = G.RewriteMap[SE.getSCEV(Phi.getIncomingValue(In))];
15247- auto *SM = dyn_cast_if_present<SCEVMinMaxExpr>(S);
15245+ if (!IncomingGuards.contains(InBlock)) {
15246+ LoopGuards G(SE);
15247+ collectFromBlock(SE, G, Phi.getParent(), InBlock, VisitedBlocks,
15248+ Depth + 1);
15249+ IncomingGuards.try_emplace(InBlock, std::move(G));
15250+ }
15251+ const LoopGuards &G = IncomingGuards.at(InBlock);
15252+ auto S = G.RewriteMap.find(SE.getSCEV(Phi.getIncomingValue(In)));
15253+ if (S == G.RewriteMap.end())
15254+ return {nullptr, scCouldNotCompute};
15255+ auto *SM = dyn_cast_if_present<SCEVMinMaxExpr>(S->second);
1524815256 if (!SM)
1524915257 return {nullptr, scCouldNotCompute};
1525015258 if (const SCEVConstant *C0 = dyn_cast<SCEVConstant>(SM->getOperand(0)))
@@ -15289,7 +15297,7 @@ void ScalarEvolution::LoopGuards::collectFromPHI(
1528915297void ScalarEvolution::LoopGuards::collectFromBlock(
1529015298 ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
1529115299 const BasicBlock *Block, const BasicBlock *Pred,
15292- SmallPtrSet <const BasicBlock *, 8 > &VisitedBlocks, unsigned Depth) {
15300+ SmallPtrSetImpl <const BasicBlock *> &VisitedBlocks, unsigned Depth) {
1529315301 SmallVector<const SCEV *> ExprsToRewrite;
1529415302 auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
1529515303 const SCEV *RHS,
@@ -15666,7 +15674,8 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1566615674 Terms.emplace_back(LoopEntryPredicate->getCondition(),
1566715675 LoopEntryPredicate->getSuccessor(0) == Pair.second);
1566815676
15669- // If we are recursively collecting guards stop after 2 predecessors.
15677+ // If we are recursively collecting guards stop after 2
15678+ // predecessors to limit compile-time impact for now.
1567015679 if (Depth > 0 && Terms.size() == 2)
1567115680 break;
1567215681 }
@@ -15677,8 +15686,9 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1567715686 // for the Phi.
1567815687 if (Pair.second->hasNPredecessorsOrMore(2) &&
1567915688 Depth < MaxLoopGuardCollectionDepth) {
15689+ SmallDenseMap<const BasicBlock *, LoopGuards> IncomingGuards;
1568015690 for (auto &Phi : Pair.second->phis()) {
15681- collectFromPHI(SE, Guards, Phi, VisitedBlocks, Depth);
15691+ collectFromPHI(SE, Guards, Phi, VisitedBlocks, IncomingGuards, Depth);
1568215692 }
1568315693 }
1568415694
0 commit comments