Index: lib/Transforms/Scalar/LoopUnrollPass.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnrollPass.cpp +++ lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -661,13 +661,21 @@ // be beneficial to fully unroll the loop even if unrolledcost is large. We // use (RolledDynamicCost / UnrolledCost) to model the unroll benefits to adjust // the unroll threshold. +// Another side-benefit of fully unrolling is to remove all branches and put all +// instructions into a single basic block, which expands optimization windows. +// To model this, we set larger threshold when the loop trip count is small +// because the relative code size increase (comparing with original loop) is +// small when trip count is small. static unsigned getFullUnrollBoostingFactor(const EstimatedUnrollCost &Cost, + unsigned TripCount, unsigned MaxPercentThresholdBoost) { + assert(TripCount != 0 && "TripCount should not be 0."); if (Cost.RolledDynamicCost >= UINT_MAX / 100) return 100; else if (Cost.UnrolledCost != 0) // The boosting factor is RolledDynamicCost / UnrolledCost - return std::min(100 * Cost.RolledDynamicCost / Cost.UnrolledCost, + return std::min(100 * Cost.RolledDynamicCost / Cost.UnrolledCost + + 40 * UnrollMaxIterationsCountToAnalyze / TripCount, MaxPercentThresholdBoost); else return MaxPercentThresholdBoost; @@ -759,7 +767,7 @@ L, FullUnrollTripCount, DT, *SE, TTI, UP.Threshold * UP.MaxPercentThresholdBoost / 100)) { unsigned Boost = - getFullUnrollBoostingFactor(*Cost, UP.MaxPercentThresholdBoost); + getFullUnrollBoostingFactor(*Cost, UP.Count, UP.MaxPercentThresholdBoost); if (Cost->UnrolledCost < UP.Threshold * Boost / 100) { UseUpperBound = (MaxTripCount == FullUnrollTripCount); TripCount = FullUnrollTripCount; Index: test/Transforms/LoopUnroll/full-unroll-heuristics.ll =================================================================== --- test/Transforms/LoopUnroll/full-unroll-heuristics.ll +++ test/Transforms/LoopUnroll/full-unroll-heuristics.ll @@ -18,7 +18,7 @@ ; and unrolled size is 65. ; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-threshold=10 -unroll-max-percent-threshold-boost=100 | FileCheck %s -check-prefix=TEST1 -; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-threshold=20 -unroll-max-percent-threshold-boost=200 | FileCheck %s -check-prefix=TEST2 +; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-threshold=12 -unroll-max-percent-threshold-boost=400 | FileCheck %s -check-prefix=TEST2 ; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=1000 -unroll-threshold=20 -unroll-max-percent-threshold-boost=100 | FileCheck %s -check-prefix=TEST3 ; If the absolute threshold is too low, we should not unroll: