[LoopUnroll] Add RuntimeUnrollMultiExit to loop unroll options (NFC) (#124462)
Add an extra knob to RuntimeUnrollMultiExit to let backends control
whether to allow multi-exit unrolling on a per-loop basis.
This gives backends more fine-grained control on deciding if multi-exit
unrolling is profitable for a given loop and uarch. Similar to
4226e0a0c7.
PR: https://github.com/llvm/llvm-project/pull/124462
This commit is contained in:
@@ -622,6 +622,11 @@ public:
|
||||
/// Don't allow runtime unrolling if expanding the trip count takes more
|
||||
/// than SCEVExpansionBudget.
|
||||
unsigned SCEVExpansionBudget;
|
||||
/// Allow runtime unrolling multi-exit loops. Should only be set if the
|
||||
/// target determined that multi-exit unrolling is profitable for the loop.
|
||||
/// Fall back to the generic logic to determine whether multi-exit unrolling
|
||||
/// is profitable if set to false.
|
||||
bool RuntimeUnrollMultiExit;
|
||||
};
|
||||
|
||||
/// Get target-customized preferences for the generic loop unrolling
|
||||
|
||||
@@ -76,6 +76,7 @@ struct UnrollLoopOptions {
|
||||
bool ForgetAllSCEV;
|
||||
const Instruction *Heart = nullptr;
|
||||
unsigned SCEVExpansionBudget;
|
||||
bool RuntimeUnrollMultiExit = false;
|
||||
};
|
||||
|
||||
LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
|
||||
@@ -91,7 +92,8 @@ bool UnrollRuntimeLoopRemainder(
|
||||
bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
|
||||
LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI, bool PreserveLCSSA,
|
||||
unsigned SCEVExpansionBudget, Loop **ResultLoop = nullptr);
|
||||
unsigned SCEVExpansionBudget, bool RuntimeUnrollMultiExit,
|
||||
Loop **ResultLoop = nullptr);
|
||||
|
||||
LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
|
||||
unsigned TripMultiple, bool UnrollRemainder,
|
||||
|
||||
@@ -220,6 +220,7 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
|
||||
UP.UnrollAndJamInnerLoopThreshold = 60;
|
||||
UP.MaxIterationsCountToAnalyze = UnrollMaxIterationsCountToAnalyze;
|
||||
UP.SCEVExpansionBudget = SCEVCheapExpansionBudget;
|
||||
UP.RuntimeUnrollMultiExit = false;
|
||||
|
||||
// Override with any target specific settings
|
||||
TTI.getUnrollingPreferences(L, SE, UP, &ORE);
|
||||
@@ -1352,6 +1353,7 @@ tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE,
|
||||
ULO.ForgetAllSCEV = ForgetAllSCEV;
|
||||
ULO.Heart = getLoopConvergenceHeart(L);
|
||||
ULO.SCEVExpansionBudget = UP.SCEVExpansionBudget;
|
||||
ULO.RuntimeUnrollMultiExit = UP.RuntimeUnrollMultiExit;
|
||||
LoopUnrollResult UnrollResult = UnrollLoop(
|
||||
L, ULO, LI, &SE, &DT, &AC, &TTI, &ORE, PreserveLCSSA, &RemainderLoop, AA);
|
||||
if (UnrollResult == LoopUnrollResult::Unmodified)
|
||||
|
||||
@@ -590,10 +590,11 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
|
||||
: isEpilogProfitable(L);
|
||||
|
||||
if (ULO.Runtime &&
|
||||
!UnrollRuntimeLoopRemainder(
|
||||
L, ULO.Count, ULO.AllowExpensiveTripCount, EpilogProfitability,
|
||||
ULO.UnrollRemainder, ULO.ForgetAllSCEV, LI, SE, DT, AC, TTI,
|
||||
PreserveLCSSA, ULO.SCEVExpansionBudget, RemainderLoop)) {
|
||||
!UnrollRuntimeLoopRemainder(L, ULO.Count, ULO.AllowExpensiveTripCount,
|
||||
EpilogProfitability, ULO.UnrollRemainder,
|
||||
ULO.ForgetAllSCEV, LI, SE, DT, AC, TTI,
|
||||
PreserveLCSSA, ULO.SCEVExpansionBudget,
|
||||
ULO.RuntimeUnrollMultiExit, RemainderLoop)) {
|
||||
if (ULO.Force)
|
||||
ULO.Runtime = false;
|
||||
else {
|
||||
|
||||
@@ -461,7 +461,7 @@ CloneLoopBlocks(Loop *L, Value *NewIter, const bool UseEpilogRemainder,
|
||||
|
||||
/// Returns true if we can profitably unroll the multi-exit loop L. Currently,
|
||||
/// we return true only if UnrollRuntimeMultiExit is set to true.
|
||||
static bool canProfitablyUnrollMultiExitLoop(
|
||||
static bool canProfitablyRuntimeUnrollMultiExitLoop(
|
||||
Loop *L, SmallVectorImpl<BasicBlock *> &OtherExits, BasicBlock *LatchExit,
|
||||
bool UseEpilogRemainder) {
|
||||
|
||||
@@ -583,7 +583,8 @@ bool llvm::UnrollRuntimeLoopRemainder(
|
||||
bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
|
||||
LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI, bool PreserveLCSSA,
|
||||
unsigned SCEVExpansionBudget, Loop **ResultLoop) {
|
||||
unsigned SCEVExpansionBudget, bool RuntimeUnrollMultiExit,
|
||||
Loop **ResultLoop) {
|
||||
LLVM_DEBUG(dbgs() << "Trying runtime unrolling on Loop: \n");
|
||||
LLVM_DEBUG(L->dump());
|
||||
LLVM_DEBUG(UseEpilogRemainder ? dbgs() << "Using epilog remainder.\n"
|
||||
@@ -632,8 +633,9 @@ bool llvm::UnrollRuntimeLoopRemainder(
|
||||
if (!PreserveLCSSA)
|
||||
return false;
|
||||
|
||||
if (!canProfitablyUnrollMultiExitLoop(L, OtherExits, LatchExit,
|
||||
UseEpilogRemainder)) {
|
||||
if (!RuntimeUnrollMultiExit &&
|
||||
!canProfitablyRuntimeUnrollMultiExitLoop(L, OtherExits, LatchExit,
|
||||
UseEpilogRemainder)) {
|
||||
LLVM_DEBUG(
|
||||
dbgs()
|
||||
<< "Multiple exit/exiting blocks in loop and multi-exit unrolling not "
|
||||
|
||||
@@ -73,6 +73,6 @@ while.end: ; preds = %while.cond
|
||||
|
||||
bool ret =
|
||||
UnrollRuntimeLoopRemainder(L, 4, true, false, false, false, &LI, &SE, &DT,
|
||||
&AC, /*TTI=*/nullptr, PreserveLCSSA, 4);
|
||||
&AC, /*TTI=*/nullptr, PreserveLCSSA, 4, false);
|
||||
EXPECT_FALSE(ret);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user