diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -998,6 +998,18 @@ SmallVectorImpl &Subscripts, SmallVectorImpl &Sizes); + /// 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 as SCEV as well as a list of integers describing + /// the size of the individual array dimensions. 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. + void getIndexExpressionsFromGEP(const GetElementPtrInst *GEP, + SmallVectorImpl &Subscripts, + SmallVectorImpl &Sizes); + /// Split this SCEVAddRecExpr into two vectors of SCEVs representing the /// subscripts and sizes of an array access. /// diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3308,50 +3308,6 @@ return true; } -static void -getIndexExpressionsFromGEP(const GetElementPtrInst *GEP, - SmallVectorImpl &Subscripts, - SmallVectorImpl &Sizes, ScalarEvolution &SE) { - assert(GEP && "getIndexExpressionsFromGEP called with a null GEP"); - Type *Ty = GEP->getPointerOperandType(); - bool DroppedFirstDim = false; - for (unsigned i = 1; i < GEP->getNumOperands(); i++) { - const SCEV *Expr = SE.getSCEV(GEP->getOperand(i)); - if (i == 1) { - if (auto *PtrTy = dyn_cast(Ty)) { - Ty = PtrTy->getElementType(); - } else if (auto *ArrayTy = dyn_cast(Ty)) { - Ty = ArrayTy->getElementType(); - } else { - Subscripts.clear(); - Sizes.clear(); - break; - } - 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(); - break; - } - - Subscripts.push_back(Expr); - if (!(DroppedFirstDim && i == 2)) - Sizes.push_back(ArrayTy->getNumElements()); - - Ty = ArrayTy->getElementType(); - } - return; -} - bool DependenceInfo::tryDelinearizeFixedSize( Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn, const SCEV *DstAccessFn, SmallVectorImpl &SrcSubscripts, @@ -3376,8 +3332,8 @@ return false; SmallVector SrcSizes, DstSizes; - getIndexExpressionsFromGEP(SrcGEP, SrcSubscripts, SrcSizes, *SE); - getIndexExpressionsFromGEP(DstGEP, DstSubscripts, DstSizes, *SE); + SE->getIndexExpressionsFromGEP(SrcGEP, SrcSubscripts, SrcSizes); + SE->getIndexExpressionsFromGEP(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 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -11409,6 +11409,49 @@ }); } +void ScalarEvolution::getIndexExpressionsFromGEP( + const GetElementPtrInst *GEP, SmallVectorImpl &Subscripts, + SmallVectorImpl &Sizes) { + assert(GEP && "getIndexExpressionsFromGEP called with a null GEP"); + Type *Ty = GEP->getPointerOperandType(); + bool DroppedFirstDim = false; + for (unsigned i = 1; i < GEP->getNumOperands(); i++) { + const SCEV *Expr = getSCEV(GEP->getOperand(i)); + if (i == 1) { + if (auto *PtrTy = dyn_cast(Ty)) { + Ty = PtrTy->getElementType(); + } else if (auto *ArrayTy = dyn_cast(Ty)) { + Ty = ArrayTy->getElementType(); + } else { + Subscripts.clear(); + Sizes.clear(); + break; + } + 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(); + break; + } + + Subscripts.push_back(Expr); + if (!(DroppedFirstDim && i == 2)) + Sizes.push_back(ArrayTy->getNumElements()); + + Ty = ArrayTy->getElementType(); + } + return; +} + //===----------------------------------------------------------------------===// // SCEVCallbackVH Class Implementation //===----------------------------------------------------------------------===// diff --git a/polly/include/polly/Support/ScopHelper.h b/polly/include/polly/Support/ScopHelper.h --- a/polly/include/polly/Support/ScopHelper.h +++ b/polly/include/polly/Support/ScopHelper.h @@ -502,22 +502,6 @@ /// case this function returns nullptr. llvm::BasicBlock *getUseBlock(const llvm::Use &U); -/// Derive 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 as SCEV as well as a list of integers describing -/// the size of the individual array dimensions. 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. -/// -/// @param GEP The GetElementPtr instruction to analyze. -/// -/// @return A tuple with the subscript expressions and the dimension sizes. -std::tuple, std::vector> -getIndexExpressionsFromGEP(llvm::GetElementPtrInst *GEP, - llvm::ScalarEvolution &SE); - // If the loop is nonaffine/boxed, return the first non-boxed surrounding loop // for Polly. If the loop is affine, return the loop itself. // diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp --- a/polly/lib/Analysis/ScopBuilder.cpp +++ b/polly/lib/Analysis/ScopBuilder.cpp @@ -1629,9 +1629,9 @@ if (!GEP) return false; - std::vector Subscripts; - std::vector Sizes; - std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP, SE); + SmallVector Subscripts; + SmallVector Sizes; + SE.getIndexExpressionsFromGEP(GEP, Subscripts, Sizes); auto *BasePtr = GEP->getOperand(0); if (auto *BasePtrCast = dyn_cast(BasePtr)) diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -668,55 +668,6 @@ return UI->getParent(); } -std::tuple, std::vector> -polly::getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) { - std::vector Subscripts; - std::vector Sizes; - - Type *Ty = GEP->getPointerOperandType(); - - bool DroppedFirstDim = false; - - for (unsigned i = 1; i < GEP->getNumOperands(); i++) { - - const SCEV *Expr = SE.getSCEV(GEP->getOperand(i)); - - if (i == 1) { - if (auto *PtrTy = dyn_cast(Ty)) { - Ty = PtrTy->getElementType(); - } else if (auto *ArrayTy = dyn_cast(Ty)) { - Ty = ArrayTy->getElementType(); - } else { - Subscripts.clear(); - Sizes.clear(); - break; - } - 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(); - break; - } - - Subscripts.push_back(Expr); - if (!(DroppedFirstDim && i == 2)) - Sizes.push_back(ArrayTy->getNumElements()); - - Ty = ArrayTy->getElementType(); - } - - return std::make_tuple(Subscripts, Sizes); -} - llvm::Loop *polly::getFirstNonBoxedLoopFor(llvm::Loop *L, llvm::LoopInfo &LI, const BoxedLoopsSetTy &BoxedLoops) { while (BoxedLoops.count(L))