diff options
author | Michael Zolotukhin <mzolotukhin@apple.com> | 2015-02-06 20:20:40 +0000 |
---|---|---|
committer | Michael Zolotukhin <mzolotukhin@apple.com> | 2015-02-06 20:20:40 +0000 |
commit | 7af83c1f39e999a51e19ba7116c9046af18a078b (patch) | |
tree | e073ebf0960dec3b72c02e53182248922b1e7139 /llvm/lib | |
parent | 0ff23ec54428cb44f35ddb178843c7b7caada7e0 (diff) | |
download | bcm5719-llvm-7af83c1f39e999a51e19ba7116c9046af18a078b.tar.gz bcm5719-llvm-7af83c1f39e999a51e19ba7116c9046af18a078b.zip |
Use estimated number of optimized insns in unroll-threshold computation.
If complete-unroll could help us to optimize away N% of instructions, we
might want to do this even if the final size would exceed loop-unroll
threshold. However, we don't want to unroll huge loop, and we are add
AbsoluteThreshold to avoid that - this threshold will never be crossed,
even if we expect to optimize 99% instructions after that.
llvm-svn: 228434
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp index 87237c62299..f691beb7219 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -45,6 +45,17 @@ static cl::opt<unsigned> UnrollMaxIterationsCountToAnalyze( cl::desc("Don't allow loop unrolling to simulate more than this number of" "iterations when checking full unroll profitability")); +static cl::opt<unsigned> UnrollMinPercentOfOptimized( + "unroll-percent-of-optimized-for-complete-unroll", cl::init(20), cl::Hidden, + cl::desc("If complete unrolling could trigger further optimizations, and, " + "by that, remove the given percent of instructions, perform the " + "complete unroll even if it's beyond the threshold")); + +static cl::opt<unsigned> UnrollAbsoluteThreshold( + "unroll-absolute-threshold", cl::init(2000), cl::Hidden, + cl::desc("Don't unroll if the unrolled size is bigger than this threshold," + " even if we can remove big portion of instructions later.")); + static cl::opt<unsigned> UnrollCount("unroll-count", cl::init(0), cl::Hidden, cl::desc("Use this unroll count for all loops including those with " @@ -70,11 +81,16 @@ namespace { static char ID; // Pass ID, replacement for typeid LoopUnroll(int T = -1, int C = -1, int P = -1, int R = -1) : LoopPass(ID) { CurrentThreshold = (T == -1) ? UnrollThreshold : unsigned(T); + CurrentAbsoluteThreshold = UnrollAbsoluteThreshold; + CurrentMinPercentOfOptimized = UnrollMinPercentOfOptimized; CurrentCount = (C == -1) ? UnrollCount : unsigned(C); CurrentAllowPartial = (P == -1) ? UnrollAllowPartial : (bool)P; CurrentRuntime = (R == -1) ? UnrollRuntime : (bool)R; UserThreshold = (T != -1) || (UnrollThreshold.getNumOccurrences() > 0); + UserAbsoluteThreshold = (UnrollAbsoluteThreshold.getNumOccurrences() > 0); + UserPercentOfOptimized = + (UnrollMinPercentOfOptimized.getNumOccurrences() > 0); UserAllowPartial = (P != -1) || (UnrollAllowPartial.getNumOccurrences() > 0); UserRuntime = (R != -1) || (UnrollRuntime.getNumOccurrences() > 0); @@ -98,10 +114,16 @@ namespace { unsigned CurrentCount; unsigned CurrentThreshold; + unsigned CurrentAbsoluteThreshold; + unsigned CurrentMinPercentOfOptimized; bool CurrentAllowPartial; bool CurrentRuntime; bool UserCount; // CurrentCount is user-specified. bool UserThreshold; // CurrentThreshold is user-specified. + bool UserAbsoluteThreshold; // CurrentAbsoluteThreshold is + // user-specified. + bool UserPercentOfOptimized; // CurrentMinPercentOfOptimized is + // user-specified. bool UserAllowPartial; // CurrentAllowPartial is user-specified. bool UserRuntime; // CurrentRuntime is user-specified. @@ -133,6 +155,8 @@ namespace { void getUnrollingPreferences(Loop *L, const TargetTransformInfo &TTI, TargetTransformInfo::UnrollingPreferences &UP) { UP.Threshold = CurrentThreshold; + UP.AbsoluteThreshold = CurrentAbsoluteThreshold; + UP.MinPercentOfOptimized = CurrentMinPercentOfOptimized; UP.OptSizeThreshold = OptSizeUnrollThreshold; UP.PartialThreshold = CurrentThreshold; UP.PartialOptSizeThreshold = OptSizeUnrollThreshold; @@ -160,13 +184,32 @@ namespace { void selectThresholds(const Loop *L, bool HasPragma, const TargetTransformInfo::UnrollingPreferences &UP, unsigned &Threshold, unsigned &PartialThreshold, - unsigned NumberOfSimplifiedInstructions) { + unsigned NumberOfOptimizedInstructions) { // Determine the current unrolling threshold. While this is // normally set from UnrollThreshold, it is overridden to a // smaller value if the current function is marked as // optimize-for-size, and the unroll threshold was not user // specified. Threshold = UserThreshold ? CurrentThreshold : UP.Threshold; + + // If we are allowed to completely unroll if we can remove M% of + // instructions, and we know that with complete unrolling we'll be able + // to kill N instructions, then we can afford to completely unroll loops + // with unrolled size up to N*100/M. + // Adjust the threshold according to that: + unsigned PercentOfOptimizedForCompleteUnroll = + UserPercentOfOptimized ? CurrentMinPercentOfOptimized + : UP.MinPercentOfOptimized; + unsigned AbsoluteThreshold = UserAbsoluteThreshold + ? CurrentAbsoluteThreshold + : UP.AbsoluteThreshold; + if (PercentOfOptimizedForCompleteUnroll) + Threshold = std::max<unsigned>(Threshold, + NumberOfOptimizedInstructions * 100 / + PercentOfOptimizedForCompleteUnroll); + // But don't allow unrolling loops bigger than absolute threshold. + Threshold = std::min<unsigned>(Threshold, AbsoluteThreshold); + PartialThreshold = UserThreshold ? CurrentThreshold : UP.PartialThreshold; if (!UserThreshold && L->getHeader()->getParent()->getAttributes(). @@ -186,7 +229,6 @@ namespace { PartialThreshold = std::max<unsigned>(PartialThreshold, PragmaUnrollThreshold); } - Threshold += NumberOfSimplifiedInstructions; } }; } |