[polly] r247893 - Extract function that derives the index expressions of a GEP instruction [NFC]
Tobias Grosser via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 17 08:47:52 PDT 2015
Author: grosser
Date: Thu Sep 17 10:47:52 2015
New Revision: 247893
URL: http://llvm.org/viewvc/llvm-project?rev=247893&view=rev
Log:
Extract function that derives the index expressions of a GEP instruction [NFC]
We currently use this functionality to add run-time assumptions that check its
in-bound property.
Modified:
polly/trunk/include/polly/ScopInfo.h
polly/trunk/lib/Analysis/ScopInfo.cpp
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=247893&r1=247892&r2=247893&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Thu Sep 17 10:47:52 2015
@@ -679,6 +679,21 @@ private:
llvm::SmallVectorImpl<MemoryAccess *> &Loads);
//@}
+ /// @brief 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 of 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 SCEV *>, std::vector<int>>
+ getIndexExpressionsFromGEP(GetElementPtrInst *GEP);
+
/// @brief Derive assumptions about parameter values from GetElementPtrInst
///
/// In case a GEP instruction references into a fixed size array e.g., an
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=247893&r1=247892&r2=247893&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Thu Sep 17 10:47:52 2015
@@ -921,6 +921,51 @@ void ScopStmt::buildDomain() {
Domain = isl_set_set_tuple_id(Domain, Id);
}
+std::tuple<std::vector<const SCEV *>, std::vector<int>>
+ScopStmt::getIndexExpressionsFromGEP(GetElementPtrInst *GEP) {
+ ScalarEvolution &SE = *Parent.getSE();
+ std::vector<const SCEV *> Subscripts;
+ std::vector<int> Sizes;
+
+ Type *Ty = GEP->getPointerOperandType();
+
+ for (long 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())
+ continue;
+ Subscripts.push_back(Expr);
+ continue;
+ }
+
+ auto ArrayTy = dyn_cast<ArrayType>(Ty);
+ if (!ArrayTy) {
+ Subscripts.clear();
+ Sizes.clear();
+ break;
+ }
+
+ Subscripts.push_back(Expr);
+ Sizes.push_back(ArrayTy->getNumElements());
+
+ Ty = ArrayTy->getElementType();
+ }
+
+ return std::make_tuple(Subscripts, Sizes);
+}
+
void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP) {
int Dimension = 0;
isl_ctx *Ctx = Parent.getIslCtx();
@@ -928,43 +973,45 @@ void ScopStmt::deriveAssumptionsFromGEP(
Type *Ty = GEP->getPointerOperandType();
ScalarEvolution &SE = *Parent.getSE();
+ std::vector<const SCEV *> Subscripts;
+ std::vector<int> Sizes;
+
+ std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP);
+
if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
Dimension = 1;
Ty = PtrTy->getElementType();
}
- while (auto ArrayTy = dyn_cast<ArrayType>(Ty)) {
- unsigned int Operand = 1 + Dimension;
+ int IndexOffset = Subscripts.size() - Sizes.size();
- if (GEP->getNumOperands() <= Operand)
- break;
+ assert(IndexOffset <= 1 && "Unexpected large index offset");
- const SCEV *Expr = SE.getSCEV(GEP->getOperand(Operand));
+ for (size_t i = 0; i < Sizes.size(); i++) {
+ auto Expr = Subscripts[i + IndexOffset];
+ auto Size = Sizes[i];
- if (isAffineExpr(&Parent.getRegion(), Expr, SE)) {
- isl_pw_aff *AccessOffset = getPwAff(Expr);
- AccessOffset =
- isl_pw_aff_set_tuple_id(AccessOffset, isl_dim_in, getDomainId());
-
- isl_pw_aff *DimSize = isl_pw_aff_from_aff(isl_aff_val_on_domain(
- isl_local_space_copy(LSpace),
- isl_val_int_from_si(Ctx, ArrayTy->getNumElements())));
-
- isl_set *OutOfBound = isl_pw_aff_ge_set(AccessOffset, DimSize);
- OutOfBound = isl_set_intersect(getDomain(), OutOfBound);
- OutOfBound = isl_set_params(OutOfBound);
- isl_set *InBound = isl_set_complement(OutOfBound);
- isl_set *Executed = isl_set_params(getDomain());
-
- // A => B == !A or B
- isl_set *InBoundIfExecuted =
- isl_set_union(isl_set_complement(Executed), InBound);
+ if (!isAffineExpr(&Parent.getRegion(), Expr, SE))
+ continue;
- Parent.addAssumption(InBoundIfExecuted);
- }
+ isl_pw_aff *AccessOffset = getPwAff(Expr);
+ AccessOffset =
+ isl_pw_aff_set_tuple_id(AccessOffset, isl_dim_in, getDomainId());
- Dimension += 1;
- Ty = ArrayTy->getElementType();
+ isl_pw_aff *DimSize = isl_pw_aff_from_aff(isl_aff_val_on_domain(
+ isl_local_space_copy(LSpace), isl_val_int_from_si(Ctx, Size)));
+
+ isl_set *OutOfBound = isl_pw_aff_ge_set(AccessOffset, DimSize);
+ OutOfBound = isl_set_intersect(getDomain(), OutOfBound);
+ OutOfBound = isl_set_params(OutOfBound);
+ isl_set *InBound = isl_set_complement(OutOfBound);
+ isl_set *Executed = isl_set_params(getDomain());
+
+ // A => B == !A or B
+ isl_set *InBoundIfExecuted =
+ isl_set_union(isl_set_complement(Executed), InBound);
+
+ Parent.addAssumption(InBoundIfExecuted);
}
isl_local_space_free(LSpace);
More information about the llvm-commits
mailing list