@@ -486,12 +486,7 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
486486
487487 // All these values should be taken only after peeling because they might have
488488 // changed.
489- BasicBlock *Preheader = L->getLoopPreheader ();
490- BasicBlock *Header = L->getHeader ();
491489 BasicBlock *LatchBlock = L->getLoopLatch ();
492- SmallVector<BasicBlock *, 4 > ExitBlocks;
493- L->getExitBlocks (ExitBlocks);
494- std::vector<BasicBlock *> OriginalLoopBlocks = L->getBlocks ();
495490
496491 const unsigned MaxTripCount = SE->getSmallConstantMaxTripCount (L);
497492 const bool MaxOrZero = SE->isBackedgeTakenCountMaxOrZero (L);
@@ -504,42 +499,6 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
504499 if (MaxTripCount && ULO.Count > MaxTripCount)
505500 ULO.Count = MaxTripCount;
506501
507- struct ExitInfo {
508- unsigned TripCount;
509- unsigned TripMultiple;
510- unsigned BreakoutTrip;
511- bool ExitOnTrue;
512- BasicBlock *FirstExitingBlock = nullptr ;
513- SmallVector<BasicBlock *> ExitingBlocks;
514- };
515- DenseMap<BasicBlock *, ExitInfo> ExitInfos;
516- SmallVector<BasicBlock *, 4 > ExitingBlocks;
517- L->getExitingBlocks (ExitingBlocks);
518- for (auto *ExitingBlock : ExitingBlocks) {
519- // The folding code is not prepared to deal with non-branch instructions
520- // right now.
521- auto *BI = dyn_cast<BranchInst>(ExitingBlock->getTerminator ());
522- if (!BI)
523- continue ;
524-
525- ExitInfo &Info = ExitInfos[ExitingBlock];
526- Info.TripCount = SE->getSmallConstantTripCount (L, ExitingBlock);
527- Info.TripMultiple = SE->getSmallConstantTripMultiple (L, ExitingBlock);
528- if (Info.TripCount != 0 ) {
529- Info.BreakoutTrip = Info.TripCount % ULO.Count ;
530- Info.TripMultiple = 0 ;
531- } else {
532- Info.BreakoutTrip = Info.TripMultiple =
533- (unsigned )std::gcd (ULO.Count , Info.TripMultiple );
534- }
535- Info.ExitOnTrue = !L->contains (BI->getSuccessor (0 ));
536- Info.ExitingBlocks .push_back (ExitingBlock);
537- LLVM_DEBUG (dbgs () << " Exiting block %" << ExitingBlock->getName ()
538- << " : TripCount=" << Info.TripCount
539- << " , TripMultiple=" << Info.TripMultiple
540- << " , BreakoutTrip=" << Info.BreakoutTrip << " \n " );
541- }
542-
543502 // Are we eliminating the loop control altogether? Note that we can know
544503 // we're eliminating the backedge without knowing exactly which iteration
545504 // of the unrolled body exits.
@@ -552,17 +511,6 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
552511 if (CompletelyUnroll)
553512 ULO.Runtime = false ;
554513
555- // Go through all exits of L and see if there are any phi-nodes there. We just
556- // conservatively assume that they're inserted to preserve LCSSA form, which
557- // means that complete unrolling might break this form. We need to either fix
558- // it in-place after the transformation, or entirely rebuild LCSSA. TODO: For
559- // now we just recompute LCSSA for the outer loop, but it should be possible
560- // to fix it in-place.
561- bool NeedToFixLCSSA =
562- PreserveLCSSA && CompletelyUnroll &&
563- any_of (ExitBlocks,
564- [](const BasicBlock *BB) { return isa<PHINode>(BB->begin ()); });
565-
566514 // The current loop unroll pass can unroll loops that have
567515 // (1) single latch; and
568516 // (2a) latch is unconditional; or
@@ -587,21 +535,87 @@ llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
587535 UnrollRuntimeEpilog.getNumOccurrences () ? UnrollRuntimeEpilog
588536 : isEpilogProfitable (L);
589537
538+ LoopReminderUnrollResult UnrollReminderResult =
539+ LoopReminderUnrollResult::Unmodified;
540+ if (ULO.Runtime ) {
541+ UnrollReminderResult = UnrollRuntimeLoopRemainder (
542+ L, ULO.Count , ULO.AllowExpensiveTripCount , EpilogProfitability,
543+ ULO.UnrollRemainder , ULO.ForgetAllSCEV , LI, SE, DT, AC, TTI,
544+ PreserveLCSSA, ULO.SCEVExpansionBudget , ULO.RuntimeUnrollMultiExit ,
545+ RemainderLoop);
546+ LatchBlock = L->getLoopLatch ();
547+ LatchIsExiting = L->isLoopExiting (LatchBlock);
548+ }
549+
590550 if (ULO.Runtime &&
591- !UnrollRuntimeLoopRemainder (L, ULO.Count , ULO.AllowExpensiveTripCount ,
592- EpilogProfitability, ULO.UnrollRemainder ,
593- ULO.ForgetAllSCEV , LI, SE, DT, AC, TTI,
594- PreserveLCSSA, ULO.SCEVExpansionBudget ,
595- ULO.RuntimeUnrollMultiExit , RemainderLoop)) {
551+ UnrollReminderResult != LoopReminderUnrollResult::Unrolled) {
596552 if (ULO.Force )
597553 ULO.Runtime = false ;
598554 else {
599555 LLVM_DEBUG (dbgs () << " Won't unroll; remainder loop could not be "
600556 " generated when assuming runtime trip count\n " );
601- return LoopUnrollResult::Unmodified;
557+ // Loop might have been rotated inside of UnrollRuntimeLoopRemainder and
558+ // this needs to be propagated.
559+ return UnrollReminderResult == LoopReminderUnrollResult::Rotated
560+ ? LoopUnrollResult::Modified
561+ : LoopUnrollResult::Unmodified;
562+ ;
602563 }
603564 }
604565
566+ BasicBlock *Preheader = L->getLoopPreheader ();
567+ BasicBlock *Header = L->getHeader ();
568+ SmallVector<BasicBlock *, 4 > ExitBlocks;
569+ L->getExitBlocks (ExitBlocks);
570+ std::vector<BasicBlock *> OriginalLoopBlocks = L->getBlocks ();
571+
572+ // Go through all exits of L and see if there are any phi-nodes there. We just
573+ // conservatively assume that they're inserted to preserve LCSSA form, which
574+ // means that complete unrolling might break this form. We need to either fix
575+ // it in-place after the transformation, or entirely rebuild LCSSA. TODO: For
576+ // now we just recompute LCSSA for the outer loop, but it should be possible
577+ // to fix it in-place.
578+ bool NeedToFixLCSSA =
579+ PreserveLCSSA && CompletelyUnroll &&
580+ any_of (ExitBlocks,
581+ [](const BasicBlock *BB) { return isa<PHINode>(BB->begin ()); });
582+
583+ struct ExitInfo {
584+ unsigned TripCount;
585+ unsigned TripMultiple;
586+ unsigned BreakoutTrip;
587+ bool ExitOnTrue;
588+ BasicBlock *FirstExitingBlock = nullptr ;
589+ SmallVector<BasicBlock *> ExitingBlocks;
590+ };
591+ DenseMap<BasicBlock *, ExitInfo> ExitInfos;
592+ SmallVector<BasicBlock *, 4 > ExitingBlocks;
593+ L->getExitingBlocks (ExitingBlocks);
594+ for (auto *ExitingBlock : ExitingBlocks) {
595+ // The folding code is not prepared to deal with non-branch instructions
596+ // right now.
597+ auto *BI = dyn_cast<BranchInst>(ExitingBlock->getTerminator ());
598+ if (!BI)
599+ continue ;
600+
601+ ExitInfo &Info = ExitInfos[ExitingBlock];
602+ Info.TripCount = SE->getSmallConstantTripCount (L, ExitingBlock);
603+ Info.TripMultiple = SE->getSmallConstantTripMultiple (L, ExitingBlock);
604+ if (Info.TripCount != 0 ) {
605+ Info.BreakoutTrip = Info.TripCount % ULO.Count ;
606+ Info.TripMultiple = 0 ;
607+ } else {
608+ Info.BreakoutTrip = Info.TripMultiple =
609+ (unsigned )std::gcd (ULO.Count , Info.TripMultiple );
610+ }
611+ Info.ExitOnTrue = !L->contains (BI->getSuccessor (0 ));
612+ Info.ExitingBlocks .push_back (ExitingBlock);
613+ LLVM_DEBUG (dbgs () << " Exiting block %" << ExitingBlock->getName ()
614+ << " : TripCount=" << Info.TripCount
615+ << " , TripMultiple=" << Info.TripMultiple
616+ << " , BreakoutTrip=" << Info.BreakoutTrip << " \n " );
617+ }
618+
605619 using namespace ore ;
606620 // Report the unrolling decision.
607621 if (CompletelyUnroll) {
0 commit comments