@@ -222,10 +222,6 @@ static cl::opt<unsigned> RangeIterThreshold(
222222 cl::desc("Threshold for switching to iteratively computing SCEV ranges"),
223223 cl::init(32));
224224
225- static cl::opt<unsigned> MaxLoopGuardCollectionDepth(
226- "scalar-evolution-max-loop-guard-collection-depth", cl::Hidden,
227- cl::desc("Maximum depth for recrusive loop guard collection"), cl::init(1));
228-
229225static cl::opt<bool>
230226ClassifyExpressions("scalar-evolution-classify-expressions",
231227 cl::Hidden, cl::init(true),
@@ -10717,7 +10713,7 @@ ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
1071710713 if (const Loop *L = LI.getLoopFor(BB))
1071810714 return {L->getLoopPredecessor(), L->getHeader()};
1071910715
10720- return {nullptr, BB };
10716+ return {nullptr, nullptr };
1072110717}
1072210718
1072310719/// SCEV structural equivalence is usually sufficient for testing whether two
@@ -15296,81 +15292,7 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
1529615292
1529715293ScalarEvolution::LoopGuards
1529815294ScalarEvolution::LoopGuards::collect(const Loop *L, ScalarEvolution &SE) {
15299- BasicBlock *Header = L->getHeader();
15300- BasicBlock *Pred = L->getLoopPredecessor();
1530115295 LoopGuards Guards(SE);
15302- SmallPtrSet<const BasicBlock *, 8> VisitedBlocks;
15303- collectFromBlock(SE, Guards, Header, Pred, VisitedBlocks);
15304- return Guards;
15305- }
15306-
15307- void ScalarEvolution::LoopGuards::collectFromPHI(
15308- ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15309- const PHINode &Phi, SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks,
15310- SmallDenseMap<const BasicBlock *, LoopGuards> &IncomingGuards,
15311- unsigned Depth) {
15312- if (!SE.isSCEVable(Phi.getType()))
15313- return;
15314-
15315- using MinMaxPattern = std::pair<const SCEVConstant *, SCEVTypes>;
15316- auto GetMinMaxConst = [&](unsigned IncomingIdx) -> MinMaxPattern {
15317- const BasicBlock *InBlock = Phi.getIncomingBlock(IncomingIdx);
15318- if (!VisitedBlocks.insert(InBlock).second)
15319- return {nullptr, scCouldNotCompute};
15320- auto [G, Inserted] = IncomingGuards.try_emplace(InBlock, LoopGuards(SE));
15321- if (Inserted)
15322- collectFromBlock(SE, G->second, Phi.getParent(), InBlock, VisitedBlocks,
15323- Depth + 1);
15324- auto &RewriteMap = G->second.RewriteMap;
15325- if (RewriteMap.empty())
15326- return {nullptr, scCouldNotCompute};
15327- auto S = RewriteMap.find(SE.getSCEV(Phi.getIncomingValue(IncomingIdx)));
15328- if (S == RewriteMap.end())
15329- return {nullptr, scCouldNotCompute};
15330- auto *SM = dyn_cast_if_present<SCEVMinMaxExpr>(S->second);
15331- if (!SM)
15332- return {nullptr, scCouldNotCompute};
15333- if (const SCEVConstant *C0 = dyn_cast<SCEVConstant>(SM->getOperand(0)))
15334- return {C0, SM->getSCEVType()};
15335- return {nullptr, scCouldNotCompute};
15336- };
15337- auto MergeMinMaxConst = [](MinMaxPattern P1,
15338- MinMaxPattern P2) -> MinMaxPattern {
15339- auto [C1, T1] = P1;
15340- auto [C2, T2] = P2;
15341- if (!C1 || !C2 || T1 != T2)
15342- return {nullptr, scCouldNotCompute};
15343- switch (T1) {
15344- case scUMaxExpr:
15345- return {C1->getAPInt().ult(C2->getAPInt()) ? C1 : C2, T1};
15346- case scSMaxExpr:
15347- return {C1->getAPInt().slt(C2->getAPInt()) ? C1 : C2, T1};
15348- case scUMinExpr:
15349- return {C1->getAPInt().ugt(C2->getAPInt()) ? C1 : C2, T1};
15350- case scSMinExpr:
15351- return {C1->getAPInt().sgt(C2->getAPInt()) ? C1 : C2, T1};
15352- default:
15353- llvm_unreachable("Trying to merge non-MinMaxExpr SCEVs.");
15354- }
15355- };
15356- auto P = GetMinMaxConst(0);
15357- for (unsigned int In = 1; In < Phi.getNumIncomingValues(); In++) {
15358- if (!P.first)
15359- break;
15360- P = MergeMinMaxConst(P, GetMinMaxConst(In));
15361- }
15362- if (P.first) {
15363- const SCEV *LHS = SE.getSCEV(const_cast<PHINode *>(&Phi));
15364- SmallVector<const SCEV *, 2> Ops({P.first, LHS});
15365- const SCEV *RHS = SE.getMinMaxExpr(P.second, Ops);
15366- Guards.RewriteMap.insert({LHS, RHS});
15367- }
15368- }
15369-
15370- void ScalarEvolution::LoopGuards::collectFromBlock(
15371- ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15372- const BasicBlock *Block, const BasicBlock *Pred,
15373- SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks, unsigned Depth) {
1537415296 SmallVector<const SCEV *> ExprsToRewrite;
1537515297 auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
1537615298 const SCEV *RHS,
@@ -15709,13 +15631,14 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1570915631 }
1571015632 };
1571115633
15634+ BasicBlock *Header = L->getHeader();
1571215635 SmallVector<PointerIntPair<Value *, 1, bool>> Terms;
1571315636 // First, collect information from assumptions dominating the loop.
1571415637 for (auto &AssumeVH : SE.AC.assumptions()) {
1571515638 if (!AssumeVH)
1571615639 continue;
1571715640 auto *AssumeI = cast<CallInst>(AssumeVH);
15718- if (!SE.DT.dominates(AssumeI, Block ))
15641+ if (!SE.DT.dominates(AssumeI, Header ))
1571915642 continue;
1572015643 Terms.emplace_back(AssumeI->getOperand(0), true);
1572115644 }
@@ -15726,42 +15649,27 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1572615649 if (GuardDecl)
1572715650 for (const auto *GU : GuardDecl->users())
1572815651 if (const auto *Guard = dyn_cast<IntrinsicInst>(GU))
15729- if (Guard->getFunction() == Block ->getParent() &&
15730- SE.DT.dominates(Guard, Block ))
15652+ if (Guard->getFunction() == Header ->getParent() &&
15653+ SE.DT.dominates(Guard, Header ))
1573115654 Terms.emplace_back(Guard->getArgOperand(0), true);
1573215655
1573315656 // Third, collect conditions from dominating branches. Starting at the loop
1573415657 // predecessor, climb up the predecessor chain, as long as there are
1573515658 // predecessors that can be found that have unique successors leading to the
1573615659 // original header.
1573715660 // TODO: share this logic with isLoopEntryGuardedByCond.
15738- std::pair<const BasicBlock *, const BasicBlock *> Pair(Pred, Block);
15739- for (; Pair.first;
15661+ for (std::pair<const BasicBlock *, const BasicBlock *> Pair(
15662+ L->getLoopPredecessor(), Header);
15663+ Pair.first;
1574015664 Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
15741- VisitedBlocks.insert(Pair.second);
15665+
1574215666 const BranchInst *LoopEntryPredicate =
1574315667 dyn_cast<BranchInst>(Pair.first->getTerminator());
1574415668 if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
1574515669 continue;
1574615670
1574715671 Terms.emplace_back(LoopEntryPredicate->getCondition(),
1574815672 LoopEntryPredicate->getSuccessor(0) == Pair.second);
15749-
15750- // If we are recursively collecting guards stop after 2
15751- // predecessors to limit compile-time impact for now.
15752- if (Depth > 0 && Terms.size() == 2)
15753- break;
15754- }
15755- // Finally, if we stopped climbing the predecessor chain because
15756- // there wasn't a unique one to continue, try to collect conditions
15757- // for PHINodes by recursively following all of their incoming
15758- // blocks and try to merge the found conditions to build a new one
15759- // for the Phi.
15760- if (Pair.second->hasNPredecessorsOrMore(2) &&
15761- Depth < MaxLoopGuardCollectionDepth) {
15762- SmallDenseMap<const BasicBlock *, LoopGuards> IncomingGuards;
15763- for (auto &Phi : Pair.second->phis())
15764- collectFromPHI(SE, Guards, Phi, VisitedBlocks, IncomingGuards, Depth);
1576515673 }
1576615674
1576715675 // Now apply the information from the collected conditions to
@@ -15818,6 +15726,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1581815726 Guards.RewriteMap.insert({Expr, Guards.rewrite(RewriteTo)});
1581915727 }
1582015728 }
15729+ return Guards;
1582115730}
1582215731
1582315732const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
0 commit comments