Skip to content

Commit

Permalink
Extract a helper function for computing estimate trip count of an exi…
Browse files Browse the repository at this point in the history
…ting branch

Plan to use this in following change to support estimated trip counts derived from multiple loop exits.
  • Loading branch information
preames committed Dec 17, 2021
1 parent 4625b84 commit f632c49
Showing 1 changed file with 36 additions and 24 deletions.
60 changes: 36 additions & 24 deletions llvm/lib/Transforms/Utils/LoopUtils.cpp
Expand Up @@ -792,39 +792,51 @@ static BranchInst *getExpectedExitLoopLatchBranch(Loop *L) {
return LatchBR;
}

Optional<unsigned>
llvm::getLoopEstimatedTripCount(Loop *L,
unsigned *EstimatedLoopInvocationWeight) {
// Currently we take the estimate exit count only from the loop latch,
// ignoring other exiting blocks. This can overestimate the trip count
// if we exit through another exit, but can never underestimate it.
// TODO: incorporate information from other exits
BranchInst *LatchBranch = getExpectedExitLoopLatchBranch(L);
if (!LatchBranch)
return None;

/// Return the estimated trip count for any exiting branch which dominates
/// the loop latch.
static Optional<uint64_t>
getEstimatedTripCount(BranchInst *ExitingBranch, Loop *L,
uint64_t &OrigExitWeight) {
// To estimate the number of times the loop body was executed, we want to
// know the number of times the backedge was taken, vs. the number of times
// we exited the loop.
uint64_t BackedgeTakenWeight, LatchExitWeight;
if (!LatchBranch->extractProfMetadata(BackedgeTakenWeight, LatchExitWeight))
uint64_t LoopWeight, ExitWeight;
if (!ExitingBranch->extractProfMetadata(LoopWeight, ExitWeight))
return None;

if (LatchBranch->getSuccessor(0) != L->getHeader())
std::swap(BackedgeTakenWeight, LatchExitWeight);
if (L->contains(ExitingBranch->getSuccessor(1)))
std::swap(LoopWeight, ExitWeight);

if (!LatchExitWeight)
if (!ExitWeight)
// Don't have a way to return predicated infinite
return None;

if (EstimatedLoopInvocationWeight)
*EstimatedLoopInvocationWeight = LatchExitWeight;
OrigExitWeight = ExitWeight;

// Estimated backedge taken count is a ratio of the backedge taken weight by
// the weight of the edge exiting the loop, rounded to nearest.
uint64_t BackedgeTakenCount =
llvm::divideNearest(BackedgeTakenWeight, LatchExitWeight);
// Estimated trip count is one plus estimated backedge taken count.
return BackedgeTakenCount + 1;
// Estimated exit count is a ratio of the loop weight by the weight of the
// edge exiting the loop, rounded to nearest.
uint64_t ExitCount = llvm::divideNearest(LoopWeight, ExitWeight);
// Estimated trip count is one plus estimated exit count.
return ExitCount + 1;
}

Optional<unsigned>
llvm::getLoopEstimatedTripCount(Loop *L,
unsigned *EstimatedLoopInvocationWeight) {
// Currently we take the estimate exit count only from the loop latch,
// ignoring other exiting blocks. This can overestimate the trip count
// if we exit through another exit, but can never underestimate it.
// TODO: incorporate information from other exits
if (BranchInst *LatchBranch = getExpectedExitLoopLatchBranch(L)) {
uint64_t ExitWeight;
if (Optional<uint64_t> EstTripCount =
getEstimatedTripCount(LatchBranch, L, ExitWeight)) {
if (EstimatedLoopInvocationWeight)
*EstimatedLoopInvocationWeight = ExitWeight;
return *EstTripCount;
}
}
return None;
}

bool llvm::setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount,
Expand Down

0 comments on commit f632c49

Please sign in to comment.