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

View File

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