diff options
author | Matthew Simpson <mssimpso@codeaurora.org> | 2016-07-14 20:59:47 +0000 |
---|---|---|
committer | Matthew Simpson <mssimpso@codeaurora.org> | 2016-07-14 20:59:47 +0000 |
commit | 65ca32b83ce9b69e590196d2feb331b4dcfabfef (patch) | |
tree | b723e775f0ed8e5b5c5efb20de336a4e5de9a7d6 /llvm/lib | |
parent | bbbb3ce7874f4128b57552537855206a26cd88b6 (diff) | |
download | bcm5719-llvm-65ca32b83ce9b69e590196d2feb331b4dcfabfef.tar.gz bcm5719-llvm-65ca32b83ce9b69e590196d2feb331b4dcfabfef.zip |
[LV] Allow interleaved accesses in loops with predicated blocks
This patch allows the formation of interleaved access groups in loops
containing predicated blocks. However, the predicated accesses are prevented
from forming groups.
Differential Revision: https://reviews.llvm.org/D19694
llvm-svn: 275471
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 64 |
1 files changed, 30 insertions, 34 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 13589418706..2a2c6409d67 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -947,6 +947,11 @@ private: return Factor >= 2 && Factor <= MaxInterleaveGroupFactor; } + /// \brief Returns true if \p BB is a predicated block. + bool isPredicated(BasicBlock *BB) const { + return LoopAccessInfo::blockNeedsPredication(BB, TheLoop, DT); + } + /// \brief Returns true if LoopAccessInfo can be used for dependence queries. bool areDependencesValid() const { return LAI && LAI->getDepChecker().getDependences(); @@ -4925,53 +4930,38 @@ bool LoopVectorizationLegality::blockCanBePredicated( void InterleavedAccessInfo::collectConstStridedAccesses( MapVector<Instruction *, StrideDescriptor> &StrideAccesses, const ValueToValueMap &Strides) { - // Holds load/store instructions in program order. - SmallVector<Instruction *, 16> AccessList; + + auto &DL = TheLoop->getHeader()->getModule()->getDataLayout(); // Since it's desired that the load/store instructions be maintained in // "program order" for the interleaved access analysis, we have to visit the // blocks in the loop in reverse postorder (i.e., in a topological order). // Such an ordering will ensure that any load/store that may be executed - // before a second load/store will precede the second load/store in the - // AccessList. + // before a second load/store will precede the second load/store in + // StrideAccesses. LoopBlocksDFS DFS(TheLoop); DFS.perform(LI); - for (BasicBlock *BB : make_range(DFS.beginRPO(), DFS.endRPO())) { - bool IsPred = LoopAccessInfo::blockNeedsPredication(BB, TheLoop, DT); - + for (BasicBlock *BB : make_range(DFS.beginRPO(), DFS.endRPO())) for (auto &I : *BB) { - if (!isa<LoadInst>(&I) && !isa<StoreInst>(&I)) + auto *LI = dyn_cast<LoadInst>(&I); + auto *SI = dyn_cast<StoreInst>(&I); + if (!LI && !SI) continue; - // FIXME: Currently we can't handle mixed accesses and predicated accesses - if (IsPred) - return; - - AccessList.push_back(&I); - } - } - - if (AccessList.empty()) - return; - - auto &DL = TheLoop->getHeader()->getModule()->getDataLayout(); - for (auto I : AccessList) { - auto *LI = dyn_cast<LoadInst>(I); - auto *SI = dyn_cast<StoreInst>(I); - Value *Ptr = LI ? LI->getPointerOperand() : SI->getPointerOperand(); - int64_t Stride = getPtrStride(PSE, Ptr, TheLoop, Strides); + Value *Ptr = LI ? LI->getPointerOperand() : SI->getPointerOperand(); + int64_t Stride = getPtrStride(PSE, Ptr, TheLoop, Strides); - const SCEV *Scev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr); - PointerType *PtrTy = dyn_cast<PointerType>(Ptr->getType()); - uint64_t Size = DL.getTypeAllocSize(PtrTy->getElementType()); + const SCEV *Scev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr); + PointerType *PtrTy = dyn_cast<PointerType>(Ptr->getType()); + uint64_t Size = DL.getTypeAllocSize(PtrTy->getElementType()); - // An alignment of 0 means target ABI alignment. - unsigned Align = LI ? LI->getAlignment() : SI->getAlignment(); - if (!Align) - Align = DL.getABITypeAlignment(PtrTy->getElementType()); + // An alignment of 0 means target ABI alignment. + unsigned Align = LI ? LI->getAlignment() : SI->getAlignment(); + if (!Align) + Align = DL.getABITypeAlignment(PtrTy->getElementType()); - StrideAccesses[I] = StrideDescriptor(Stride, Scev, Size, Align); - } + StrideAccesses[&I] = StrideDescriptor(Stride, Scev, Size, Align); + } } // Analyze interleaved accesses and collect them into interleaved load and @@ -5125,6 +5115,12 @@ void InterleavedAccessInfo::analyzeInterleaving( if (DistanceToA % static_cast<int64_t>(DesA.Size)) continue; + // If either A or B is in a predicated block, we prevent adding them to a + // group. We may be able to relax this limitation in the future once we + // handle more complicated blocks. + if (isPredicated(A->getParent()) || isPredicated(B->getParent())) + continue; + // The index of B is the index of A plus the related index to A. int IndexB = Group->getIndex(A) + DistanceToA / static_cast<int64_t>(DesA.Size); |