Skip to content

Commit 95416ac

Browse files
committed
!fixup update to return pair of peel counts
1 parent 4083a70 commit 95416ac

File tree

1 file changed

+37
-21
lines changed

1 file changed

+37
-21
lines changed

llvm/lib/Transforms/Utils/LoopPeel.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -376,21 +376,22 @@ static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred,
376376
SE.isKnownPredicate(Pred, ValAtSecondToLastIter, RightSCEV);
377377
}
378378

379-
// Return the number of iterations to peel off that make conditions in the
380-
// body true/false. Positive return values indicate the iterations to peel of
381-
// from the front and negative return values indicate the number of iterations
382-
// from the back after removing the sign. For example, if we peel 2 iterations
383-
// off the loop below, the condition i < 2 can be evaluated at compile time.
379+
// Return the number of iterations to peel off from the beginning and end of the
380+
// loop respectively, that make conditions in the body true/false. For example,
381+
// if we peel 2 iterations off the loop below, the condition i < 2 can be
382+
// evaluated at compile time.
383+
//
384384
// for (i = 0; i < n; i++)
385385
// if (i < 2)
386386
// ..
387387
// else
388388
// ..
389389
// }
390-
static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
391-
ScalarEvolution &SE) {
390+
static std::pair<unsigned, unsigned>
391+
countToEliminateCompares(Loop &L, unsigned MaxPeelCount, ScalarEvolution &SE) {
392392
assert(L.isLoopSimplifyForm() && "Loop needs to be in loop simplify form");
393-
int DesiredPeelCount = 0;
393+
unsigned DesiredPeelCount = 0;
394+
unsigned DesiredPeelCountLast = 0;
394395

395396
// Do not peel the entire loop.
396397
const SCEV *BE = SE.getConstantMaxBackedgeTakenCount(&L);
@@ -402,9 +403,9 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
402403
// return true if inversed condition become known before reaching the
403404
// MaxPeelCount limit.
404405
auto PeelWhilePredicateIsKnown =
405-
[&](int &PeelCount, const SCEV *&IterVal, const SCEV *BoundSCEV,
406+
[&](unsigned &PeelCount, const SCEV *&IterVal, const SCEV *BoundSCEV,
406407
const SCEV *Step, ICmpInst::Predicate Pred) {
407-
while (unsigned(std::abs(PeelCount)) < MaxPeelCount &&
408+
while (PeelCount < MaxPeelCount &&
408409
SE.isKnownPredicate(Pred, IterVal, BoundSCEV)) {
409410
IterVal = SE.getAddExpr(IterVal, Step);
410411
++PeelCount;
@@ -461,7 +462,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
461462

462463
// Check if extending the current DesiredPeelCount lets us evaluate Pred
463464
// or !Pred in the loop body statically.
464-
int NewPeelCount = DesiredPeelCount;
465+
unsigned NewPeelCount = DesiredPeelCount;
465466

466467
const SCEV *IterVal = LeftAR->evaluateAtIteration(
467468
SE.getConstant(LeftSCEV->getType(), NewPeelCount), SE);
@@ -476,7 +477,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
476477
if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, RightSCEV, Step,
477478
Pred)) {
478479
if (shouldPeelLastIteration(L, Pred, LeftAR, RightSCEV, SE))
479-
DesiredPeelCount = -1;
480+
DesiredPeelCountLast = 1;
480481
return;
481482
}
482483

@@ -489,12 +490,13 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
489490
RightSCEV) &&
490491
!SE.isKnownPredicate(Pred, IterVal, RightSCEV) &&
491492
SE.isKnownPredicate(Pred, NextIterVal, RightSCEV)) {
492-
if (unsigned(std::abs(NewPeelCount)) >= MaxPeelCount)
493+
if (NewPeelCount >= MaxPeelCount)
493494
return; // Need to peel one more iteration, but can't. Give up.
494495
++NewPeelCount; // Great!
495496
}
496497

497498
DesiredPeelCount = std::max(DesiredPeelCount, NewPeelCount);
499+
DesiredPeelCountLast = std::max(DesiredPeelCountLast, NewPeelCount);
498500
};
499501

500502
auto ComputePeelCountMinMax = [&](MinMaxIntrinsic *MinMax) {
@@ -528,7 +530,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
528530
// Check that AddRec is not wrapping.
529531
if (!(IsSigned ? AddRec->hasNoSignedWrap() : AddRec->hasNoUnsignedWrap()))
530532
return;
531-
int NewPeelCount = DesiredPeelCount;
533+
unsigned NewPeelCount = DesiredPeelCount;
532534
const SCEV *IterVal = AddRec->evaluateAtIteration(
533535
SE.getConstant(AddRec->getType(), NewPeelCount), SE);
534536
if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, BoundSCEV, Step,
@@ -556,7 +558,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
556558
ComputePeelCount(BI->getCondition(), 0);
557559
}
558560

559-
return DesiredPeelCount;
561+
return {DesiredPeelCount, DesiredPeelCountLast};
560562
}
561563

562564
/// This "heuristic" exactly matches implicit behavior which used to exist
@@ -649,9 +651,9 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
649651
DesiredPeelCount = std::max(DesiredPeelCount, *NumPeels);
650652
}
651653

652-
int CountToEliminateCmps = countToEliminateCompares(*L, MaxPeelCount, SE);
653-
DesiredPeelCount =
654-
std::max(DesiredPeelCount, unsigned(std::abs(CountToEliminateCmps)));
654+
const auto &[CountToEliminateCmps, CountToEliminateCmpsLast] =
655+
countToEliminateCompares(*L, MaxPeelCount, SE);
656+
DesiredPeelCount = std::max(DesiredPeelCount, CountToEliminateCmps);
655657

656658
if (DesiredPeelCount == 0)
657659
DesiredPeelCount = peelToTurnInvariantLoadsDerefencebale(*L, DT, AC);
@@ -666,9 +668,23 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
666668
<< " some Phis into invariants.\n");
667669
PP.PeelCount = DesiredPeelCount;
668670
PP.PeelProfiledIterations = false;
669-
PP.PeelLast =
670-
DesiredPeelCount == unsigned(std::abs(CountToEliminateCmps)) &&
671-
CountToEliminateCmps < 0;
671+
PP.PeelLast = false;
672+
return;
673+
}
674+
}
675+
676+
if (CountToEliminateCmpsLast > 0) {
677+
unsigned DesiredPeelCountLast =
678+
std::min(CountToEliminateCmpsLast, MaxPeelCount);
679+
// Consider max peel count limitation.
680+
assert(DesiredPeelCountLast > 0 && "Wrong loop size estimation?");
681+
if (DesiredPeelCountLast + AlreadyPeeled <= UnrollPeelMaxCount) {
682+
LLVM_DEBUG(dbgs() << "Peel " << DesiredPeelCount
683+
<< " iteration(s) to turn"
684+
<< " some Phis into invariants.\n");
685+
PP.PeelCount = DesiredPeelCountLast;
686+
PP.PeelProfiledIterations = false;
687+
PP.PeelLast = true;
672688
return;
673689
}
674690
}

0 commit comments

Comments
 (0)