diff options
Diffstat (limited to 'polly/lib/Support/ScopHelper.cpp')
| -rw-r--r-- | polly/lib/Support/ScopHelper.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp index c97eedffcf1..9e94b9f5740 100644 --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -490,3 +490,52 @@ llvm::BasicBlock *polly::getUseBlock(llvm::Use &U) { 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); +} |

