Skip to content

Commit e0c59b6

Browse files
Florian Hahnfhahn
authored andcommitted
Revert "[SCEV] Collect and merge loop guards through PHI nodes with multiple incoming values (llvm#113915)"
This reverts commit 7c8e05a.
1 parent bd7988d commit e0c59b6

File tree

4 files changed

+12
-474
lines changed

4 files changed

+12
-474
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,7 @@ class ScalarEvolution {
13261326
/// Collect loop guards in \p Guards, starting from PHINode \p
13271327
/// Phi, by calling \p collectFromBlock on the incoming blocks of
13281328
/// \Phi and trying to merge the found constraints into a single
1329-
/// combined one for \p Phi.
1329+
/// combined on for \p Phi.
13301330
static void collectFromPHI(
13311331
ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
13321332
const PHINode &Phi, SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks,

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 10 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
231227
static cl::opt<bool>
232228
ClassifyExpressions("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

1532615322
ScalarEvolution::LoopGuards
1532715323
ScalarEvolution::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

1585215756
const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {

0 commit comments

Comments
 (0)