summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
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
commit22174f5d5af1eb15b376c6d49e7925cbb7cca6be (patch)
tree694bbab472d3d60f6f96496e7697587ab826b497 /llvm/lib/Transforms
parent36017454ac374449570e685aee5d697ee7d3f8de (diff)
downloadbcm5719-llvm-22174f5d5af1eb15b376c6d49e7925cbb7cca6be.tar.gz
bcm5719-llvm-22174f5d5af1eb15b376c6d49e7925cbb7cca6be.zip
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 llvm-svn: 174377
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorize.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 1b242c93ba1..62542737de0 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/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;
+}
OpenPOWER on IntegriCloud