summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2014-01-31 10:51:08 +0000
committerChandler Carruth <chandlerc@gmail.com>2014-01-31 10:51:08 +0000
commit93228f6199694860fd824e765293718561f00136 (patch)
treed14ce9800910f99f41534aa7408572ede651dfea /lib
parentf0b161d7743934936ada17c06c871bceacd5767f (diff)
downloadllvm-93228f6199694860fd824e765293718561f00136.tar.gz
llvm-93228f6199694860fd824e765293718561f00136.tar.bz2
llvm-93228f6199694860fd824e765293718561f00136.tar.xz
[vectorizer] Tweak the way we do small loop runtime unrolling in the
loop vectorizer to not do so when runtime pointer checks are needed and share code with the new (not yet enabled) load/store saturation runtime unrolling. Also ensure that we only consider the runtime checks when the loop hasn't already been vectorized. If it has, the runtime check cost has already been paid. I've fleshed out a test case to cover the scalar unrolling as well as the vector unrolling and comment clearly why we are or aren't following the pattern. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200530 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp37
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp
index 1ffb4289cb..1f494922b3 100644
--- a/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -5195,26 +5195,33 @@ LoopVectorizationCostModel::selectUnrollFactor(bool OptForSize,
return UF;
}
- if (EnableLoadStoreRuntimeUnroll &&
- !Legal->getRuntimePointerCheck()->Need &&
+ // Note that if we've already vectorized the loop we will have done the
+ // runtime check and so unrolling won't require further checks.
+ bool UnrollingRequiresRuntimePointerCheck =
+ (VF == 1 && Legal->getRuntimePointerCheck()->Need);
+
+ // We want to unroll small loops in order to reduce the loop overhead and
+ // potentially expose ILP opportunities.
+ DEBUG(dbgs() << "LV: Loop cost is " << LoopCost << '\n');
+ if (!UnrollingRequiresRuntimePointerCheck &&
LoopCost < SmallLoopCost) {
+ // We assume that the cost overhead is 1 and we use the cost model
+ // to estimate the cost of the loop and unroll until the cost of the
+ // loop overhead is about 5% of the cost of the loop.
+ unsigned SmallUF = std::min(UF, (unsigned)PowerOf2Floor(SmallLoopCost / LoopCost));
+
// Unroll until store/load ports (estimated by max unroll factor) are
// saturated.
- unsigned UnrollStores = UF / (Legal->NumStores ? Legal->NumStores : 1);
- unsigned UnrollLoads = UF / (Legal->NumLoads ? Legal->NumLoads : 1);
- UF = std::max(std::min(UnrollStores, UnrollLoads), 1u);
- return UF;
- }
+ unsigned StoresUF = UF / (Legal->NumStores ? Legal->NumStores : 1);
+ unsigned LoadsUF = UF / (Legal->NumLoads ? Legal->NumLoads : 1);
+
+ if (EnableLoadStoreRuntimeUnroll && std::max(StoresUF, LoadsUF) > SmallUF) {
+ DEBUG(dbgs() << "LV: Unrolling to saturate store or load ports.\n");
+ return std::max(StoresUF, LoadsUF);
+ }
- // We want to unroll tiny loops in order to reduce the loop overhead.
- // We assume that the cost overhead is 1 and we use the cost model
- // to estimate the cost of the loop and unroll until the cost of the
- // loop overhead is about 5% of the cost of the loop.
- DEBUG(dbgs() << "LV: Loop cost is " << LoopCost << '\n');
- if (LoopCost < SmallLoopCost) {
DEBUG(dbgs() << "LV: Unrolling to reduce branch cost.\n");
- unsigned NewUF = PowerOf2Floor(SmallLoopCost / LoopCost);
- return std::min(NewUF, UF);
+ return SmallUF;
}
DEBUG(dbgs() << "LV: Not Unrolling.\n");