SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &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 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<const SCEV *> &Subscripts,
+ SmallVectorImpl<int> &Sizes);
+
/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
/// subscripts and sizes of an array access.
///
});
}
+bool ScalarEvolution::getIndexExpressionsFromGEP(
+ const GetElementPtrInst *GEP, SmallVectorImpl<const SCEV *> &Subscripts,
+ SmallVectorImpl<int> &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 = 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<PointerType>(Ty)) {
+ Ty = PtrTy->getElementType();
+ } else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
+ Ty = ArrayTy->getElementType();
+ } else {
+ Subscripts.clear();
+ Sizes.clear();
+ return false;
+ }
+ if (auto *Const = dyn_cast<SCEVConstant>(Expr))
+ if (Const->getValue()->isZero()) {
+ DroppedFirstDim = true;
+ continue;
+ }
+ Subscripts.push_back(Expr);
+ continue;
+ }
+
+ auto *ArrayTy = dyn_cast<ArrayType>(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
//===----------------------------------------------------------------------===//
/// 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<const llvm::SCEV *>, std::vector<int>>
-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.
//
if (!GEP)
return false;
- std::vector<const SCEV *> Subscripts;
- std::vector<int> Sizes;
- std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP, SE);
+ SmallVector<const SCEV *, 4> Subscripts;
+ SmallVector<int, 4> Sizes;
+ SE.getIndexExpressionsFromGEP(GEP, Subscripts, Sizes);
auto *BasePtr = GEP->getOperand(0);
if (auto *BasePtrCast = dyn_cast<BitCastInst>(BasePtr))
return UI->getParent();
}
-std::tuple<std::vector<const SCEV *>, std::vector<int>>
-polly::getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) {
- std::vector<const SCEV *> Subscripts;
- std::vector<int> 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<PointerType>(Ty)) {
- Ty = PtrTy->getElementType();
- } else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
- Ty = ArrayTy->getElementType();
- } else {
- Subscripts.clear();
- Sizes.clear();
- break;
- }
- if (auto *Const = dyn_cast<SCEVConstant>(Expr))
- if (Const->getValue()->isZero()) {
- DroppedFirstDim = true;
- continue;
- }
- Subscripts.push_back(Expr);
- continue;
- }
-
- auto *ArrayTy = dyn_cast<ArrayType>(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))