From e9f1882406e3639de66cb4c01cc5da61a5ac6fae Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Tue, 7 Sep 2010 23:15:30 +0000 Subject: [PATCH] Add a separate unrolling threshold when the current function is being optimized for size. The threshold value of 50 is arbitrary, and I chose it simply by analogy to the inlining thresholds, where the baseline unrolling threshold is slightly smaller than the baseline inlining threshold. This could undoubtedly use some tuning. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113306 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopUnrollPass.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index d0edfa22005..f20f7dc5d6d 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -49,6 +49,12 @@ namespace { /// that the loop unroll should be performed regardless of how much /// code expansion would result. static const unsigned NoThreshold = UINT_MAX; + + // Threshold to use when optsize is specified (and there is no + // explicit -unroll-threshold). + static const unsigned OptSizeUnrollThreshold = 50; + + unsigned CurrentThreshold; bool runOnLoop(Loop *L, LPPassManager &LPM); @@ -88,12 +94,22 @@ static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) { } bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { + LoopInfo *LI = &getAnalysis(); BasicBlock *Header = L->getHeader(); DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName() << "] Loop %" << Header->getName() << "\n"); (void)Header; + + // 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. + CurrentThreshold = UnrollThreshold; + if (Header->getParent()->hasFnAttr(Attribute::OptimizeForSize) && + UnrollThreshold.getNumOccurrences() == 0) + CurrentThreshold = OptSizeUnrollThreshold; // Find trip count unsigned TripCount = L->getSmallConstantTripCount(); @@ -111,7 +127,7 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { } // Enforce the threshold. - if (UnrollThreshold != NoThreshold) { + if (CurrentThreshold != NoThreshold) { unsigned NumCalls; unsigned LoopSize = ApproximateLoopSize(L, NumCalls); DEBUG(dbgs() << " Loop Size = " << LoopSize << "\n"); @@ -120,16 +136,16 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { return false; } uint64_t Size = (uint64_t)LoopSize*Count; - if (TripCount != 1 && Size > UnrollThreshold) { + if (TripCount != 1 && Size > CurrentThreshold) { DEBUG(dbgs() << " Too large to fully unroll with count: " << Count - << " because size: " << Size << ">" << UnrollThreshold << "\n"); + << " because size: " << Size << ">" << CurrentThreshold << "\n"); if (!UnrollAllowPartial) { DEBUG(dbgs() << " will not try to unroll partially because " << "-unroll-allow-partial not given\n"); return false; } // Reduce unroll count to be modulo of TripCount for partial unrolling - Count = UnrollThreshold / LoopSize; + Count = CurrentThreshold / LoopSize; while (Count != 0 && TripCount%Count != 0) { Count--; } -- 2.34.1