Skip to content

Commit 9a64d8a

Browse files
committed
[SCEV] Cache collected loop guards. NFCI
This tries to compensate for it by caching the collected loop guards, which gives a -0.07% geomean reduction for stage2-O3: https://llvm-compile-time-tracker.com/compare.php?from=aff98e4be05a1060e489ce62a88ee0ff365e571a&to=198a76db2c0b8fbda5374ffd195731a9d47469e3&stat=instructions:u LoopAccessAnalysis already had a LoopGuards cache for the innermost loop, so this hoists it up into ScalarEvolution.
1 parent aff98e4 commit 9a64d8a

File tree

4 files changed

+22
-26
lines changed

4 files changed

+22
-26
lines changed

llvm/include/llvm/Analysis/LoopAccessAnalysis.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,6 @@ class MemoryDepChecker {
334334
std::pair<const SCEV *, const SCEV *>>
335335
PointerBounds;
336336

337-
/// Cache for the loop guards of InnermostLoop.
338-
std::optional<ScalarEvolution::LoopGuards> LoopGuards;
339-
340337
/// Check whether there is a plausible dependence between the two
341338
/// accesses.
342339
///

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,6 @@ class ScalarEvolution {
13461346

13471347
/// Try to apply information from loop guards for \p L to \p Expr.
13481348
const SCEV *applyLoopGuards(const SCEV *Expr, const Loop *L);
1349-
const SCEV *applyLoopGuards(const SCEV *Expr, const LoopGuards &Guards);
13501349

13511350
/// Return true if the loop has no abnormal exits. That is, if the loop
13521351
/// is not infinite, it must exit through an explicit edge in the CFG.
@@ -1651,6 +1650,10 @@ class ScalarEvolution {
16511650
/// function as they are computed.
16521651
DenseMap<const Loop *, BackedgeTakenInfo> PredicatedBackedgeTakenCounts;
16531652

1653+
/// Cache the collected loop guards of the loops of this function as they are
1654+
/// computed.
1655+
DenseMap<const Loop *, LoopGuards> LoopGuardsCache;
1656+
16541657
/// Loops whose backedge taken counts directly use this non-constant SCEV.
16551658
DenseMap<const SCEV *, SmallPtrSet<PointerIntPair<const Loop *, 1, bool>, 4>>
16561659
BECountUsers;

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,16 +1945,13 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
19451945
!isa<SCEVCouldNotCompute>(SrcEnd_) &&
19461946
!isa<SCEVCouldNotCompute>(SinkStart_) &&
19471947
!isa<SCEVCouldNotCompute>(SinkEnd_)) {
1948-
if (!LoopGuards)
1949-
LoopGuards.emplace(
1950-
ScalarEvolution::LoopGuards::collect(InnermostLoop, SE));
1951-
auto SrcEnd = SE.applyLoopGuards(SrcEnd_, *LoopGuards);
1952-
auto SinkStart = SE.applyLoopGuards(SinkStart_, *LoopGuards);
1948+
auto SrcEnd = SE.applyLoopGuards(SrcEnd_, InnermostLoop);
1949+
auto SinkStart = SE.applyLoopGuards(SinkStart_, InnermostLoop);
19531950
if (SE.isKnownPredicate(CmpInst::ICMP_ULE, SrcEnd, SinkStart))
19541951
return MemoryDepChecker::Dependence::NoDep;
19551952

1956-
auto SinkEnd = SE.applyLoopGuards(SinkEnd_, *LoopGuards);
1957-
auto SrcStart = SE.applyLoopGuards(SrcStart_, *LoopGuards);
1953+
auto SinkEnd = SE.applyLoopGuards(SinkEnd_, InnermostLoop);
1954+
auto SrcStart = SE.applyLoopGuards(SrcStart_, InnermostLoop);
19581955
if (SE.isKnownPredicate(CmpInst::ICMP_ULE, SinkEnd, SrcStart))
19591956
return MemoryDepChecker::Dependence::NoDep;
19601957
}
@@ -2057,10 +2054,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
20572054
return Dependence::NoDep;
20582055
}
20592056
} else {
2060-
if (!LoopGuards)
2061-
LoopGuards.emplace(
2062-
ScalarEvolution::LoopGuards::collect(InnermostLoop, SE));
2063-
Dist = SE.applyLoopGuards(Dist, *LoopGuards);
2057+
Dist = SE.applyLoopGuards(Dist, InnermostLoop);
20642058
}
20652059

20662060
// Negative distances are not plausible dependencies.

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8417,6 +8417,7 @@ void ScalarEvolution::forgetAllLoops() {
84178417
// result.
84188418
BackedgeTakenCounts.clear();
84198419
PredicatedBackedgeTakenCounts.clear();
8420+
LoopGuardsCache.clear();
84208421
BECountUsers.clear();
84218422
LoopPropertiesCache.clear();
84228423
ConstantEvolutionLoopExitValue.clear();
@@ -10551,9 +10552,8 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1055110552
if (!isLoopInvariant(Step, L))
1055210553
return getCouldNotCompute();
1055310554

10554-
LoopGuards Guards = LoopGuards::collect(L, *this);
1055510555
// Specialize step for this loop so we get context sensitive facts below.
10556-
const SCEV *StepWLG = applyLoopGuards(Step, Guards);
10556+
const SCEV *StepWLG = applyLoopGuards(Step, L);
1055710557

1055810558
// For positive steps (counting up until unsigned overflow):
1055910559
// N = -Start/Step (as unsigned)
@@ -10570,7 +10570,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1057010570
// N = Distance (as unsigned)
1057110571
if (StepC &&
1057210572
(StepC->getValue()->isOne() || StepC->getValue()->isMinusOne())) {
10573-
APInt MaxBECount = getUnsignedRangeMax(applyLoopGuards(Distance, Guards));
10573+
APInt MaxBECount = getUnsignedRangeMax(applyLoopGuards(Distance, L));
1057410574
MaxBECount = APIntOps::umin(MaxBECount, getUnsignedRangeMax(Distance));
1057510575

1057610576
// When a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated,
@@ -10611,7 +10611,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1061110611
getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
1061210612
const SCEV *ConstantMax = getCouldNotCompute();
1061310613
if (Exact != getCouldNotCompute()) {
10614-
APInt MaxInt = getUnsignedRangeMax(applyLoopGuards(Exact, Guards));
10614+
APInt MaxInt = getUnsignedRangeMax(applyLoopGuards(Exact, L));
1061510615
ConstantMax =
1061610616
getConstant(APIntOps::umin(MaxInt, getUnsignedRangeMax(Exact)));
1061710617
}
@@ -10629,7 +10629,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1062910629

1063010630
const SCEV *M = E;
1063110631
if (E != getCouldNotCompute()) {
10632-
APInt MaxWithGuards = getUnsignedRangeMax(applyLoopGuards(E, Guards));
10632+
APInt MaxWithGuards = getUnsignedRangeMax(applyLoopGuards(E, L));
1063310633
M = getConstant(APIntOps::umin(MaxWithGuards, getUnsignedRangeMax(E)));
1063410634
}
1063510635
auto *S = isa<SCEVCouldNotCompute>(E) ? M : E;
@@ -13674,6 +13674,7 @@ ScalarEvolution::~ScalarEvolution() {
1367413674
HasRecMap.clear();
1367513675
BackedgeTakenCounts.clear();
1367613676
PredicatedBackedgeTakenCounts.clear();
13677+
LoopGuardsCache.clear();
1367713678

1367813679
assert(PendingLoopPredicates.empty() && "isImpliedCond garbage");
1367913680
assert(PendingPhiRanges.empty() && "getRangeRef garbage");
@@ -15889,10 +15890,11 @@ const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
1588915890
}
1589015891

1589115892
const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
15892-
return applyLoopGuards(Expr, LoopGuards::collect(L, *this));
15893-
}
15894-
15895-
const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr,
15896-
const LoopGuards &Guards) {
15897-
return Guards.rewrite(Expr);
15893+
auto Itr = LoopGuardsCache.find(L);
15894+
if (Itr == LoopGuardsCache.end()) {
15895+
LoopGuards Guard = LoopGuards::collect(L, *this);
15896+
LoopGuardsCache.insert({L, Guard});
15897+
return Guard.rewrite(Expr);
15898+
}
15899+
return Itr->second.rewrite(Expr);
1589815900
}

0 commit comments

Comments
 (0)