[llvm] change contents of ScalarEvolution from private to protected (PR #83052)
William Moses via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 13 13:25:13 PDT 2024
================
@@ -8923,10 +8949,104 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondCached(
ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimitFromCondImpl(
ExitLimitCacheTy &Cache, const Loop *L, Value *ExitCond, bool ExitIfTrue,
bool ControlsOnlyExit, bool AllowPredicates) {
- // Handle BinOp conditions (And, Or).
- if (auto LimitFromBinOp = computeExitLimitFromCondFromBinOp(
- Cache, L, ExitCond, ExitIfTrue, ControlsOnlyExit, AllowPredicates))
- return *LimitFromBinOp;
+ if (!AssumeLoopExits) {
+ // Handle BinOp conditions (And, Or).
+ if (auto LimitFromBinOp = computeExitLimitFromCondFromBinOp(
+ Cache, L, ExitCond, ExitIfTrue, ControlsOnlyExit, AllowPredicates))
+ return *LimitFromBinOp;
+ } else {
+ // Check if the controlling expression for this loop is an And or Or.
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(ExitCond)) {
+ if (BO->getOpcode() == Instruction::And) {
+ // Recurse on the operands of the and.
+ bool EitherMayExit = !ExitIfTrue;
+ ExitLimit EL0 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(0), ExitIfTrue,
+ ControlsOnlyExit && !EitherMayExit, AllowPredicates);
+ ExitLimit EL1 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(1), ExitIfTrue,
+ ControlsOnlyExit && !EitherMayExit, AllowPredicates);
+ const SCEV *BECount = getCouldNotCompute();
+ const SCEV *MaxBECount = getCouldNotCompute();
+ if (EitherMayExit) {
+ // Both conditions must be true for the loop to continue executing.
+ // Choose the less conservative count.
+ if (EL0.ExactNotTaken == getCouldNotCompute() ||
+ EL1.ExactNotTaken == getCouldNotCompute())
+ BECount = getCouldNotCompute();
+ else
+ BECount = getUMinFromMismatchedTypes(EL0.ExactNotTaken,
+ EL1.ExactNotTaken);
+
+ if (EL0.ConstantMaxNotTaken == getCouldNotCompute())
+ MaxBECount = EL1.ConstantMaxNotTaken;
+ else if (EL1.ConstantMaxNotTaken == getCouldNotCompute())
+ MaxBECount = EL0.ConstantMaxNotTaken;
+ else
+ MaxBECount = getUMinFromMismatchedTypes(EL0.ConstantMaxNotTaken,
+ EL1.ConstantMaxNotTaken);
+ } else {
+ // Both conditions must be true at the same time for the loop to exit.
+ // For now, be conservative.
+ if (EL0.ConstantMaxNotTaken == EL1.ConstantMaxNotTaken)
+ MaxBECount = EL0.ConstantMaxNotTaken;
+ if (EL0.ExactNotTaken == EL1.ExactNotTaken)
+ BECount = EL0.ExactNotTaken;
+ }
+
+ // There are cases (e.g. PR26207) where computeExitLimitFromCond is able
+ // to be more aggressive when computing BECount than when computing
+ // MaxBECount. In these cases it is possible for EL0.ExactNotTaken and
+ // EL1.ExactNotTaken to match, but for EL0.ConstantMaxNotTaken and
+ // EL1.ConstantMaxNotTaken to not.
+ if (isa<SCEVCouldNotCompute>(MaxBECount) &&
+ !isa<SCEVCouldNotCompute>(BECount))
+ MaxBECount = getConstant(getUnsignedRangeMax(BECount));
+
+ return ExitLimit(BECount, MaxBECount, MaxBECount, false,
+ {&EL0.Predicates, &EL1.Predicates});
+ }
+ if (BO->getOpcode() == Instruction::Or) {
+ // Recurse on the operands of the or.
+ bool EitherMayExit = ExitIfTrue;
+ ExitLimit EL0 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(0), ExitIfTrue,
+ ControlsOnlyExit && !EitherMayExit, AllowPredicates);
+ ExitLimit EL1 = computeExitLimitFromCondCached(
+ Cache, L, BO->getOperand(1), ExitIfTrue,
+ ControlsOnlyExit && !EitherMayExit, AllowPredicates);
+ const SCEV *BECount = getCouldNotCompute();
+ const SCEV *MaxBECount = getCouldNotCompute();
+ if (EitherMayExit) {
+ // Both conditions must be false for the loop to continue executing.
+ // Choose the less conservative count.
+ if (EL0.ExactNotTaken == getCouldNotCompute() ||
+ EL1.ExactNotTaken == getCouldNotCompute())
+ BECount = getCouldNotCompute();
+ else
+ BECount = getUMinFromMismatchedTypes(EL0.ExactNotTaken,
+ EL1.ExactNotTaken);
+
+ if (EL0.ConstantMaxNotTaken == getCouldNotCompute())
+ MaxBECount = EL1.ConstantMaxNotTaken;
+ else if (EL1.ConstantMaxNotTaken == getCouldNotCompute())
+ MaxBECount = EL0.ConstantMaxNotTaken;
+ else
+ MaxBECount = getUMinFromMismatchedTypes(EL0.ConstantMaxNotTaken,
+ EL1.ConstantMaxNotTaken);
+ } else {
+ // Both conditions must be false at the same time for the loop to
+ // exit. For now, be conservative.
+ if (EL0.ConstantMaxNotTaken == EL1.ConstantMaxNotTaken)
+ MaxBECount = EL0.ConstantMaxNotTaken;
----------------
wsmoses wrote:
this may be fine to drop from the diff?
https://github.com/llvm/llvm-project/pull/83052
More information about the llvm-commits
mailing list