forked from OSchip/llvm-project
[SCEV] Introduce field for storing SymbolicMaxNotTaken. NFCI
ritht is initialized with either exact (if available) or with constant max exit count. In the future, this can be improved. Hypothetically this is not an NFC (it is possible that exact is not known and max is known for a particular exit), but for how we use it now it seems be an NFC (or at least I could not find an example where it differs). constant max exit count. In the future, this can be improved. Differential Revision: https://reviews.llvm.org/D138699 Reviewed By: lebedev.ri
This commit is contained in:
parent
baca3b382b
commit
0b74cb4231
|
@ -1314,6 +1314,7 @@ private:
|
||||||
const SCEV *ExactNotTaken; // The exit is not taken exactly this many times
|
const SCEV *ExactNotTaken; // The exit is not taken exactly this many times
|
||||||
const SCEV *ConstantMaxNotTaken; // The exit is not taken at most this many
|
const SCEV *ConstantMaxNotTaken; // The exit is not taken at most this many
|
||||||
// times
|
// times
|
||||||
|
const SCEV *SymbolicMaxNotTaken;
|
||||||
|
|
||||||
// Not taken either exactly ConstantMaxNotTaken or zero times
|
// Not taken either exactly ConstantMaxNotTaken or zero times
|
||||||
bool MaxOrZero = false;
|
bool MaxOrZero = false;
|
||||||
|
@ -1360,14 +1361,16 @@ private:
|
||||||
PoisoningVH<BasicBlock> ExitingBlock;
|
PoisoningVH<BasicBlock> ExitingBlock;
|
||||||
const SCEV *ExactNotTaken;
|
const SCEV *ExactNotTaken;
|
||||||
const SCEV *ConstantMaxNotTaken;
|
const SCEV *ConstantMaxNotTaken;
|
||||||
|
const SCEV *SymbolicMaxNotTaken;
|
||||||
SmallPtrSet<const SCEVPredicate *, 4> Predicates;
|
SmallPtrSet<const SCEVPredicate *, 4> Predicates;
|
||||||
|
|
||||||
explicit ExitNotTakenInfo(
|
explicit ExitNotTakenInfo(
|
||||||
PoisoningVH<BasicBlock> ExitingBlock, const SCEV *ExactNotTaken,
|
PoisoningVH<BasicBlock> ExitingBlock, const SCEV *ExactNotTaken,
|
||||||
const SCEV *ConstantMaxNotTaken,
|
const SCEV *ConstantMaxNotTaken, const SCEV *SymbolicMaxNotTaken,
|
||||||
const SmallPtrSet<const SCEVPredicate *, 4> &Predicates)
|
const SmallPtrSet<const SCEVPredicate *, 4> &Predicates)
|
||||||
: ExitingBlock(ExitingBlock), ExactNotTaken(ExactNotTaken),
|
: ExitingBlock(ExitingBlock), ExactNotTaken(ExactNotTaken),
|
||||||
ConstantMaxNotTaken(ConstantMaxNotTaken), Predicates(Predicates) {}
|
ConstantMaxNotTaken(ConstantMaxNotTaken),
|
||||||
|
SymbolicMaxNotTaken(SymbolicMaxNotTaken), Predicates(Predicates) {}
|
||||||
|
|
||||||
bool hasAlwaysTruePredicate() const {
|
bool hasAlwaysTruePredicate() const {
|
||||||
return Predicates.empty();
|
return Predicates.empty();
|
||||||
|
|
|
@ -8560,8 +8560,11 @@ const SCEV *ScalarEvolution::BackedgeTakenInfo::getConstantMax(
|
||||||
|
|
||||||
const SCEV *ScalarEvolution::BackedgeTakenInfo::getSymbolicMax(
|
const SCEV *ScalarEvolution::BackedgeTakenInfo::getSymbolicMax(
|
||||||
const BasicBlock *ExitingBlock, ScalarEvolution *SE) const {
|
const BasicBlock *ExitingBlock, ScalarEvolution *SE) const {
|
||||||
// FIXME: Need to implement this. Return exact for now.
|
for (const auto &ENT : ExitNotTaken)
|
||||||
return getExact(ExitingBlock, SE);
|
if (ENT.ExitingBlock == ExitingBlock && ENT.hasAlwaysTruePredicate())
|
||||||
|
return ENT.SymbolicMaxNotTaken;
|
||||||
|
|
||||||
|
return SE->getCouldNotCompute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getConstantMax - Get the constant max backedge taken count for the loop.
|
/// getConstantMax - Get the constant max backedge taken count for the loop.
|
||||||
|
@ -8611,6 +8614,13 @@ ScalarEvolution::ExitLimit::ExitLimit(
|
||||||
if (ConstantMaxNotTaken->isZero())
|
if (ConstantMaxNotTaken->isZero())
|
||||||
ExactNotTaken = ConstantMaxNotTaken;
|
ExactNotTaken = ConstantMaxNotTaken;
|
||||||
|
|
||||||
|
// FIXME: For now, SymbolicMaxNotTaken is either exact (if available) or
|
||||||
|
// constant max. In the future, we are planning to make it more powerful.
|
||||||
|
if (isa<SCEVCouldNotCompute>(ExactNotTaken))
|
||||||
|
SymbolicMaxNotTaken = ConstantMaxNotTaken;
|
||||||
|
else
|
||||||
|
SymbolicMaxNotTaken = ExactNotTaken;
|
||||||
|
|
||||||
assert((isa<SCEVCouldNotCompute>(ExactNotTaken) ||
|
assert((isa<SCEVCouldNotCompute>(ExactNotTaken) ||
|
||||||
!isa<SCEVCouldNotCompute>(ConstantMaxNotTaken)) &&
|
!isa<SCEVCouldNotCompute>(ConstantMaxNotTaken)) &&
|
||||||
"Exact is not allowed to be less precise than Max");
|
"Exact is not allowed to be less precise than Max");
|
||||||
|
@ -8647,7 +8657,8 @@ ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
|
||||||
BasicBlock *ExitBB = EEI.first;
|
BasicBlock *ExitBB = EEI.first;
|
||||||
const ExitLimit &EL = EEI.second;
|
const ExitLimit &EL = EEI.second;
|
||||||
return ExitNotTakenInfo(ExitBB, EL.ExactNotTaken,
|
return ExitNotTakenInfo(ExitBB, EL.ExactNotTaken,
|
||||||
EL.ConstantMaxNotTaken, EL.Predicates);
|
EL.ConstantMaxNotTaken, EL.SymbolicMaxNotTaken,
|
||||||
|
EL.Predicates);
|
||||||
});
|
});
|
||||||
assert((isa<SCEVCouldNotCompute>(ConstantMax) ||
|
assert((isa<SCEVCouldNotCompute>(ConstantMax) ||
|
||||||
isa<SCEVConstant>(ConstantMax)) &&
|
isa<SCEVConstant>(ConstantMax)) &&
|
||||||
|
@ -14752,9 +14763,6 @@ ScalarEvolution::computeSymbolicMaxBackedgeTakenCount(const Loop *L) {
|
||||||
for (BasicBlock *ExitingBB : ExitingBlocks) {
|
for (BasicBlock *ExitingBB : ExitingBlocks) {
|
||||||
const SCEV *ExitCount =
|
const SCEV *ExitCount =
|
||||||
getExitCount(L, ExitingBB, ScalarEvolution::SymbolicMaximum);
|
getExitCount(L, ExitingBB, ScalarEvolution::SymbolicMaximum);
|
||||||
if (isa<SCEVCouldNotCompute>(ExitCount))
|
|
||||||
ExitCount = getExitCount(L, ExitingBB,
|
|
||||||
ScalarEvolution::ConstantMaximum);
|
|
||||||
if (!isa<SCEVCouldNotCompute>(ExitCount)) {
|
if (!isa<SCEVCouldNotCompute>(ExitCount)) {
|
||||||
assert(DT.dominates(ExitingBB, L->getLoopLatch()) &&
|
assert(DT.dominates(ExitingBB, L->getLoopLatch()) &&
|
||||||
"We should only have known counts for exiting blocks that "
|
"We should only have known counts for exiting blocks that "
|
||||||
|
|
Loading…
Reference in New Issue