@@ -224,10 +224,6 @@ static cl::opt<unsigned> RangeIterThreshold(
224224 cl::desc("Threshold for switching to iteratively computing SCEV ranges"),
225225 cl::init(32));
226226
227- static cl::opt<unsigned> MaxLoopGuardCollectionDepth(
228- "scalar-evolution-max-loop-guard-collection-depth", cl::Hidden,
229- cl::desc("Maximum depth for recursive loop guard collection"), cl::init(1));
230-
231227static cl::opt<bool>
232228ClassifyExpressions("scalar-evolution-classify-expressions",
233229 cl::Hidden, cl::init(true),
@@ -10707,7 +10703,7 @@ ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
1070710703 if (const Loop *L = LI.getLoopFor(BB))
1070810704 return {L->getLoopPredecessor(), L->getHeader()};
1070910705
10710- return {nullptr, BB };
10706+ return {nullptr, nullptr };
1071110707}
1071210708
1071310709/// SCEV structural equivalence is usually sufficient for testing whether two
@@ -15325,83 +15321,7 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
1532515321
1532615322ScalarEvolution::LoopGuards
1532715323ScalarEvolution::LoopGuards::collect(const Loop *L, ScalarEvolution &SE) {
15328- BasicBlock *Header = L->getHeader();
15329- BasicBlock *Pred = L->getLoopPredecessor();
1533015324 LoopGuards Guards(SE);
15331- if (!Pred)
15332- return Guards;
15333- SmallPtrSet<const BasicBlock *, 8> VisitedBlocks;
15334- collectFromBlock(SE, Guards, Header, Pred, VisitedBlocks);
15335- return Guards;
15336- }
15337-
15338- void ScalarEvolution::LoopGuards::collectFromPHI(
15339- ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15340- const PHINode &Phi, SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks,
15341- SmallDenseMap<const BasicBlock *, LoopGuards> &IncomingGuards,
15342- unsigned Depth) {
15343- if (!SE.isSCEVable(Phi.getType()))
15344- return;
15345-
15346- using MinMaxPattern = std::pair<const SCEVConstant *, SCEVTypes>;
15347- auto GetMinMaxConst = [&](unsigned IncomingIdx) -> MinMaxPattern {
15348- const BasicBlock *InBlock = Phi.getIncomingBlock(IncomingIdx);
15349- if (!VisitedBlocks.insert(InBlock).second)
15350- return {nullptr, scCouldNotCompute};
15351- auto [G, Inserted] = IncomingGuards.try_emplace(InBlock, LoopGuards(SE));
15352- if (Inserted)
15353- collectFromBlock(SE, G->second, Phi.getParent(), InBlock, VisitedBlocks,
15354- Depth + 1);
15355- auto &RewriteMap = G->second.RewriteMap;
15356- if (RewriteMap.empty())
15357- return {nullptr, scCouldNotCompute};
15358- auto S = RewriteMap.find(SE.getSCEV(Phi.getIncomingValue(IncomingIdx)));
15359- if (S == RewriteMap.end())
15360- return {nullptr, scCouldNotCompute};
15361- auto *SM = dyn_cast_if_present<SCEVMinMaxExpr>(S->second);
15362- if (!SM)
15363- return {nullptr, scCouldNotCompute};
15364- if (const SCEVConstant *C0 = dyn_cast<SCEVConstant>(SM->getOperand(0)))
15365- return {C0, SM->getSCEVType()};
15366- return {nullptr, scCouldNotCompute};
15367- };
15368- auto MergeMinMaxConst = [](MinMaxPattern P1,
15369- MinMaxPattern P2) -> MinMaxPattern {
15370- auto [C1, T1] = P1;
15371- auto [C2, T2] = P2;
15372- if (!C1 || !C2 || T1 != T2)
15373- return {nullptr, scCouldNotCompute};
15374- switch (T1) {
15375- case scUMaxExpr:
15376- return {C1->getAPInt().ult(C2->getAPInt()) ? C1 : C2, T1};
15377- case scSMaxExpr:
15378- return {C1->getAPInt().slt(C2->getAPInt()) ? C1 : C2, T1};
15379- case scUMinExpr:
15380- return {C1->getAPInt().ugt(C2->getAPInt()) ? C1 : C2, T1};
15381- case scSMinExpr:
15382- return {C1->getAPInt().sgt(C2->getAPInt()) ? C1 : C2, T1};
15383- default:
15384- llvm_unreachable("Trying to merge non-MinMaxExpr SCEVs.");
15385- }
15386- };
15387- auto P = GetMinMaxConst(0);
15388- for (unsigned int In = 1; In < Phi.getNumIncomingValues(); In++) {
15389- if (!P.first)
15390- break;
15391- P = MergeMinMaxConst(P, GetMinMaxConst(In));
15392- }
15393- if (P.first) {
15394- const SCEV *LHS = SE.getSCEV(const_cast<PHINode *>(&Phi));
15395- SmallVector<const SCEV *, 2> Ops({P.first, LHS});
15396- const SCEV *RHS = SE.getMinMaxExpr(P.second, Ops);
15397- Guards.RewriteMap.insert({LHS, RHS});
15398- }
15399- }
15400-
15401- void ScalarEvolution::LoopGuards::collectFromBlock(
15402- ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15403- const BasicBlock *Block, const BasicBlock *Pred,
15404- SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks, unsigned Depth) {
1540515325 SmallVector<const SCEV *> ExprsToRewrite;
1540615326 auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
1540715327 const SCEV *RHS,
@@ -15735,13 +15655,14 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1573515655 }
1573615656 };
1573715657
15658+ BasicBlock *Header = L->getHeader();
1573815659 SmallVector<PointerIntPair<Value *, 1, bool>> Terms;
1573915660 // First, collect information from assumptions dominating the loop.
1574015661 for (auto &AssumeVH : SE.AC.assumptions()) {
1574115662 if (!AssumeVH)
1574215663 continue;
1574315664 auto *AssumeI = cast<CallInst>(AssumeVH);
15744- if (!SE.DT.dominates(AssumeI, Block ))
15665+ if (!SE.DT.dominates(AssumeI, Header ))
1574515666 continue;
1574615667 Terms.emplace_back(AssumeI->getOperand(0), true);
1574715668 }
@@ -15752,45 +15673,27 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1575215673 if (GuardDecl)
1575315674 for (const auto *GU : GuardDecl->users())
1575415675 if (const auto *Guard = dyn_cast<IntrinsicInst>(GU))
15755- if (Guard->getFunction() == Block ->getParent() &&
15756- SE.DT.dominates(Guard, Block ))
15676+ if (Guard->getFunction() == Header ->getParent() &&
15677+ SE.DT.dominates(Guard, Header ))
1575715678 Terms.emplace_back(Guard->getArgOperand(0), true);
1575815679
1575915680 // Third, collect conditions from dominating branches. Starting at the loop
1576015681 // predecessor, climb up the predecessor chain, as long as there are
1576115682 // predecessors that can be found that have unique successors leading to the
1576215683 // original header.
1576315684 // TODO: share this logic with isLoopEntryGuardedByCond.
15764- unsigned NumCollectedConditions = 0;
15765- VisitedBlocks.insert(Block);
15766- std::pair<const BasicBlock *, const BasicBlock *> Pair(Pred, Block);
15767- for (; Pair.first;
15685+ for (std::pair<const BasicBlock *, const BasicBlock *> Pair(
15686+ L->getLoopPredecessor(), Header);
15687+ Pair.first;
1576815688 Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
15769- VisitedBlocks.insert(Pair.second);
15689+
1577015690 const BranchInst *LoopEntryPredicate =
1577115691 dyn_cast<BranchInst>(Pair.first->getTerminator());
1577215692 if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
1577315693 continue;
1577415694
1577515695 Terms.emplace_back(LoopEntryPredicate->getCondition(),
1577615696 LoopEntryPredicate->getSuccessor(0) == Pair.second);
15777- NumCollectedConditions++;
15778-
15779- // If we are recursively collecting guards stop after 2
15780- // conditions to limit compile-time impact for now.
15781- if (Depth > 0 && NumCollectedConditions == 2)
15782- break;
15783- }
15784- // Finally, if we stopped climbing the predecessor chain because
15785- // there wasn't a unique one to continue, try to collect conditions
15786- // for PHINodes by recursively following all of their incoming
15787- // blocks and try to merge the found conditions to build a new one
15788- // for the Phi.
15789- if (Pair.second->hasNPredecessorsOrMore(2) &&
15790- Depth < MaxLoopGuardCollectionDepth) {
15791- SmallDenseMap<const BasicBlock *, LoopGuards> IncomingGuards;
15792- for (auto &Phi : Pair.second->phis())
15793- collectFromPHI(SE, Guards, Phi, VisitedBlocks, IncomingGuards, Depth);
1579415697 }
1579515698
1579615699 // Now apply the information from the collected conditions to
@@ -15847,6 +15750,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1584715750 Guards.RewriteMap.insert({Expr, Guards.rewrite(RewriteTo)});
1584815751 }
1584915752 }
15753+ return Guards;
1585015754}
1585115755
1585215756const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
0 commit comments