[llvm] [SCEV] Avoid unnecessary call to getExitingBlock() in computeExitLimit() (PR #96188)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 20 06:28:05 PDT 2024
https://github.com/Enna1 created https://github.com/llvm/llvm-project/pull/96188
In `computeExitLimit()`, we use `getExitingBlock()` to check if loop has exactly one exiting block.
Since `computeExitLimit()` is only used in `computeBackedgeTakenCount()`, and `getExitingBlocks()` is called to get all exiting blocks in `computeBackedgeTakenCount()`, we can simply check if loop has exactly one exiting block by checking if the number of exiting blocks equals 1 in `computeBackedgeTakenCount()` and pass it as an argument to `computeExitLimit()`.
This change helps to improve the compile time for files containing large loops.
>From ad57d93d8ccc8bc1a81f56ce182628f25546d7a7 Mon Sep 17 00:00:00 2001
From: "xumingjie.enna1" <xumingjie.enna1 at bytedance.com>
Date: Thu, 20 Jun 2024 20:48:20 +0800
Subject: [PATCH] [SCEV] Avoid unnecessary call to getExitingBlock() in
computeExitLimit()
In `computeExitLimit()`, we use `getExitingBlock()` to check if loop has exactly
one exiting block.
Since `computeExitLimit()` is only used in `computeBackedgeTakenCount()`,
and `getExitingBlocks()` is called to get all exiting blocks in
`computeBackedgeTakenCount()`, we can simply check if loop has exactly one
exiting block by checking if the number of exiting blocks equals 1 in
`computeBackedgeTakenCount()` and pass it as an argument to `computeExitLimit()`.
This change helps to improve the compile time for files containing large loops.
---
llvm/include/llvm/Analysis/ScalarEvolution.h | 1 +
llvm/lib/Analysis/ScalarEvolution.cpp | 13 +++++--------
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index b273d118c4c76..67260ac4d8a9c 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1766,6 +1766,7 @@ class ScalarEvolution {
/// this call will try to use a minimal set of SCEV predicates in order to
/// return an exact answer.
ExitLimit computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
+ bool ControlsOnlyExit,
bool AllowPredicates = false);
// Helper functions for computeExitLimitFromCond to avoid exponential time
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 7d3e3f4fcd45d..2d88e35e67823 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8775,6 +8775,7 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
const SCEV *MustExitMaxBECount = nullptr;
const SCEV *MayExitMaxBECount = nullptr;
bool MustExitMaxOrZero = false;
+ bool IsOnlyExit = ExitingBlocks.size() == 1;
// Compute the ExitLimit for each loop exit. Use this to populate ExitCounts
// and compute maxBECount.
@@ -8792,7 +8793,7 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
continue;
}
- ExitLimit EL = computeExitLimit(L, ExitBB, AllowPredicates);
+ ExitLimit EL = computeExitLimit(L, ExitBB, IsOnlyExit, AllowPredicates);
assert((AllowPredicates || EL.Predicates.empty()) &&
"Predicated exit limit when predicates are not allowed!");
@@ -8867,7 +8868,7 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
ScalarEvolution::ExitLimit
ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
- bool AllowPredicates) {
+ bool ControlsOnlyExit, bool AllowPredicates) {
assert(L->contains(ExitingBlock) && "Exit count for non-loop block?");
// If our exiting block does not dominate the latch, then its connection with
// loop's exit limit may be far from trivial.
@@ -8875,7 +8876,6 @@ ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
if (!Latch || !DT.dominates(ExitingBlock, Latch))
return getCouldNotCompute();
- bool IsOnlyExit = (L->getExitingBlock() != nullptr);
Instruction *Term = ExitingBlock->getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(Term)) {
assert(BI->isConditional() && "If unconditional, it can't be in loop!");
@@ -8884,8 +8884,7 @@ ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
"It should have one successor in loop and one exit block!");
// Proceed to the next level to examine the exit condition expression.
return computeExitLimitFromCond(L, BI->getCondition(), ExitIfTrue,
- /*ControlsOnlyExit=*/IsOnlyExit,
- AllowPredicates);
+ ControlsOnlyExit, AllowPredicates);
}
if (SwitchInst *SI = dyn_cast<SwitchInst>(Term)) {
@@ -8898,9 +8897,7 @@ ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
Exit = SBB;
}
assert(Exit && "Exiting block must have at least one exit");
- return computeExitLimitFromSingleExitSwitch(
- L, SI, Exit,
- /*ControlsOnlyExit=*/IsOnlyExit);
+ return computeExitLimitFromSingleExitSwitch(L, SI, Exit, ControlsOnlyExit);
}
return getCouldNotCompute();
More information about the llvm-commits
mailing list