1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[SCEV] Generalize getSmallConstantTripCount(L) for multiple exit loops

This came up in review for another patch, see https://reviews.llvm.org/D102982#2782407 for full context.

I've reviewed the callers to make sure they can handle multiple exit loops w/non-zero returns.  There's two cases in target cost models where results might change (Hexagon and PowerPC), but the results looked legal and reasonable.  If a target maintainer wishes to back out the effect of the costing change, they should explicitly check for multiple exit loops and handle them as desired.

Differential Revision: https://reviews.llvm.org/D103182
This commit is contained in:
Philip Reames 2021-05-26 11:16:11 -07:00
parent c2d4999f01
commit 948729e467
2 changed files with 12 additions and 14 deletions

View File

@ -712,17 +712,18 @@ public:
/// must be interpreted as a loop having an unknown trip count.
const SCEV *getTripCountFromExitCount(const SCEV *ExitCount);
/// Returns the maximum trip count of the loop if it is a single-exit
/// loop and we can compute a small maximum for that loop.
///
/// Implemented in terms of the \c getSmallConstantTripCount overload with
/// the single exiting block passed to it. See that routine for details.
/// Returns the exact trip count of the loop if we can compute it, and
/// the result is a small constant. '0' is used to represent an unknown
/// or non-constant trip count. Note that a trip count is simply one more
/// than the backedge taken count for the loop.
unsigned getSmallConstantTripCount(const Loop *L);
/// Returns the maximum trip count of this loop as a normal unsigned
/// value. Returns 0 if the trip count is unknown or not constant. This
/// "trip count" assumes that control exits via ExitingBlock. More
/// precisely, it is the number of times that control may reach ExitingBlock
/// Return the exact trip count for this loop if we exit through ExitingBlock.
/// '0' is used to represent an unknown or non-constant trip count. Note
/// that a trip count is simply one more than the backedge taken count for
/// the same exit.
/// This "trip count" assumes that control exits via ExitingBlock. More
/// precisely, it is the number of times that control will reach ExitingBlock
/// before taking the branch. For loops with multiple exits, it may not be
/// the number times that the loop header executes if the loop exits
/// prematurely via another branch.

View File

@ -6948,11 +6948,8 @@ static unsigned getConstantTripCount(const SCEVConstant *ExitCount) {
}
unsigned ScalarEvolution::getSmallConstantTripCount(const Loop *L) {
if (BasicBlock *ExitingBB = L->getExitingBlock())
return getSmallConstantTripCount(L, ExitingBB);
// No trip count information for multiple exits.
return 0;
auto *ExitCount = dyn_cast<SCEVConstant>(getBackedgeTakenCount(L, Exact));
return getConstantTripCount(ExitCount);
}
unsigned