@@ -222,10 +222,6 @@ static cl::opt<unsigned> RangeIterThreshold(
222
222
cl::desc("Threshold for switching to iteratively computing SCEV ranges"),
223
223
cl::init(32));
224
224
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
-
229
225
static cl::opt<bool>
230
226
ClassifyExpressions("scalar-evolution-classify-expressions",
231
227
cl::Hidden, cl::init(true),
@@ -10717,7 +10713,7 @@ ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
10717
10713
if (const Loop *L = LI.getLoopFor(BB))
10718
10714
return {L->getLoopPredecessor(), L->getHeader()};
10719
10715
10720
- return {nullptr, BB };
10716
+ return {nullptr, nullptr };
10721
10717
}
10722
10718
10723
10719
/// SCEV structural equivalence is usually sufficient for testing whether two
@@ -15296,81 +15292,7 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
15296
15292
15297
15293
ScalarEvolution::LoopGuards
15298
15294
ScalarEvolution::LoopGuards::collect(const Loop *L, ScalarEvolution &SE) {
15299
- BasicBlock *Header = L->getHeader();
15300
- BasicBlock *Pred = L->getLoopPredecessor();
15301
15295
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) {
15374
15296
SmallVector<const SCEV *> ExprsToRewrite;
15375
15297
auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
15376
15298
const SCEV *RHS,
@@ -15709,13 +15631,14 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
15709
15631
}
15710
15632
};
15711
15633
15634
+ BasicBlock *Header = L->getHeader();
15712
15635
SmallVector<PointerIntPair<Value *, 1, bool>> Terms;
15713
15636
// First, collect information from assumptions dominating the loop.
15714
15637
for (auto &AssumeVH : SE.AC.assumptions()) {
15715
15638
if (!AssumeVH)
15716
15639
continue;
15717
15640
auto *AssumeI = cast<CallInst>(AssumeVH);
15718
- if (!SE.DT.dominates(AssumeI, Block ))
15641
+ if (!SE.DT.dominates(AssumeI, Header ))
15719
15642
continue;
15720
15643
Terms.emplace_back(AssumeI->getOperand(0), true);
15721
15644
}
@@ -15726,42 +15649,27 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
15726
15649
if (GuardDecl)
15727
15650
for (const auto *GU : GuardDecl->users())
15728
15651
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 ))
15731
15654
Terms.emplace_back(Guard->getArgOperand(0), true);
15732
15655
15733
15656
// Third, collect conditions from dominating branches. Starting at the loop
15734
15657
// predecessor, climb up the predecessor chain, as long as there are
15735
15658
// predecessors that can be found that have unique successors leading to the
15736
15659
// original header.
15737
15660
// 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;
15740
15664
Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
15741
- VisitedBlocks.insert(Pair.second);
15665
+
15742
15666
const BranchInst *LoopEntryPredicate =
15743
15667
dyn_cast<BranchInst>(Pair.first->getTerminator());
15744
15668
if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
15745
15669
continue;
15746
15670
15747
15671
Terms.emplace_back(LoopEntryPredicate->getCondition(),
15748
15672
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);
15765
15673
}
15766
15674
15767
15675
// Now apply the information from the collected conditions to
@@ -15818,6 +15726,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
15818
15726
Guards.RewriteMap.insert({Expr, Guards.rewrite(RewriteTo)});
15819
15727
}
15820
15728
}
15729
+ return Guards;
15821
15730
}
15822
15731
15823
15732
const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
0 commit comments