aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/LoopUnrollPass.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-09-07 23:15:30 +0000
committerOwen Anderson <resistor@mac.com>2010-09-07 23:15:30 +0000
commite9f1882406e3639de66cb4c01cc5da61a5ac6fae (patch)
tree119c8804e56500b601575e8378cd8a9faae7d8c4 /lib/Transforms/Scalar/LoopUnrollPass.cpp
parent8c3593658371902e8486fd9a0bb970b5e95a2562 (diff)
downloadexternal_llvm-e9f1882406e3639de66cb4c01cc5da61a5ac6fae.zip
external_llvm-e9f1882406e3639de66cb4c01cc5da61a5ac6fae.tar.gz
external_llvm-e9f1882406e3639de66cb4c01cc5da61a5ac6fae.tar.bz2
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
Diffstat (limited to 'lib/Transforms/Scalar/LoopUnrollPass.cpp')
-rw-r--r--lib/Transforms/Scalar/LoopUnrollPass.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp
index d0edfa2..f20f7dc 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<LoopInfo>();
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--;
}