forked from OSchip/llvm-project
[SCEV][NFC] Cache symbolic max exit count
We want to have a caching version of symbolic BE exit count rather than recompute it every time we need it. Differential Revision: https://reviews.llvm.org/D89954 Reviewed By: nikic, efriedma
This commit is contained in:
parent
3590a8319a
commit
6e574abf61
|
@ -744,6 +744,8 @@ public:
|
|||
Exact,
|
||||
/// A constant which provides an upper bound on the exact trip count.
|
||||
ConstantMaximum,
|
||||
/// An expression which provides an upper bound on the exact trip count.
|
||||
SymbolicMaximum,
|
||||
};
|
||||
|
||||
/// Return the number of times the backedge executes before the given exit
|
||||
|
@ -780,12 +782,15 @@ public:
|
|||
/// SCEVCouldNotCompute object.
|
||||
const SCEV *getConstantMaxBackedgeTakenCount(const Loop *L) {
|
||||
return getBackedgeTakenCount(L, ConstantMaximum);
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a symbolic upper bound for the backedge taken count of the loop.
|
||||
/// This is more general than getConstantMaxBackedgeTakenCount as it returns
|
||||
/// an arbitrary expression as opposed to only constants.
|
||||
const SCEV* computeMaxBackedgeTakenCount(const Loop *L);
|
||||
/// When successful, this returns a SCEV that is greater than or equal
|
||||
/// to (i.e. a "conservative over-approximation") of the value returend by
|
||||
/// getBackedgeTakenCount. If such a value cannot be computed, it returns the
|
||||
/// SCEVCouldNotCompute object.
|
||||
const SCEV *getSymbolicMaxBackedgeTakenCount(const Loop *L) {
|
||||
return getBackedgeTakenCount(L, SymbolicMaximum);
|
||||
}
|
||||
|
||||
/// Return true if the backedge taken count is either the value returned by
|
||||
/// getConstantMaxBackedgeTakenCount or zero.
|
||||
|
@ -1317,23 +1322,24 @@ private:
|
|||
/// never have more than one computable exit.
|
||||
SmallVector<ExitNotTakenInfo, 1> ExitNotTaken;
|
||||
|
||||
/// Expression indicating the least maximum backedge-taken count of the loop
|
||||
/// that is known, or a SCEVCouldNotCompute. This expression is only valid
|
||||
/// if the redicates associated with all loop exits are true.
|
||||
/// Expression indicating the least constant maximum backedge-taken count of
|
||||
/// the loop that is known, or a SCEVCouldNotCompute. This expression is
|
||||
/// only valid if the redicates associated with all loop exits are true.
|
||||
const SCEV *ConstantMax;
|
||||
|
||||
/// Indicating if \c ExitNotTaken has an element for every exiting block in
|
||||
/// the loop.
|
||||
bool IsComplete;
|
||||
|
||||
/// Expression indicating the least maximum backedge-taken count of the loop
|
||||
/// that is known, or a SCEVCouldNotCompute. Lazily computed on first query.
|
||||
const SCEV *SymbolicMax = nullptr;
|
||||
|
||||
/// True iff the backedge is taken either exactly Max or zero times.
|
||||
bool MaxOrZero = false;
|
||||
|
||||
/// \name Helper projection functions on \c ConstantMaxAndComplete.
|
||||
/// @{
|
||||
bool isComplete() const { return IsComplete; }
|
||||
const SCEV *getConstantMax() const { return ConstantMax; }
|
||||
/// @}
|
||||
|
||||
public:
|
||||
BackedgeTakenInfo() : ConstantMax(nullptr), IsComplete(false) {}
|
||||
|
@ -1391,6 +1397,9 @@ private:
|
|||
const SCEV *getConstantMax(const BasicBlock *ExitingBlock,
|
||||
ScalarEvolution *SE) const;
|
||||
|
||||
/// Get the symbolic max backedge taken count for the loop.
|
||||
const SCEV *getSymbolicMax(const Loop *L, ScalarEvolution *SE);
|
||||
|
||||
/// Return true if the number of times this backedge is taken is either the
|
||||
/// value returned by getConstantMax or zero.
|
||||
bool isConstantMaxOrZero(ScalarEvolution *SE) const;
|
||||
|
@ -1543,7 +1552,7 @@ private:
|
|||
/// Return the BackedgeTakenInfo for the given loop, lazily computing new
|
||||
/// values if the loop hasn't been analyzed yet. The returned result is
|
||||
/// guaranteed not to be predicated.
|
||||
const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
|
||||
BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
|
||||
|
||||
/// Similar to getBackedgeTakenInfo, but will add predicates as required
|
||||
/// with the purpose of returning complete information.
|
||||
|
@ -1576,6 +1585,11 @@ private:
|
|||
bool ExitIfTrue, bool ControlsExit,
|
||||
bool AllowPredicates = false);
|
||||
|
||||
/// Return a symbolic upper bound for the backedge taken count of the loop.
|
||||
/// This is more general than getConstantMaxBackedgeTakenCount as it returns
|
||||
/// an arbitrary expression as opposed to only constants.
|
||||
const SCEV *computeSymbolicMaxBackedgeTakenCount(const Loop *L);
|
||||
|
||||
// Helper functions for computeExitLimitFromCond to avoid exponential time
|
||||
// complexity.
|
||||
|
||||
|
|
|
@ -6508,6 +6508,7 @@ const SCEV *ScalarEvolution::getExitCount(const Loop *L,
|
|||
ExitCountKind Kind) {
|
||||
switch (Kind) {
|
||||
case Exact:
|
||||
case SymbolicMaximum:
|
||||
return getBackedgeTakenInfo(L).getExact(ExitingBlock, this);
|
||||
case ConstantMaximum:
|
||||
return getBackedgeTakenInfo(L).getConstantMax(ExitingBlock, this);
|
||||
|
@ -6528,6 +6529,8 @@ const SCEV *ScalarEvolution::getBackedgeTakenCount(const Loop *L,
|
|||
return getBackedgeTakenInfo(L).getExact(L, this);
|
||||
case ConstantMaximum:
|
||||
return getBackedgeTakenInfo(L).getConstantMax(this);
|
||||
case SymbolicMaximum:
|
||||
return getBackedgeTakenInfo(L).getSymbolicMax(L, this);
|
||||
};
|
||||
llvm_unreachable("Invalid ExitCountKind!");
|
||||
}
|
||||
|
@ -6563,7 +6566,7 @@ ScalarEvolution::getPredicatedBackedgeTakenInfo(const Loop *L) {
|
|||
return PredicatedBackedgeTakenCounts.find(L)->second = std::move(Result);
|
||||
}
|
||||
|
||||
const ScalarEvolution::BackedgeTakenInfo &
|
||||
ScalarEvolution::BackedgeTakenInfo &
|
||||
ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
|
||||
// Initially insert an invalid entry for this loop. If the insertion
|
||||
// succeeds, proceed to actually compute a backedge-taken count and
|
||||
|
@ -6850,7 +6853,7 @@ const SCEV *ScalarEvolution::BackedgeTakenInfo::getConstantMax(
|
|||
return SE->getCouldNotCompute();
|
||||
}
|
||||
|
||||
/// getMax - Get the max backedge taken count for the loop.
|
||||
/// getConstantMax - Get the constant max backedge taken count for the loop.
|
||||
const SCEV *
|
||||
ScalarEvolution::BackedgeTakenInfo::getConstantMax(ScalarEvolution *SE) const {
|
||||
auto PredicateNotAlwaysTrue = [](const ExitNotTakenInfo &ENT) {
|
||||
|
@ -6866,6 +6869,14 @@ ScalarEvolution::BackedgeTakenInfo::getConstantMax(ScalarEvolution *SE) const {
|
|||
return getConstantMax();
|
||||
}
|
||||
|
||||
const SCEV *
|
||||
ScalarEvolution::BackedgeTakenInfo::getSymbolicMax(const Loop *L,
|
||||
ScalarEvolution *SE) {
|
||||
if (!SymbolicMax)
|
||||
SymbolicMax = SE->computeSymbolicMaxBackedgeTakenCount(L);
|
||||
return SymbolicMax;
|
||||
}
|
||||
|
||||
bool ScalarEvolution::BackedgeTakenInfo::isConstantMaxOrZero(
|
||||
ScalarEvolution *SE) const {
|
||||
auto PredicateNotAlwaysTrue = [](const ExitNotTakenInfo &ENT) {
|
||||
|
@ -12714,7 +12725,8 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS,
|
|||
return false;
|
||||
}
|
||||
|
||||
const SCEV* ScalarEvolution::computeMaxBackedgeTakenCount(const Loop *L) {
|
||||
const SCEV *
|
||||
ScalarEvolution::computeSymbolicMaxBackedgeTakenCount(const Loop *L) {
|
||||
SmallVector<BasicBlock*, 16> ExitingBlocks;
|
||||
L->getExitingBlocks(ExitingBlocks);
|
||||
|
||||
|
|
|
@ -2372,7 +2372,7 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
|
|||
return false;
|
||||
|
||||
// Get a symbolic upper bound on the loop backedge taken count.
|
||||
const SCEV *MaxExitCount = SE->computeMaxBackedgeTakenCount(L);
|
||||
const SCEV *MaxExitCount = SE->getSymbolicMaxBackedgeTakenCount(L);
|
||||
if (isa<SCEVCouldNotCompute>(MaxExitCount))
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue