Skip to content

Commit df890b8

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 e6d4fd0 commit df890b8

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),
@@ -10705,7 +10701,7 @@ ScalarEvolution::getPredecessorWithUniqueSuccessorForBB(const BasicBlock *BB)
1070510701
if (const Loop *L = LI.getLoopFor(BB))
1070610702
return {L->getLoopPredecessor(), L->getHeader()};
1070710703

10708-
return {nullptr, BB};
10704+
return {nullptr, nullptr};
1070910705
}
1071010706

1071110707
/// SCEV structural equivalence is usually sufficient for testing whether two
@@ -15329,83 +15325,7 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
1532915325

1533015326
ScalarEvolution::LoopGuards
1533115327
ScalarEvolution::LoopGuards::collect(const Loop *L, ScalarEvolution &SE) {
15332-
BasicBlock *Header = L->getHeader();
15333-
BasicBlock *Pred = L->getLoopPredecessor();
1533415328
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) {
1540915329
SmallVector<const SCEV *> ExprsToRewrite;
1541015330
auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
1541115331
const SCEV *RHS,
@@ -15739,13 +15659,14 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1573915659
}
1574015660
};
1574115661

15662+
BasicBlock *Header = L->getHeader();
1574215663
SmallVector<PointerIntPair<Value *, 1, bool>> Terms;
1574315664
// First, collect information from assumptions dominating the loop.
1574415665
for (auto &AssumeVH : SE.AC.assumptions()) {
1574515666
if (!AssumeVH)
1574615667
continue;
1574715668
auto *AssumeI = cast<CallInst>(AssumeVH);
15748-
if (!SE.DT.dominates(AssumeI, Block))
15669+
if (!SE.DT.dominates(AssumeI, Header))
1574915670
continue;
1575015671
Terms.emplace_back(AssumeI->getOperand(0), true);
1575115672
}
@@ -15756,45 +15677,27 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1575615677
if (GuardDecl)
1575715678
for (const auto *GU : GuardDecl->users())
1575815679
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))
1576115682
Terms.emplace_back(Guard->getArgOperand(0), true);
1576215683

1576315684
// Third, collect conditions from dominating branches. Starting at the loop
1576415685
// predecessor, climb up the predecessor chain, as long as there are
1576515686
// predecessors that can be found that have unique successors leading to the
1576615687
// original header.
1576715688
// 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;
1577215692
Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
15773-
VisitedBlocks.insert(Pair.second);
15693+
1577415694
const BranchInst *LoopEntryPredicate =
1577515695
dyn_cast<BranchInst>(Pair.first->getTerminator());
1577615696
if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
1577715697
continue;
1577815698

1577915699
Terms.emplace_back(LoopEntryPredicate->getCondition(),
1578015700
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);
1579815701
}
1579915702

1580015703
// Now apply the information from the collected conditions to
@@ -15851,6 +15754,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1585115754
Guards.RewriteMap.insert({Expr, Guards.rewrite(RewriteTo)});
1585215755
}
1585315756
}
15757+
return Guards;
1585415758
}
1585515759

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

0 commit comments

Comments
 (0)