@@ -376,21 +376,22 @@ static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred,
376
376
SE.isKnownPredicate (Pred, ValAtSecondToLastIter, RightSCEV);
377
377
}
378
378
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
+ //
384
384
// for (i = 0; i < n; i++)
385
385
// if (i < 2)
386
386
// ..
387
387
// else
388
388
// ..
389
389
// }
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) {
392
392
assert (L.isLoopSimplifyForm () && " Loop needs to be in loop simplify form" );
393
- int DesiredPeelCount = 0 ;
393
+ unsigned DesiredPeelCount = 0 ;
394
+ unsigned DesiredPeelCountLast = 0 ;
394
395
395
396
// Do not peel the entire loop.
396
397
const SCEV *BE = SE.getConstantMaxBackedgeTakenCount (&L);
@@ -402,9 +403,9 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
402
403
// return true if inversed condition become known before reaching the
403
404
// MaxPeelCount limit.
404
405
auto PeelWhilePredicateIsKnown =
405
- [&](int &PeelCount, const SCEV *&IterVal, const SCEV *BoundSCEV,
406
+ [&](unsigned &PeelCount, const SCEV *&IterVal, const SCEV *BoundSCEV,
406
407
const SCEV *Step, ICmpInst::Predicate Pred) {
407
- while (unsigned ( std::abs ( PeelCount)) < MaxPeelCount &&
408
+ while (PeelCount < MaxPeelCount &&
408
409
SE.isKnownPredicate (Pred, IterVal, BoundSCEV)) {
409
410
IterVal = SE.getAddExpr (IterVal, Step);
410
411
++PeelCount;
@@ -461,7 +462,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
461
462
462
463
// Check if extending the current DesiredPeelCount lets us evaluate Pred
463
464
// or !Pred in the loop body statically.
464
- int NewPeelCount = DesiredPeelCount;
465
+ unsigned NewPeelCount = DesiredPeelCount;
465
466
466
467
const SCEV *IterVal = LeftAR->evaluateAtIteration (
467
468
SE.getConstant (LeftSCEV->getType (), NewPeelCount), SE);
@@ -476,7 +477,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
476
477
if (!PeelWhilePredicateIsKnown (NewPeelCount, IterVal, RightSCEV, Step,
477
478
Pred)) {
478
479
if (shouldPeelLastIteration (L, Pred, LeftAR, RightSCEV, SE))
479
- DesiredPeelCount = - 1 ;
480
+ DesiredPeelCountLast = 1 ;
480
481
return ;
481
482
}
482
483
@@ -489,12 +490,13 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
489
490
RightSCEV) &&
490
491
!SE.isKnownPredicate (Pred, IterVal, RightSCEV) &&
491
492
SE.isKnownPredicate (Pred, NextIterVal, RightSCEV)) {
492
- if (unsigned ( std::abs ( NewPeelCount)) >= MaxPeelCount)
493
+ if (NewPeelCount >= MaxPeelCount)
493
494
return ; // Need to peel one more iteration, but can't. Give up.
494
495
++NewPeelCount; // Great!
495
496
}
496
497
497
498
DesiredPeelCount = std::max (DesiredPeelCount, NewPeelCount);
499
+ DesiredPeelCountLast = std::max (DesiredPeelCountLast, NewPeelCount);
498
500
};
499
501
500
502
auto ComputePeelCountMinMax = [&](MinMaxIntrinsic *MinMax) {
@@ -528,7 +530,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
528
530
// Check that AddRec is not wrapping.
529
531
if (!(IsSigned ? AddRec->hasNoSignedWrap () : AddRec->hasNoUnsignedWrap ()))
530
532
return ;
531
- int NewPeelCount = DesiredPeelCount;
533
+ unsigned NewPeelCount = DesiredPeelCount;
532
534
const SCEV *IterVal = AddRec->evaluateAtIteration (
533
535
SE.getConstant (AddRec->getType (), NewPeelCount), SE);
534
536
if (!PeelWhilePredicateIsKnown (NewPeelCount, IterVal, BoundSCEV, Step,
@@ -556,7 +558,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
556
558
ComputePeelCount (BI->getCondition (), 0 );
557
559
}
558
560
559
- return DesiredPeelCount;
561
+ return { DesiredPeelCount, DesiredPeelCountLast} ;
560
562
}
561
563
562
564
// / This "heuristic" exactly matches implicit behavior which used to exist
@@ -649,9 +651,9 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
649
651
DesiredPeelCount = std::max (DesiredPeelCount, *NumPeels);
650
652
}
651
653
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);
655
657
656
658
if (DesiredPeelCount == 0 )
657
659
DesiredPeelCount = peelToTurnInvariantLoadsDerefencebale (*L, DT, AC);
@@ -666,9 +668,23 @@ void llvm::computePeelCount(Loop *L, unsigned LoopSize,
666
668
<< " some Phis into invariants.\n " );
667
669
PP.PeelCount = DesiredPeelCount;
668
670
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 ;
672
688
return ;
673
689
}
674
690
}
0 commit comments