diff options
Diffstat (limited to 'llvm/lib/Analysis/Delinearization.cpp')
| -rw-r--r-- | llvm/lib/Analysis/Delinearization.cpp | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp index 670532c6d9a8..c36e1d922915 100644 --- a/llvm/lib/Analysis/Delinearization.cpp +++ b/llvm/lib/Analysis/Delinearization.cpp @@ -24,9 +24,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/LLVMContext.h" #include "llvm/IR/PassManager.h" -#include "llvm/IR/Type.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" @@ -523,6 +521,44 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE, return !Subscripts.empty(); } +bool llvm::tryDelinearizeFixedSizeImpl( + ScalarEvolution *SE, Instruction *Inst, const SCEV *AccessFn, + SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<int> &Sizes) { + Value *SrcPtr = getLoadStorePointerOperand(Inst); + + // Check the simple case where the array dimensions are fixed size. + auto *SrcGEP = dyn_cast<GetElementPtrInst>(SrcPtr); + if (!SrcGEP) + return false; + + getIndexExpressionsFromGEP(*SE, SrcGEP, Subscripts, Sizes); + + // Check that the two size arrays are non-empty and equal in length and + // value. + // TODO: it would be better to let the caller to clear Subscripts, similar + // to how we handle Sizes. + if (Sizes.empty() || Subscripts.size() <= 1) { + Subscripts.clear(); + return false; + } + + // Check that for identical base pointers we do not miss index offsets + // that have been added before this GEP is applied. + Value *SrcBasePtr = SrcGEP->getOperand(0)->stripPointerCasts(); + const SCEVUnknown *SrcBase = + dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFn)); + if (!SrcBase || SrcBasePtr != SrcBase->getValue()) { + Subscripts.clear(); + return false; + } + + assert(Subscripts.size() == Sizes.size() + 1 && + "Expected equal number of entries in the list of size and " + "subscript."); + + return true; +} + namespace { class Delinearization : public FunctionPass { |
