diff options
author | Philip Reames <listmail@philipreames.com> | 2019-09-10 21:33:53 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2019-09-10 21:33:53 +0000 |
commit | cffa630c809f07f38334b8e5e03f8126387f997b (patch) | |
tree | 805a814954eb270a1a209a7265649997d9cd62ca /llvm/lib/Analysis/Loads.cpp | |
parent | 045b2270ceba0ad785cf27beb05dd59ce10372f6 (diff) | |
download | bcm5719-llvm-cffa630c809f07f38334b8e5e03f8126387f997b.tar.gz bcm5719-llvm-cffa630c809f07f38334b8e5e03f8126387f997b.zip |
[Loads] Move generic code out of vectorizer into a location it might be reused [NFC]
llvm-svn: 371558
Diffstat (limited to 'llvm/lib/Analysis/Loads.cpp')
-rw-r--r-- | llvm/lib/Analysis/Loads.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp index e74df9c69d7..ea98ca915c6 100644 --- a/llvm/lib/Analysis/Loads.cpp +++ b/llvm/lib/Analysis/Loads.cpp @@ -12,6 +12,9 @@ #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalAlias.h" @@ -190,6 +193,53 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) { return false; } +bool llvm::isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, + ScalarEvolution &SE, + DominatorTree &DT) { + auto &DL = LI->getModule()->getDataLayout(); + Value *Ptr = LI->getPointerOperand(); + auto *AddRec = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(Ptr)); + if (!AddRec || AddRec->getLoop() != L || !AddRec->isAffine()) + return false; + auto* Step = dyn_cast<SCEVConstant>(AddRec->getStepRecurrence(SE)); + if (!Step) + return false; + APInt StepC = Step->getAPInt(); + APInt EltSize(DL.getIndexTypeSizeInBits(Ptr->getType()), + DL.getTypeStoreSize(LI->getType())); + // TODO: generalize to access patterns which have gaps + // TODO: handle uniform addresses (if not already handled by LICM) + if (StepC != EltSize) + return false; + + // TODO: If the symbolic trip count has a small bound (max count), we might + // be able to prove safety. + auto TC = SE.getSmallConstantTripCount(L); + if (!TC) + return false; + + const APInt AccessSize = TC * EltSize; + + auto *StartS = dyn_cast<SCEVUnknown>(AddRec->getStart()); + if (!StartS) + return false; + assert(SE.isLoopInvariant(StartS, L) && "implied by addrec definition"); + Value *Base = StartS->getValue(); + + Instruction *HeaderFirstNonPHI = L->getHeader()->getFirstNonPHI(); + + unsigned Align = LI->getAlignment(); + if (Align == 0) + Align = DL.getABITypeAlignment(LI->getType()); + // For the moment, restrict ourselves to the case where the access size is a + // multiple of the requested alignment and the base is aligned. + // TODO: generalize if a case found which warrants + if (EltSize.urem(Align) != 0) + return false; + return isDereferenceableAndAlignedPointer(Base, Align, AccessSize, + DL, HeaderFirstNonPHI, &DT); +} + /// Check if executing a load of this pointer value cannot trap. /// /// If DT and ScanFrom are specified this method performs context-sensitive |