summaryrefslogtreecommitdiff
path: root/lib/Transforms/Vectorize/LoopVectorize.cpp
diff options
context:
space:
mode:
authorArnold Schwaighofer <aschwaighofer@apple.com>2013-02-05 15:08:02 +0000
committerArnold Schwaighofer <aschwaighofer@apple.com>2013-02-05 15:08:02 +0000
commit935645b7655a0b5189d40b3d65b3bcb14e30d859 (patch)
treede502da9e44f1930cd496e6e0667ab1bbb340d2a /lib/Transforms/Vectorize/LoopVectorize.cpp
parentb9e1a33941d25faf54dc3ddec4be7f8f0750a155 (diff)
Loop Vectorizer: Handle pointer stores/loads in getWidestType()
In the loop vectorizer cost model, we used to ignore stores/loads of a pointer type when computing the widest type within a loop. This meant that if we had only stores/loads of pointers in a loop we would return a widest type of 8bits (instead of 32 or 64 bit) and therefore a vector factor that was too big. Now, if we see a consecutive store/load of pointers we use the size of a pointer (from data layout). This problem occured in SingleSource/Benchmarks/Shootout-C++/hash.cpp (reduced test case is the first test in vector_ptr_load_store.ll). radar://13139343 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174377 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Vectorize/LoopVectorize.cpp')
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp
index 1b242c93ba1..62542737de0 100644
--- a/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -518,8 +518,9 @@ class LoopVectorizationCostModel {
public:
LoopVectorizationCostModel(Loop *L, ScalarEvolution *SE, LoopInfo *LI,
LoopVectorizationLegality *Legal,
- const TargetTransformInfo &TTI)
- : TheLoop(L), SE(SE), LI(LI), Legal(Legal), TTI(TTI) {}
+ const TargetTransformInfo &TTI,
+ DataLayout *DL)
+ : TheLoop(L), SE(SE), LI(LI), Legal(Legal), TTI(TTI), DL(DL) {}
/// Information about vectorization costs
struct VectorizationFactor {
@@ -575,6 +576,10 @@ private:
/// the scalar type.
static Type* ToVectorTy(Type *Scalar, unsigned VF);
+ /// Returns whether the instruction is a load or store and will be a emitted
+ /// as a vector operation.
+ bool isConsecutiveLoadOrStore(Instruction *I);
+
/// The loop that we evaluate.
Loop *TheLoop;
/// Scev analysis.
@@ -585,6 +590,8 @@ private:
LoopVectorizationLegality *Legal;
/// Vector target information.
const TargetTransformInfo &TTI;
+ /// Target data layout information.
+ DataLayout *DL;
};
/// The LoopVectorize Pass.
@@ -624,7 +631,7 @@ struct LoopVectorize : public LoopPass {
}
// Use the cost model.
- LoopVectorizationCostModel CM(L, SE, LI, &LVL, *TTI);
+ LoopVectorizationCostModel CM(L, SE, LI, &LVL, *TTI, DL);
// Check the function attribues to find out if this function should be
// optimized for size.
@@ -2786,14 +2793,17 @@ unsigned LoopVectorizationCostModel::getWidestType() {
continue;
// Examine the stored values.
- if (StoreInst *ST = dyn_cast<StoreInst>(it))
+ StoreInst *ST = 0;
+ if ((ST = dyn_cast<StoreInst>(it)))
T = ST->getValueOperand()->getType();
- // Ignore stored/loaded pointer types.
- if (T->isPointerTy())
- continue;
-
- MaxWidth = std::max(MaxWidth, T->getScalarSizeInBits());
+ // Ignore loaded pointer types and stored pointer types that are not
+ // consecutive. However, we do want to take consecutive stores/loads of
+ // pointer vectors into account.
+ if (T->isPointerTy() && isConsecutiveLoadOrStore(it))
+ MaxWidth = std::max(MaxWidth, DL->getPointerSizeInBits());
+ else
+ MaxWidth = std::max(MaxWidth, T->getScalarSizeInBits());
}
}
@@ -3241,4 +3251,16 @@ namespace llvm {
}
}
+bool LoopVectorizationCostModel::isConsecutiveLoadOrStore(Instruction *Inst) {
+ // Check for a store.
+ StoreInst *ST = dyn_cast<StoreInst>(Inst);
+ if (ST)
+ return Legal->isConsecutivePtr(ST->getPointerOperand()) != 0;
+ // Check for a load.
+ LoadInst *LI = dyn_cast<LoadInst>(Inst);
+ if (LI)
+ return Legal->isConsecutivePtr(LI->getPointerOperand()) != 0;
+
+ return false;
+}