diff options
author | Arnold Schwaighofer <aschwaighofer@apple.com> | 2013-02-05 15:08:02 +0000 |
---|---|---|
committer | Arnold Schwaighofer <aschwaighofer@apple.com> | 2013-02-05 15:08:02 +0000 |
commit | 935645b7655a0b5189d40b3d65b3bcb14e30d859 (patch) | |
tree | de502da9e44f1930cd496e6e0667ab1bbb340d2a /lib/Transforms/Vectorize | |
parent | b9e1a33941d25faf54dc3ddec4be7f8f0750a155 (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')
-rw-r--r-- | lib/Transforms/Vectorize/LoopVectorize.cpp | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 1b242c93ba..62542737de 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; +} |