@@ -224,10 +224,6 @@ static cl::opt<unsigned> RangeIterThreshold(
224
224
cl::desc("Threshold for switching to iteratively computing SCEV ranges"),
225
225
cl::init(32));
226
226
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
-
231
227
static cl::opt<bool>
232
228
ClassifyExpressions("scalar-evolution-classify-expressions",
233
229
cl::Hidden, cl::init(true),
@@ -10705,7 +10701,7 @@ ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
10705
10701
if (const Loop *L = LI.getLoopFor(BB))
10706
10702
return {L->getLoopPredecessor(), L->getHeader()};
10707
10703
10708
- return {nullptr, BB };
10704
+ return {nullptr, nullptr };
10709
10705
}
10710
10706
10711
10707
/// SCEV structural equivalence is usually sufficient for testing whether two
@@ -15329,83 +15325,7 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
15329
15325
15330
15326
ScalarEvolution::LoopGuards
15331
15327
ScalarEvolution::LoopGuards::collect(const Loop *L, ScalarEvolution &SE) {
15332
- BasicBlock *Header = L->getHeader();
15333
- BasicBlock *Pred = L->getLoopPredecessor();
15334
15328
LoopGuards Guards(SE);
15335
- if (!Pred)
15336
- return Guards;
15337
- SmallPtrSet<const BasicBlock *, 8> VisitedBlocks;
15338
- collectFromBlock(SE, Guards, Header, Pred, VisitedBlocks);
15339
- return Guards;
15340
- }
15341
-
15342
- void ScalarEvolution::LoopGuards::collectFromPHI(
15343
- ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15344
- const PHINode &Phi, SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks,
15345
- SmallDenseMap<const BasicBlock *, LoopGuards> &IncomingGuards,
15346
- unsigned Depth) {
15347
- if (!SE.isSCEVable(Phi.getType()))
15348
- return;
15349
-
15350
- using MinMaxPattern = std::pair<const SCEVConstant *, SCEVTypes>;
15351
- auto GetMinMaxConst = [&](unsigned IncomingIdx) -> MinMaxPattern {
15352
- const BasicBlock *InBlock = Phi.getIncomingBlock(IncomingIdx);
15353
- if (!VisitedBlocks.insert(InBlock).second)
15354
- return {nullptr, scCouldNotCompute};
15355
- auto [G, Inserted] = IncomingGuards.try_emplace(InBlock, LoopGuards(SE));
15356
- if (Inserted)
15357
- collectFromBlock(SE, G->second, Phi.getParent(), InBlock, VisitedBlocks,
15358
- Depth + 1);
15359
- auto &RewriteMap = G->second.RewriteMap;
15360
- if (RewriteMap.empty())
15361
- return {nullptr, scCouldNotCompute};
15362
- auto S = RewriteMap.find(SE.getSCEV(Phi.getIncomingValue(IncomingIdx)));
15363
- if (S == RewriteMap.end())
15364
- return {nullptr, scCouldNotCompute};
15365
- auto *SM = dyn_cast_if_present<SCEVMinMaxExpr>(S->second);
15366
- if (!SM)
15367
- return {nullptr, scCouldNotCompute};
15368
- if (const SCEVConstant *C0 = dyn_cast<SCEVConstant>(SM->getOperand(0)))
15369
- return {C0, SM->getSCEVType()};
15370
- return {nullptr, scCouldNotCompute};
15371
- };
15372
- auto MergeMinMaxConst = [](MinMaxPattern P1,
15373
- MinMaxPattern P2) -> MinMaxPattern {
15374
- auto [C1, T1] = P1;
15375
- auto [C2, T2] = P2;
15376
- if (!C1 || !C2 || T1 != T2)
15377
- return {nullptr, scCouldNotCompute};
15378
- switch (T1) {
15379
- case scUMaxExpr:
15380
- return {C1->getAPInt().ult(C2->getAPInt()) ? C1 : C2, T1};
15381
- case scSMaxExpr:
15382
- return {C1->getAPInt().slt(C2->getAPInt()) ? C1 : C2, T1};
15383
- case scUMinExpr:
15384
- return {C1->getAPInt().ugt(C2->getAPInt()) ? C1 : C2, T1};
15385
- case scSMinExpr:
15386
- return {C1->getAPInt().sgt(C2->getAPInt()) ? C1 : C2, T1};
15387
- default:
15388
- llvm_unreachable("Trying to merge non-MinMaxExpr SCEVs.");
15389
- }
15390
- };
15391
- auto P = GetMinMaxConst(0);
15392
- for (unsigned int In = 1; In < Phi.getNumIncomingValues(); In++) {
15393
- if (!P.first)
15394
- break;
15395
- P = MergeMinMaxConst(P, GetMinMaxConst(In));
15396
- }
15397
- if (P.first) {
15398
- const SCEV *LHS = SE.getSCEV(const_cast<PHINode *>(&Phi));
15399
- SmallVector<const SCEV *, 2> Ops({P.first, LHS});
15400
- const SCEV *RHS = SE.getMinMaxExpr(P.second, Ops);
15401
- Guards.RewriteMap.insert({LHS, RHS});
15402
- }
15403
- }
15404
-
15405
- void ScalarEvolution::LoopGuards::collectFromBlock(
15406
- ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
15407
- const BasicBlock *Block, const BasicBlock *Pred,
15408
- SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks, unsigned Depth) {
15409
15329
SmallVector<const SCEV *> ExprsToRewrite;
15410
15330
auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
15411
15331
const SCEV *RHS,
@@ -15739,13 +15659,14 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
15739
15659
}
15740
15660
};
15741
15661
15662
+ BasicBlock *Header = L->getHeader();
15742
15663
SmallVector<PointerIntPair<Value *, 1, bool>> Terms;
15743
15664
// First, collect information from assumptions dominating the loop.
15744
15665
for (auto &AssumeVH : SE.AC.assumptions()) {
15745
15666
if (!AssumeVH)
15746
15667
continue;
15747
15668
auto *AssumeI = cast<CallInst>(AssumeVH);
15748
- if (!SE.DT.dominates(AssumeI, Block ))
15669
+ if (!SE.DT.dominates(AssumeI, Header ))
15749
15670
continue;
15750
15671
Terms.emplace_back(AssumeI->getOperand(0), true);
15751
15672
}
@@ -15756,45 +15677,27 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
15756
15677
if (GuardDecl)
15757
15678
for (const auto *GU : GuardDecl->users())
15758
15679
if (const auto *Guard = dyn_cast<IntrinsicInst>(GU))
15759
- if (Guard->getFunction() == Block ->getParent() &&
15760
- SE.DT.dominates(Guard, Block ))
15680
+ if (Guard->getFunction() == Header ->getParent() &&
15681
+ SE.DT.dominates(Guard, Header ))
15761
15682
Terms.emplace_back(Guard->getArgOperand(0), true);
15762
15683
15763
15684
// Third, collect conditions from dominating branches. Starting at the loop
15764
15685
// predecessor, climb up the predecessor chain, as long as there are
15765
15686
// predecessors that can be found that have unique successors leading to the
15766
15687
// original header.
15767
15688
// TODO: share this logic with isLoopEntryGuardedByCond.
15768
- unsigned NumCollectedConditions = 0;
15769
- VisitedBlocks.insert(Block);
15770
- std::pair<const BasicBlock *, const BasicBlock *> Pair(Pred, Block);
15771
- for (; Pair.first;
15689
+ for (std::pair<const BasicBlock *, const BasicBlock *> Pair(
15690
+ L->getLoopPredecessor(), Header);
15691
+ Pair.first;
15772
15692
Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
15773
- VisitedBlocks.insert(Pair.second);
15693
+
15774
15694
const BranchInst *LoopEntryPredicate =
15775
15695
dyn_cast<BranchInst>(Pair.first->getTerminator());
15776
15696
if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
15777
15697
continue;
15778
15698
15779
15699
Terms.emplace_back(LoopEntryPredicate->getCondition(),
15780
15700
LoopEntryPredicate->getSuccessor(0) == Pair.second);
15781
- NumCollectedConditions++;
15782
-
15783
- // If we are recursively collecting guards stop after 2
15784
- // conditions to limit compile-time impact for now.
15785
- if (Depth > 0 && NumCollectedConditions == 2)
15786
- break;
15787
- }
15788
- // Finally, if we stopped climbing the predecessor chain because
15789
- // there wasn't a unique one to continue, try to collect conditions
15790
- // for PHINodes by recursively following all of their incoming
15791
- // blocks and try to merge the found conditions to build a new one
15792
- // for the Phi.
15793
- if (Pair.second->hasNPredecessorsOrMore(2) &&
15794
- Depth < MaxLoopGuardCollectionDepth) {
15795
- SmallDenseMap<const BasicBlock *, LoopGuards> IncomingGuards;
15796
- for (auto &Phi : Pair.second->phis())
15797
- collectFromPHI(SE, Guards, Phi, VisitedBlocks, IncomingGuards, Depth);
15798
15701
}
15799
15702
15800
15703
// Now apply the information from the collected conditions to
@@ -15851,6 +15754,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
15851
15754
Guards.RewriteMap.insert({Expr, Guards.rewrite(RewriteTo)});
15852
15755
}
15853
15756
}
15757
+ return Guards;
15854
15758
}
15855
15759
15856
15760
const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
0 commit comments