From 935645b7655a0b5189d40b3d65b3bcb14e30d859 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 5 Feb 2013 15:08:02 +0000 Subject: 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 --- lib/Transforms/Vectorize/LoopVectorize.cpp | 40 +++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'lib/Transforms/Vectorize/LoopVectorize.cpp') 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(it)) + StoreInst *ST = 0; + if ((ST = dyn_cast(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(Inst); + if (ST) + return Legal->isConsecutivePtr(ST->getPointerOperand()) != 0; + // Check for a load. + LoadInst *LI = dyn_cast(Inst); + if (LI) + return Legal->isConsecutivePtr(LI->getPointerOperand()) != 0; + + return false; +} -- cgit v1.2.3-18-g5258