@@ -107,8 +107,8 @@ static cl::opt<bool> PrintRangeChecks("irce-print-range-checks", cl::Hidden,
107
107
static cl::opt<bool > SkipProfitabilityChecks (" irce-skip-profitability-checks" ,
108
108
cl::Hidden, cl::init(false ));
109
109
110
- static cl::opt<unsigned > MinRuntimeIterations (" irce-min-runtime-iterations " ,
111
- cl::Hidden, cl::init(10 ));
110
+ static cl::opt<unsigned > MinEliminatedChecks (" irce-min-eliminated-checks " ,
111
+ cl::Hidden, cl::init(10 ));
112
112
113
113
static cl::opt<bool > AllowUnsignedLatchCondition (" irce-allow-unsigned-latch" ,
114
114
cl::Hidden, cl::init(true ));
@@ -132,15 +132,9 @@ static cl::opt<bool>
132
132
133
133
namespace {
134
134
135
- // / An inductive range check is conditional branch in a loop with
136
- // /
137
- // / 1. a very cold successor (i.e. the branch jumps to that successor very
138
- // / rarely)
139
- // /
140
- // / and
141
- // /
142
- // / 2. a condition that is provably true for some contiguous range of values
143
- // / taken by the containing loop's induction variable.
135
+ // / An inductive range check is conditional branch in a loop with a condition
136
+ // / that is provably true for some contiguous range of values taken by the
137
+ // / containing loop's induction variable.
144
138
// /
145
139
class InductiveRangeCheck {
146
140
@@ -235,6 +229,7 @@ class InductiveRangeCheck {
235
229
// / checks, and hence don't end up in \p Checks.
236
230
static void extractRangeChecksFromBranch (
237
231
BranchInst *BI, Loop *L, ScalarEvolution &SE, BranchProbabilityInfo *BPI,
232
+ std::optional<uint64_t > EstimatedTripCount,
238
233
SmallVectorImpl<InductiveRangeCheck> &Checks, bool &Changed);
239
234
};
240
235
@@ -248,9 +243,10 @@ class InductiveRangeCheckElimination {
248
243
std::optional<llvm::function_ref<llvm::BlockFrequencyInfo &()>>;
249
244
GetBFIFunc GetBFI;
250
245
251
- // Returns true if it is profitable to do a transform basing on estimation of
252
- // number of iterations.
253
- bool isProfitableToTransform (const Loop &L, LoopStructure &LS);
246
+ // Returns the estimated number of iterations based on block frequency info if
247
+ // available, or on branch probability info. Nullopt is returned if the number
248
+ // of iterations cannot be estimated.
249
+ std::optional<uint64_t > estimatedTripCount (const Loop &L);
254
250
255
251
public:
256
252
InductiveRangeCheckElimination (ScalarEvolution &SE,
@@ -524,18 +520,40 @@ void InductiveRangeCheck::extractRangeChecksFromCond(
524
520
525
521
void InductiveRangeCheck::extractRangeChecksFromBranch (
526
522
BranchInst *BI, Loop *L, ScalarEvolution &SE, BranchProbabilityInfo *BPI,
523
+ std::optional<uint64_t > EstimatedTripCount,
527
524
SmallVectorImpl<InductiveRangeCheck> &Checks, bool &Changed) {
528
525
if (BI->isUnconditional () || BI->getParent () == L->getLoopLatch ())
529
526
return ;
530
527
531
528
unsigned IndexLoopSucc = L->contains (BI->getSuccessor (0 )) ? 0 : 1 ;
532
529
assert (L->contains (BI->getSuccessor (IndexLoopSucc)) &&
533
530
" No edges coming to loop?" );
534
- BranchProbability LikelyTaken (15 , 16 );
535
531
536
- if (!SkipProfitabilityChecks && BPI &&
537
- BPI->getEdgeProbability (BI->getParent (), IndexLoopSucc) < LikelyTaken)
538
- return ;
532
+ if (!SkipProfitabilityChecks && BPI) {
533
+ auto SuccessProbability =
534
+ BPI->getEdgeProbability (BI->getParent (), IndexLoopSucc);
535
+ if (EstimatedTripCount) {
536
+ auto EstimatedEliminatedChecks =
537
+ SuccessProbability.scale (*EstimatedTripCount);
538
+ if (EstimatedEliminatedChecks < MinEliminatedChecks) {
539
+ LLVM_DEBUG (dbgs () << " irce: could not prove profitability for branch "
540
+ << *BI << " : "
541
+ << " estimated eliminated checks too low "
542
+ << EstimatedEliminatedChecks << " \n " ;);
543
+ return ;
544
+ }
545
+ } else {
546
+ BranchProbability LikelyTaken (15 , 16 );
547
+ if (SuccessProbability < LikelyTaken) {
548
+ LLVM_DEBUG (dbgs () << " irce: could not prove profitability for branch "
549
+ << *BI << " : "
550
+ << " could not estimate trip count "
551
+ << " and branch success probability too low "
552
+ << SuccessProbability << " \n " ;);
553
+ return ;
554
+ }
555
+ }
556
+ }
539
557
540
558
// IRCE expects branch's true edge comes to loop. Invert branch for opposite
541
559
// case.
@@ -940,35 +958,35 @@ PreservedAnalyses IRCEPass::run(Function &F, FunctionAnalysisManager &AM) {
940
958
return getLoopPassPreservedAnalyses ();
941
959
}
942
960
943
- bool
944
- InductiveRangeCheckElimination::isProfitableToTransform (const Loop &L,
945
- LoopStructure &LS) {
946
- if (SkipProfitabilityChecks)
947
- return true ;
961
+ std::optional<uint64_t >
962
+ InductiveRangeCheckElimination::estimatedTripCount (const Loop &L) {
948
963
if (GetBFI) {
949
964
BlockFrequencyInfo &BFI = (*GetBFI)();
950
- uint64_t hFreq = BFI.getBlockFreq (LS. Header ).getFrequency ();
965
+ uint64_t hFreq = BFI.getBlockFreq (L. getHeader () ).getFrequency ();
951
966
uint64_t phFreq = BFI.getBlockFreq (L.getLoopPreheader ()).getFrequency ();
952
- if (phFreq != 0 && hFreq != 0 && (hFreq / phFreq < MinRuntimeIterations)) {
953
- LLVM_DEBUG (dbgs () << " irce: could not prove profitability: "
954
- << " the estimated number of iterations basing on "
955
- " frequency info is " << (hFreq / phFreq) << " \n " ;);
956
- return false ;
957
- }
958
- return true ;
967
+ if (phFreq == 0 || hFreq == 0 )
968
+ return std::nullopt;
969
+ return {hFreq / phFreq};
959
970
}
960
971
961
972
if (!BPI)
962
- return true ;
973
+ return std::nullopt;
974
+
975
+ auto *Latch = L.getLoopLatch ();
976
+ if (!Latch)
977
+ return std::nullopt;
978
+
979
+ auto *LatchBr = dyn_cast<BranchInst>(Latch->getTerminator ());
980
+ if (!LatchBr)
981
+ return std::nullopt;
982
+
983
+ auto LatchBrExitIdx = LatchBr->getSuccessor (0 ) == L.getHeader () ? 1 : 0 ;
963
984
BranchProbability ExitProbability =
964
- BPI->getEdgeProbability (LS.Latch , LS.LatchBrExitIdx );
965
- if (ExitProbability > BranchProbability (1 , MinRuntimeIterations)) {
966
- LLVM_DEBUG (dbgs () << " irce: could not prove profitability: "
967
- << " the exit probability is too big " << ExitProbability
968
- << " \n " ;);
969
- return false ;
970
- }
971
- return true ;
985
+ BPI->getEdgeProbability (Latch, LatchBrExitIdx);
986
+ if (ExitProbability.isUnknown () || ExitProbability.isZero ())
987
+ return std::nullopt;
988
+
989
+ return {ExitProbability.scaleByInverse (1 )};
972
990
}
973
991
974
992
bool InductiveRangeCheckElimination::run (
@@ -988,10 +1006,11 @@ bool InductiveRangeCheckElimination::run(
988
1006
SmallVector<InductiveRangeCheck, 16 > RangeChecks;
989
1007
bool Changed = false ;
990
1008
1009
+ auto EstimatedTripCount = estimatedTripCount (*L);
991
1010
for (auto *BBI : L->getBlocks ())
992
1011
if (BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator ()))
993
- InductiveRangeCheck::extractRangeChecksFromBranch (TBI, L, SE, BPI,
994
- RangeChecks, Changed);
1012
+ InductiveRangeCheck::extractRangeChecksFromBranch (
1013
+ TBI, L, SE, BPI, EstimatedTripCount, RangeChecks, Changed);
995
1014
996
1015
if (RangeChecks.empty ())
997
1016
return Changed;
@@ -1019,8 +1038,6 @@ bool InductiveRangeCheckElimination::run(
1019
1038
return Changed;
1020
1039
}
1021
1040
LoopStructure LS = *MaybeLoopStructure;
1022
- if (!isProfitableToTransform (*L, LS))
1023
- return Changed;
1024
1041
const SCEVAddRecExpr *IndVar =
1025
1042
cast<SCEVAddRecExpr>(SE.getMinusSCEV (SE.getSCEV (LS.IndVarBase ), SE.getSCEV (LS.IndVarStep )));
1026
1043
0 commit comments