diff --git a/llvm/include/llvm/Analysis/Delinearization.h b/llvm/include/llvm/Analysis/Delinearization.h index dec3fd9b08a9f8..6e942530f25324 100644 --- a/llvm/include/llvm/Analysis/Delinearization.h +++ b/llvm/include/llvm/Analysis/Delinearization.h @@ -21,6 +21,7 @@ #include "llvm/Support/raw_ostream.h" namespace llvm { +class GetElementPtrInst; class ScalarEvolution; class SCEV; @@ -110,6 +111,20 @@ void delinearize(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl &Subscripts, SmallVectorImpl &Sizes, const SCEV *ElementSize); +/// Gathers the individual index expressions from a GEP instruction. +/// +/// This function optimistically assumes the GEP references into a fixed size +/// array. If this is actually true, this function returns a list of array +/// subscript expressions in \p Subscripts and a list of integers describing +/// the size of the individual array dimensions in \p Sizes. Both lists have +/// either equal length or the size list is one element shorter in case there +/// is no known size available for the outermost array dimension. Returns true +/// if successful and false otherwise. +bool getIndexExpressionsFromGEP(ScalarEvolution &SE, + const GetElementPtrInst *GEP, + SmallVectorImpl &Subscripts, + SmallVectorImpl &Sizes); + struct DelinearizationPrinterPass : public PassInfoMixin { explicit DelinearizationPrinterPass(raw_ostream &OS); diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index d7314bb8ed17ca..098a076536f6d0 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1104,19 +1104,6 @@ class ScalarEvolution { bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv); - /// Gathers the individual index expressions from a GEP instruction. - /// - /// This function optimistically assumes the GEP references into a fixed size - /// array. If this is actually true, this function returns a list of array - /// subscript expressions in \p Subscripts and a list of integers describing - /// the size of the individual array dimensions in \p Sizes. Both lists have - /// either equal length or the size list is one element shorter in case there - /// is no known size available for the outermost array dimension. Returns true - /// if successful and false otherwise. - bool getIndexExpressionsFromGEP(const GetElementPtrInst *GEP, - SmallVectorImpl &Subscripts, - SmallVectorImpl &Sizes); - /// Return the DataLayout associated with the module this SCEV instance is /// operating on. const DataLayout &getDataLayout() const { diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp index de490ba7ec6e23..670532c6d9a85f 100644 --- a/llvm/lib/Analysis/Delinearization.cpp +++ b/llvm/lib/Analysis/Delinearization.cpp @@ -485,6 +485,44 @@ void llvm::delinearize(ScalarEvolution &SE, const SCEV *Expr, }); } +bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE, + const GetElementPtrInst *GEP, + SmallVectorImpl &Subscripts, + SmallVectorImpl &Sizes) { + assert(Subscripts.empty() && Sizes.empty() && + "Expected output lists to be empty on entry to this function."); + assert(GEP && "getIndexExpressionsFromGEP called with a null GEP"); + Type *Ty = nullptr; + bool DroppedFirstDim = false; + for (unsigned i = 1; i < GEP->getNumOperands(); i++) { + const SCEV *Expr = SE.getSCEV(GEP->getOperand(i)); + if (i == 1) { + Ty = GEP->getSourceElementType(); + if (auto *Const = dyn_cast(Expr)) + if (Const->getValue()->isZero()) { + DroppedFirstDim = true; + continue; + } + Subscripts.push_back(Expr); + continue; + } + + auto *ArrayTy = dyn_cast(Ty); + if (!ArrayTy) { + Subscripts.clear(); + Sizes.clear(); + return false; + } + + Subscripts.push_back(Expr); + if (!(DroppedFirstDim && i == 2)) + Sizes.push_back(ArrayTy->getNumElements()); + + Ty = ArrayTy->getElementType(); + } + return !Subscripts.empty(); +} + namespace { class Delinearization : public FunctionPass { diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index fa9c6721194550..ff18820953fc4d 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3339,8 +3339,8 @@ bool DependenceInfo::tryDelinearizeFixedSize( return false; SmallVector SrcSizes, DstSizes; - SE->getIndexExpressionsFromGEP(SrcGEP, SrcSubscripts, SrcSizes); - SE->getIndexExpressionsFromGEP(DstGEP, DstSubscripts, DstSizes); + getIndexExpressionsFromGEP(*SE, SrcGEP, SrcSubscripts, SrcSizes); + getIndexExpressionsFromGEP(*SE, DstGEP, DstSubscripts, DstSizes); // Check that the two size arrays are non-empty and equal in length and // value. diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index e9e83918dcbdd1..9d93fbe034d9ef 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -12201,43 +12201,6 @@ const SCEV *ScalarEvolution::getElementSize(Instruction *Inst) { return getSizeOfExpr(ETy, Ty); } -bool ScalarEvolution::getIndexExpressionsFromGEP( - const GetElementPtrInst *GEP, SmallVectorImpl &Subscripts, - SmallVectorImpl &Sizes) { - assert(Subscripts.empty() && Sizes.empty() && - "Expected output lists to be empty on entry to this function."); - assert(GEP && "getIndexExpressionsFromGEP called with a null GEP"); - Type *Ty = nullptr; - bool DroppedFirstDim = false; - for (unsigned i = 1; i < GEP->getNumOperands(); i++) { - const SCEV *Expr = getSCEV(GEP->getOperand(i)); - if (i == 1) { - Ty = GEP->getSourceElementType(); - if (auto *Const = dyn_cast(Expr)) - if (Const->getValue()->isZero()) { - DroppedFirstDim = true; - continue; - } - Subscripts.push_back(Expr); - continue; - } - - auto *ArrayTy = dyn_cast(Ty); - if (!ArrayTy) { - Subscripts.clear(); - Sizes.clear(); - return false; - } - - Subscripts.push_back(Expr); - if (!(DroppedFirstDim && i == 2)) - Sizes.push_back(ArrayTy->getNumElements()); - - Ty = ArrayTy->getElementType(); - } - return !Subscripts.empty(); -} - //===----------------------------------------------------------------------===// // SCEVCallbackVH Class Implementation //===----------------------------------------------------------------------===//