diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
commit | d9484dd61cc151c4f34c31e07f693fefa66316b5 (patch) | |
tree | ab0560b3da293f1fafd3269c59692e929418f5c2 /contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp | |
parent | 79e0962d4c3cf1f0acf359a9d69cb3ac68c414c4 (diff) | |
parent | d8e91e46262bc44006913e6796843909f1ac7bcd (diff) |
Notes
Diffstat (limited to 'contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp | 108 |
1 files changed, 64 insertions, 44 deletions
diff --git a/contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp index 5f3d127202ad..9ff18328c219 100644 --- a/contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ b/contrib/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -79,6 +79,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Vectorize.h" +#include "llvm/Transforms/Vectorize/LoadStoreVectorizer.h" #include <algorithm> #include <cassert> #include <cstdlib> @@ -205,12 +206,12 @@ private: unsigned Alignment); }; -class LoadStoreVectorizer : public FunctionPass { +class LoadStoreVectorizerLegacyPass : public FunctionPass { public: static char ID; - LoadStoreVectorizer() : FunctionPass(ID) { - initializeLoadStoreVectorizerPass(*PassRegistry::getPassRegistry()); + LoadStoreVectorizerLegacyPass() : FunctionPass(ID) { + initializeLoadStoreVectorizerLegacyPassPass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override; @@ -230,30 +231,23 @@ public: } // end anonymous namespace -char LoadStoreVectorizer::ID = 0; +char LoadStoreVectorizerLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(LoadStoreVectorizer, DEBUG_TYPE, +INITIALIZE_PASS_BEGIN(LoadStoreVectorizerLegacyPass, DEBUG_TYPE, "Vectorize load and Store instructions", false, false) INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) -INITIALIZE_PASS_END(LoadStoreVectorizer, DEBUG_TYPE, +INITIALIZE_PASS_END(LoadStoreVectorizerLegacyPass, DEBUG_TYPE, "Vectorize load and store instructions", false, false) Pass *llvm::createLoadStoreVectorizerPass() { - return new LoadStoreVectorizer(); + return new LoadStoreVectorizerLegacyPass(); } -// The real propagateMetadata expects a SmallVector<Value*>, but we deal in -// vectors of Instructions. -static void propagateMetadata(Instruction *I, ArrayRef<Instruction *> IL) { - SmallVector<Value *, 8> VL(IL.begin(), IL.end()); - propagateMetadata(I, VL); -} - -bool LoadStoreVectorizer::runOnFunction(Function &F) { +bool LoadStoreVectorizerLegacyPass::runOnFunction(Function &F) { // Don't vectorize when the attribute NoImplicitFloat is used. if (skipFunction(F) || F.hasFnAttribute(Attribute::NoImplicitFloat)) return false; @@ -268,6 +262,30 @@ bool LoadStoreVectorizer::runOnFunction(Function &F) { return V.run(); } +PreservedAnalyses LoadStoreVectorizerPass::run(Function &F, FunctionAnalysisManager &AM) { + // Don't vectorize when the attribute NoImplicitFloat is used. + if (F.hasFnAttribute(Attribute::NoImplicitFloat)) + return PreservedAnalyses::all(); + + AliasAnalysis &AA = AM.getResult<AAManager>(F); + DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); + ScalarEvolution &SE = AM.getResult<ScalarEvolutionAnalysis>(F); + TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F); + + Vectorizer V(F, AA, DT, SE, TTI); + bool Changed = V.run(); + PreservedAnalyses PA; + PA.preserveSet<CFGAnalyses>(); + return Changed ? PA : PreservedAnalyses::all(); +} + +// The real propagateMetadata expects a SmallVector<Value*>, but we deal in +// vectors of Instructions. +static void propagateMetadata(Instruction *I, ArrayRef<Instruction *> IL) { + SmallVector<Value *, 8> VL(IL.begin(), IL.end()); + propagateMetadata(I, VL); +} + // Vectorizer Implementation bool Vectorizer::run() { bool Changed = false; @@ -954,11 +972,6 @@ bool Vectorizer::vectorizeStoreChain( // try again. unsigned EltSzInBytes = Sz / 8; unsigned SzInBytes = EltSzInBytes * ChainSize; - if (!TTI.isLegalToVectorizeStoreChain(SzInBytes, Alignment, AS)) { - auto Chains = splitOddVectorElts(Chain, Sz); - return vectorizeStoreChain(Chains.first, InstructionsProcessed) | - vectorizeStoreChain(Chains.second, InstructionsProcessed); - } VectorType *VecTy; VectorType *VecStoreTy = dyn_cast<VectorType>(StoreTy); @@ -991,14 +1004,23 @@ bool Vectorizer::vectorizeStoreChain( // If the store is going to be misaligned, don't vectorize it. if (accessIsMisaligned(SzInBytes, AS, Alignment)) { - if (S0->getPointerAddressSpace() != 0) - return false; + if (S0->getPointerAddressSpace() != DL.getAllocaAddrSpace()) { + auto Chains = splitOddVectorElts(Chain, Sz); + return vectorizeStoreChain(Chains.first, InstructionsProcessed) | + vectorizeStoreChain(Chains.second, InstructionsProcessed); + } unsigned NewAlign = getOrEnforceKnownAlignment(S0->getPointerOperand(), StackAdjustedAlignment, DL, S0, nullptr, &DT); - if (NewAlign < StackAdjustedAlignment) - return false; + if (NewAlign != 0) + Alignment = NewAlign; + } + + if (!TTI.isLegalToVectorizeStoreChain(SzInBytes, Alignment, AS)) { + auto Chains = splitOddVectorElts(Chain, Sz); + return vectorizeStoreChain(Chains.first, InstructionsProcessed) | + vectorizeStoreChain(Chains.second, InstructionsProcessed); } BasicBlock::iterator First, Last; @@ -1037,13 +1059,11 @@ bool Vectorizer::vectorizeStoreChain( } } - // This cast is safe because Builder.CreateStore() always creates a bona fide - // StoreInst. - StoreInst *SI = cast<StoreInst>( - Builder.CreateStore(Vec, Builder.CreateBitCast(S0->getPointerOperand(), - VecTy->getPointerTo(AS)))); + StoreInst *SI = Builder.CreateAlignedStore( + Vec, + Builder.CreateBitCast(S0->getPointerOperand(), VecTy->getPointerTo(AS)), + Alignment); propagateMetadata(SI, Chain); - SI->setAlignment(Alignment); eraseInstructions(Chain); ++NumVectorInstructions; @@ -1102,12 +1122,6 @@ bool Vectorizer::vectorizeLoadChain( // try again. unsigned EltSzInBytes = Sz / 8; unsigned SzInBytes = EltSzInBytes * ChainSize; - if (!TTI.isLegalToVectorizeLoadChain(SzInBytes, Alignment, AS)) { - auto Chains = splitOddVectorElts(Chain, Sz); - return vectorizeLoadChain(Chains.first, InstructionsProcessed) | - vectorizeLoadChain(Chains.second, InstructionsProcessed); - } - VectorType *VecTy; VectorType *VecLoadTy = dyn_cast<VectorType>(LoadTy); if (VecLoadTy) @@ -1132,18 +1146,27 @@ bool Vectorizer::vectorizeLoadChain( // If the load is going to be misaligned, don't vectorize it. if (accessIsMisaligned(SzInBytes, AS, Alignment)) { - if (L0->getPointerAddressSpace() != 0) - return false; + if (L0->getPointerAddressSpace() != DL.getAllocaAddrSpace()) { + auto Chains = splitOddVectorElts(Chain, Sz); + return vectorizeLoadChain(Chains.first, InstructionsProcessed) | + vectorizeLoadChain(Chains.second, InstructionsProcessed); + } unsigned NewAlign = getOrEnforceKnownAlignment(L0->getPointerOperand(), StackAdjustedAlignment, DL, L0, nullptr, &DT); - if (NewAlign < StackAdjustedAlignment) - return false; + if (NewAlign != 0) + Alignment = NewAlign; Alignment = NewAlign; } + if (!TTI.isLegalToVectorizeLoadChain(SzInBytes, Alignment, AS)) { + auto Chains = splitOddVectorElts(Chain, Sz); + return vectorizeLoadChain(Chains.first, InstructionsProcessed) | + vectorizeLoadChain(Chains.second, InstructionsProcessed); + } + LLVM_DEBUG({ dbgs() << "LSV: Loads to vectorize:\n"; for (Instruction *I : Chain) @@ -1159,11 +1182,8 @@ bool Vectorizer::vectorizeLoadChain( Value *Bitcast = Builder.CreateBitCast(L0->getPointerOperand(), VecTy->getPointerTo(AS)); - // This cast is safe because Builder.CreateLoad always creates a bona fide - // LoadInst. - LoadInst *LI = cast<LoadInst>(Builder.CreateLoad(Bitcast)); + LoadInst *LI = Builder.CreateAlignedLoad(Bitcast, Alignment); propagateMetadata(LI, Chain); - LI->setAlignment(Alignment); if (VecLoadTy) { SmallVector<Instruction *, 16> InstrsToErase; |