[SCEV] Clarify behavior around max backedge taken count
This is a re-application of a r303497 that was reverted in r303498. I thought it had broken a bot when it had not (the breakage did not go away with the revert). This change makes the split between the "exact" backedge taken count and the "maximum" backedge taken count a bit more obvious. Both of these are upper bounds on the number of times the loop header executes (since SCEV does not account for most kinds of abnormal control flow), but the latter is guaranteed to be a constant. There were a few places where the max backedge taken count *was* a non-constant; I've changed those to compute constants instead. At this point, I'm not sure if the constant max backedge count can be computed by calling `getUnsignedRange(Exact).getUnsignedMax()` without losing precision. If it can, we can simplify even further by making `getMaxBackedgeTakenCount` a thin wrapper around `getBackedgeTakenCount` and `getUnsignedRange`. llvm-svn: 303531
This commit is contained in:
@@ -5947,6 +5947,8 @@ ScalarEvolution::BackedgeTakenInfo::getMax(ScalarEvolution *SE) const {
|
||||
if (any_of(ExitNotTaken, PredicateNotAlwaysTrue) || !getMax())
|
||||
return SE->getCouldNotCompute();
|
||||
|
||||
assert((isa<SCEVCouldNotCompute>(getMax()) || isa<SCEVConstant>(getMax())) &&
|
||||
"No point in having a non-constant max backedge taken count!");
|
||||
return getMax();
|
||||
}
|
||||
|
||||
@@ -5972,7 +5974,11 @@ bool ScalarEvolution::BackedgeTakenInfo::hasOperand(const SCEV *S,
|
||||
}
|
||||
|
||||
ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E)
|
||||
: ExactNotTaken(E), MaxNotTaken(E), MaxOrZero(false) {}
|
||||
: ExactNotTaken(E), MaxNotTaken(E), MaxOrZero(false) {
|
||||
assert((isa<SCEVCouldNotCompute>(MaxNotTaken) ||
|
||||
isa<SCEVConstant>(MaxNotTaken)) &&
|
||||
"No point in having a non-constant max backedge taken count!");
|
||||
}
|
||||
|
||||
ScalarEvolution::ExitLimit::ExitLimit(
|
||||
const SCEV *E, const SCEV *M, bool MaxOrZero,
|
||||
@@ -5981,6 +5987,9 @@ ScalarEvolution::ExitLimit::ExitLimit(
|
||||
assert((isa<SCEVCouldNotCompute>(ExactNotTaken) ||
|
||||
!isa<SCEVCouldNotCompute>(MaxNotTaken)) &&
|
||||
"Exact is not allowed to be less precise than Max");
|
||||
assert((isa<SCEVCouldNotCompute>(MaxNotTaken) ||
|
||||
isa<SCEVConstant>(MaxNotTaken)) &&
|
||||
"No point in having a non-constant max backedge taken count!");
|
||||
for (auto *PredSet : PredSetList)
|
||||
for (auto *P : *PredSet)
|
||||
addPredicate(P);
|
||||
@@ -5989,11 +5998,19 @@ ScalarEvolution::ExitLimit::ExitLimit(
|
||||
ScalarEvolution::ExitLimit::ExitLimit(
|
||||
const SCEV *E, const SCEV *M, bool MaxOrZero,
|
||||
const SmallPtrSetImpl<const SCEVPredicate *> &PredSet)
|
||||
: ExitLimit(E, M, MaxOrZero, {&PredSet}) {}
|
||||
: ExitLimit(E, M, MaxOrZero, {&PredSet}) {
|
||||
assert((isa<SCEVCouldNotCompute>(MaxNotTaken) ||
|
||||
isa<SCEVConstant>(MaxNotTaken)) &&
|
||||
"No point in having a non-constant max backedge taken count!");
|
||||
}
|
||||
|
||||
ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E, const SCEV *M,
|
||||
bool MaxOrZero)
|
||||
: ExitLimit(E, M, MaxOrZero, None) {}
|
||||
: ExitLimit(E, M, MaxOrZero, None) {
|
||||
assert((isa<SCEVCouldNotCompute>(MaxNotTaken) ||
|
||||
isa<SCEVConstant>(MaxNotTaken)) &&
|
||||
"No point in having a non-constant max backedge taken count!");
|
||||
}
|
||||
|
||||
/// Allocate memory for BackedgeTakenInfo and copy the not-taken count of each
|
||||
/// computable exit into a persistent ExitNotTakenInfo array.
|
||||
@@ -6018,6 +6035,8 @@ ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
|
||||
|
||||
return ExitNotTakenInfo(ExitBB, EL.ExactNotTaken, std::move(Predicate));
|
||||
});
|
||||
assert((isa<SCEVCouldNotCompute>(MaxCount) || isa<SCEVConstant>(MaxCount)) &&
|
||||
"No point in having a non-constant max backedge taken count!");
|
||||
}
|
||||
|
||||
/// Invalidate this result and free the ExitNotTakenInfo array.
|
||||
@@ -6279,7 +6298,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondImpl(
|
||||
// to not.
|
||||
if (isa<SCEVCouldNotCompute>(MaxBECount) &&
|
||||
!isa<SCEVCouldNotCompute>(BECount))
|
||||
MaxBECount = BECount;
|
||||
MaxBECount = getConstant(getUnsignedRange(BECount).getUnsignedMax());
|
||||
|
||||
return ExitLimit(BECount, MaxBECount, false,
|
||||
{&EL0.Predicates, &EL1.Predicates});
|
||||
@@ -7583,13 +7602,20 @@ ScalarEvolution::howFarToZero(const SCEV *V, const Loop *L, bool ControlsExit,
|
||||
loopHasNoAbnormalExits(AddRec->getLoop())) {
|
||||
const SCEV *Exact =
|
||||
getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
|
||||
return ExitLimit(Exact, Exact, false, Predicates);
|
||||
const SCEV *Max =
|
||||
Exact == getCouldNotCompute()
|
||||
? Exact
|
||||
: getConstant(getUnsignedRange(Exact).getUnsignedMax());
|
||||
return ExitLimit(Exact, Max, false, Predicates);
|
||||
}
|
||||
|
||||
// Solve the general equation.
|
||||
const SCEV *E = SolveLinEquationWithOverflow(
|
||||
StepC->getAPInt(), getNegativeSCEV(Start), *this);
|
||||
return ExitLimit(E, E, false, Predicates);
|
||||
const SCEV *E = SolveLinEquationWithOverflow(StepC->getAPInt(),
|
||||
getNegativeSCEV(Start), *this);
|
||||
const SCEV *M = E == getCouldNotCompute()
|
||||
? E
|
||||
: getConstant(getUnsignedRange(E).getUnsignedMax());
|
||||
return ExitLimit(E, M, false, Predicates);
|
||||
}
|
||||
|
||||
ScalarEvolution::ExitLimit
|
||||
@@ -9218,8 +9244,9 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
||||
getConstant(StrideForMaxBECount), false);
|
||||
}
|
||||
|
||||
if (isa<SCEVCouldNotCompute>(MaxBECount))
|
||||
MaxBECount = BECount;
|
||||
if (isa<SCEVCouldNotCompute>(MaxBECount) &&
|
||||
!isa<SCEVCouldNotCompute>(BECount))
|
||||
MaxBECount = getConstant(getUnsignedRange(BECount).getUnsignedMax());
|
||||
|
||||
return ExitLimit(BECount, MaxBECount, MaxOrZero, Predicates);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user