Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions llvm/include/llvm/Analysis/LoopAccessAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,6 @@ class MemoryDepChecker {
std::pair<const SCEV *, const SCEV *>>
PointerBounds;

/// Cache for the loop guards of InnermostLoop.
std::optional<ScalarEvolution::LoopGuards> LoopGuards;

/// Check whether there is a plausible dependence between the two
/// accesses.
///
Expand Down
5 changes: 4 additions & 1 deletion llvm/include/llvm/Analysis/ScalarEvolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,6 @@ class ScalarEvolution {

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

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

/// Cache the collected loop guards of the loops of this function as they are
/// computed.
DenseMap<const Loop *, LoopGuards> LoopGuardsCache;

/// Loops whose backedge taken counts directly use this non-constant SCEV.
DenseMap<const SCEV *, SmallPtrSet<PointerIntPair<const Loop *, 1, bool>, 4>>
BECountUsers;
Expand Down
16 changes: 5 additions & 11 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1945,16 +1945,13 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
!isa<SCEVCouldNotCompute>(SrcEnd_) &&
!isa<SCEVCouldNotCompute>(SinkStart_) &&
!isa<SCEVCouldNotCompute>(SinkEnd_)) {
if (!LoopGuards)
LoopGuards.emplace(
ScalarEvolution::LoopGuards::collect(InnermostLoop, SE));
auto SrcEnd = SE.applyLoopGuards(SrcEnd_, *LoopGuards);
auto SinkStart = SE.applyLoopGuards(SinkStart_, *LoopGuards);
auto SrcEnd = SE.applyLoopGuards(SrcEnd_, InnermostLoop);
auto SinkStart = SE.applyLoopGuards(SinkStart_, InnermostLoop);
if (SE.isKnownPredicate(CmpInst::ICMP_ULE, SrcEnd, SinkStart))
return MemoryDepChecker::Dependence::NoDep;

auto SinkEnd = SE.applyLoopGuards(SinkEnd_, *LoopGuards);
auto SrcStart = SE.applyLoopGuards(SrcStart_, *LoopGuards);
auto SinkEnd = SE.applyLoopGuards(SinkEnd_, InnermostLoop);
auto SrcStart = SE.applyLoopGuards(SrcStart_, InnermostLoop);
if (SE.isKnownPredicate(CmpInst::ICMP_ULE, SinkEnd, SrcStart))
return MemoryDepChecker::Dependence::NoDep;
}
Expand Down Expand Up @@ -2057,10 +2054,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return Dependence::NoDep;
}
} else {
if (!LoopGuards)
LoopGuards.emplace(
ScalarEvolution::LoopGuards::collect(InnermostLoop, SE));
Dist = SE.applyLoopGuards(Dist, *LoopGuards);
Dist = SE.applyLoopGuards(Dist, InnermostLoop);
}

// Negative distances are not plausible dependencies.
Expand Down
24 changes: 13 additions & 11 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8417,6 +8417,7 @@ void ScalarEvolution::forgetAllLoops() {
// result.
BackedgeTakenCounts.clear();
PredicatedBackedgeTakenCounts.clear();
LoopGuardsCache.clear();
BECountUsers.clear();
LoopPropertiesCache.clear();
ConstantEvolutionLoopExitValue.clear();
Expand Down Expand Up @@ -10551,9 +10552,8 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
if (!isLoopInvariant(Step, L))
return getCouldNotCompute();

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

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

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

const SCEV *M = E;
if (E != getCouldNotCompute()) {
APInt MaxWithGuards = getUnsignedRangeMax(applyLoopGuards(E, Guards));
APInt MaxWithGuards = getUnsignedRangeMax(applyLoopGuards(E, L));
M = getConstant(APIntOps::umin(MaxWithGuards, getUnsignedRangeMax(E)));
}
auto *S = isa<SCEVCouldNotCompute>(E) ? M : E;
Expand Down Expand Up @@ -13674,6 +13674,7 @@ ScalarEvolution::~ScalarEvolution() {
HasRecMap.clear();
BackedgeTakenCounts.clear();
PredicatedBackedgeTakenCounts.clear();
LoopGuardsCache.clear();

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

const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
return applyLoopGuards(Expr, LoopGuards::collect(L, *this));
}

const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr,
const LoopGuards &Guards) {
return Guards.rewrite(Expr);
auto Itr = LoopGuardsCache.find(L);
if (Itr == LoopGuardsCache.end()) {
LoopGuards Guard = LoopGuards::collect(L, *this);
LoopGuardsCache.insert({L, Guard});
return Guard.rewrite(Expr);
}
return Itr->second.rewrite(Expr);
}
Loading