@@ -11409,6 +11409,51 @@ void ScalarEvolution::delinearize(const SCEV *Expr,
1140911409 });
1141011410}
1141111411
11412+ bool ScalarEvolution::getIndexExpressionsFromGEP (
11413+ const GetElementPtrInst *GEP, SmallVectorImpl<const SCEV *> &Subscripts,
11414+ SmallVectorImpl<int > &Sizes) {
11415+ assert (Subscripts.empty () && Sizes.empty () &&
11416+ " Expected output lists to be empty on entry to this function." );
11417+ assert (GEP && " getIndexExpressionsFromGEP called with a null GEP" );
11418+ Type *Ty = GEP->getPointerOperandType ();
11419+ bool DroppedFirstDim = false ;
11420+ for (unsigned i = 1 ; i < GEP->getNumOperands (); i++) {
11421+ const SCEV *Expr = getSCEV (GEP->getOperand (i));
11422+ if (i == 1 ) {
11423+ if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
11424+ Ty = PtrTy->getElementType ();
11425+ } else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
11426+ Ty = ArrayTy->getElementType ();
11427+ } else {
11428+ Subscripts.clear ();
11429+ Sizes.clear ();
11430+ return false ;
11431+ }
11432+ if (auto *Const = dyn_cast<SCEVConstant>(Expr))
11433+ if (Const->getValue ()->isZero ()) {
11434+ DroppedFirstDim = true ;
11435+ continue ;
11436+ }
11437+ Subscripts.push_back (Expr);
11438+ continue ;
11439+ }
11440+
11441+ auto *ArrayTy = dyn_cast<ArrayType>(Ty);
11442+ if (!ArrayTy) {
11443+ Subscripts.clear ();
11444+ Sizes.clear ();
11445+ return false ;
11446+ }
11447+
11448+ Subscripts.push_back (Expr);
11449+ if (!(DroppedFirstDim && i == 2 ))
11450+ Sizes.push_back (ArrayTy->getNumElements ());
11451+
11452+ Ty = ArrayTy->getElementType ();
11453+ }
11454+ return !Subscripts.empty ();
11455+ }
11456+
1141211457// ===----------------------------------------------------------------------===//
1141311458// SCEVCallbackVH Class Implementation
1141411459// ===----------------------------------------------------------------------===//
0 commit comments