diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp --- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -758,15 +758,15 @@ } }; -bool shouldUnroll(UnrollingOption UO, Loop *L, const TargetTransformInfo &TTI, - DominatorTree &DT, ScalarEvolution &SE, - const SmallPtrSetImpl &EphValues, - OptimizationRemarkEmitter *ORE, bool MaxOrZero, - unsigned LoopSize, unsigned &TripMultiple, unsigned TripCount, - unsigned MaxTripCount, UnrollCostEstimator UCE, - TargetTransformInfo::UnrollingPreferences &UP, - TargetTransformInfo::PeelingPreferences &PP, - bool &UseUpperBound) { +std::pair +shouldUnroll(UnrollingOption UO, Loop *L, const TargetTransformInfo &TTI, + DominatorTree &DT, ScalarEvolution &SE, + const SmallPtrSetImpl &EphValues, + OptimizationRemarkEmitter *ORE, bool MaxOrZero, unsigned LoopSize, + unsigned &TripMultiple, unsigned TripCount, unsigned MaxTripCount, + UnrollCostEstimator UCE, + TargetTransformInfo::UnrollingPreferences &UP, + TargetTransformInfo::PeelingPreferences &PP, bool &UseUpperBound) { const bool UserUnrollCount = UnrollCount.getNumOccurrences() > 0; @@ -786,6 +786,9 @@ "because loop has a runtime trip count."; }); + DEBUG_WITH_TYPE("mypass", dbgs() << "With TripCount: " << TripCount + << " Entered Unrolling\n"); + if (UO == UnrollingOption::Full) { // Using unroll pragma @@ -794,7 +797,7 @@ UP.AllowExpensiveTripCount = true; UP.Force = true; if (UP.AllowRemainder && UCE.getUnrolledLoopSize(UP) < UP.Threshold) - return true; + return std::make_pair(false, true); } if (PragmaCount > 0) { @@ -804,13 +807,13 @@ UP.Force = true; if ((UP.AllowRemainder || (TripMultiple % PragmaCount == 0)) && UCE.getUnrolledLoopSize(UP) < PragmaUnrollThreshold) - return true; + return std::make_pair(false, true); } if (PragmaFullUnroll && TripCount != 0) { UP.Count = TripCount; if (UCE.getUnrolledLoopSize(UP) < PragmaUnrollThreshold) - return false; + return std::make_pair(false, false); } if (ExplicitUnroll && TripCount != 0) { @@ -843,7 +846,7 @@ UseUpperBound = (FullUnrollMaxTripCount == FullUnrollTripCount); TripCount = FullUnrollTripCount; TripMultiple = UP.UpperBound ? 1 : TripMultiple; - return ExplicitUnroll; + return std::make_pair(false, ExplicitUnroll); } else { // The loop isn't that small, but we still can fully unroll it if that // helps to remove a significant number of instructions. @@ -858,7 +861,7 @@ UseUpperBound = (FullUnrollMaxTripCount == FullUnrollTripCount); TripCount = FullUnrollTripCount; TripMultiple = UP.UpperBound ? 1 : TripMultiple; - return ExplicitUnroll; + return std::make_pair(false, ExplicitUnroll); } } } @@ -872,7 +875,7 @@ LLVM_DEBUG(dbgs() << " will not try to unroll partially because " << "-unroll-allow-partial not given\n"); UP.Count = 0; - return false; + return std::make_pair(true, ExplicitUnroll); } if (UP.Count == 0) UP.Count = TripCount; @@ -926,13 +929,13 @@ LLVM_DEBUG(dbgs() << " partially unrolling with count: " << UP.Count << "\n"); - return ExplicitUnroll; + return std::make_pair(false, ExplicitUnroll); } - DEBUG_WITH_TYPE("mypass", dbgs() << UP.Count); } - UP.Runtime |= PragmaEnableUnroll || PragmaCount > 0 || UserUnrollCount; - return ExplicitUnroll; + // if didn't return until here, should continue to other priorties + UP.Runtime |= PragmaEnableUnroll || PragmaCount > 0 || UserUnrollCount; + return std::make_pair(true, ExplicitUnroll); } // Returns true if unroll count was set explicitly. // Calculates unroll count and writes it to UP.Count. @@ -953,26 +956,46 @@ UnrollCostEstimator UCE(*L, LoopSize); - bool ExplicitUnroll = false; + bool ExplicitUnroll; + bool ShouldContinue; - ExplicitUnroll = + std::tie(ShouldContinue, ExplicitUnroll) = shouldUnroll(UnrollingOption::Full, L, TTI, DT, SE, EphValues, ORE, MaxOrZero, LoopSize, TripMultiple, TripCount, MaxTripCount, UCE, UP, PP, UseUpperBound); + DEBUG_WITH_TYPE("mypass", dbgs() << "After trying for full unroll " + << "Continue: " << int(ShouldContinue) + << " Explicit: " << int(ExplicitUnroll) + << "\n"); + + if (ShouldContinue == false) + return ExplicitUnroll; // 4th priority is loop peeling. computePeelCount(L, LoopSize, PP, TripCount, SE, UP.Threshold); if (PP.PeelCount) { UP.Runtime = false; UP.Count = 1; + DEBUG_WITH_TYPE("mypass", dbgs() << "After trying for peeling " + << "Continue: " << int(ShouldContinue) + << " Explicit: " << int(ExplicitUnroll) + << "\n"); return ExplicitUnroll; } - ExplicitUnroll = + std::tie(ShouldContinue, ExplicitUnroll) = shouldUnroll(UnrollingOption::Partial, L, TTI, DT, SE, EphValues, ORE, MaxOrZero, LoopSize, TripMultiple, TripCount, MaxTripCount, UCE, UP, PP, UseUpperBound); + DEBUG_WITH_TYPE("mypass", dbgs() << "After trying for partial unroll " + << "Continue: " << int(ShouldContinue) + << " Explicit: " << int(ExplicitUnroll) + << "\n"); + + if (ShouldContinue == false) + return ExplicitUnroll; + assert(TripCount == 0 && "All cases when TripCount is constant should be covered here.");