[polly] r230328 - Add ScalarEvolution bounds to non-affine access functions

Johannes Doerfert doerfert at cs.uni-saarland.de
Tue Feb 24 03:58:31 PST 2015


Author: jdoerfert
Date: Tue Feb 24 05:58:30 2015
New Revision: 230328

URL: http://llvm.org/viewvc/llvm-project?rev=230328&view=rev
Log:
Add ScalarEvolution bounds to non-affine access functions

Added:
    polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range.ll
    polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range_2.ll
Modified:
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll
    polly/trunk/test/ScopInfo/non_affine_access.ll
    polly/trunk/test/ScopInfo/non_affine_parametric_loop.ll

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=230328&r1=230327&r2=230328&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Tue Feb 24 05:58:30 2015
@@ -209,6 +209,11 @@ private:
 
   void assumeNoOutOfBound(const IRAccess &Access);
 
+  /// @brief Compute bounds on an over approximated  access relation.
+  ///
+  /// @param ElementSize The size of one element accessed.
+  void computeBoundsOnAccessRelation(unsigned ElementSize);
+
   /// @brief Get the original access function as read from IR.
   isl_map *getOriginalAccessRelation() const;
 

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=230328&r1=230327&r2=230328&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Tue Feb 24 05:58:30 2015
@@ -299,6 +299,27 @@ int SCEVAffinator::getLoopDepth(const Lo
   return L->getLoopDepth() - outerLoop->getLoopDepth();
 }
 
+/// @brief Add the bounds of @p Range to the set @p S for dimension @p dim.
+static __isl_give isl_set *addRangeBoundsToSet(__isl_take isl_set *S,
+                                               const ConstantRange &Range,
+                                               int dim,
+                                               enum isl_dim_type type) {
+  isl_val *V;
+  isl_ctx *ctx = isl_set_get_ctx(S);
+
+  V = isl_valFromAPInt(ctx, Range.getLower(), true);
+  isl_set *SLB = isl_set_lower_bound_val(isl_set_copy(S), type, dim, V);
+
+  V = isl_valFromAPInt(ctx, Range.getUpper(), true);
+  V = isl_val_sub_ui(V, 1);
+  isl_set *SUB = isl_set_upper_bound_val(S, type, dim, V);
+
+  if (Range.isSignWrappedSet())
+    return isl_set_union(SLB, SUB);
+  else
+    return isl_set_intersect(SLB, SUB);
+}
+
 ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *AccessType, isl_ctx *Ctx,
                              const SmallVector<const SCEV *, 4> &DimensionSizes)
     : BasePtr(BasePtr), AccessType(AccessType), DimensionSizes(DimensionSizes) {
@@ -510,6 +531,36 @@ void MemoryAccess::assumeNoOutOfBound(co
   isl_space_free(Space);
 }
 
+void MemoryAccess::computeBoundsOnAccessRelation(unsigned ElementSize) {
+  ScalarEvolution *SE = Statement->getParent()->getSE();
+
+  Value *Ptr = getPointerOperand(*getAccessInstruction());
+  if (!Ptr || !SE->isSCEVable(Ptr->getType()))
+    return;
+
+  auto *PtrSCEV = SE->getSCEV(Ptr);
+  if (isa<SCEVCouldNotCompute>(PtrSCEV))
+    return;
+
+  auto *BasePtrSCEV = SE->getPointerBase(PtrSCEV);
+  if (BasePtrSCEV && !isa<SCEVCouldNotCompute>(BasePtrSCEV))
+    PtrSCEV = SE->getMinusSCEV(PtrSCEV, BasePtrSCEV);
+
+  const ConstantRange &Range = SE->getSignedRange(PtrSCEV);
+  if (Range.isFullSet())
+    return;
+
+  unsigned BW = Range.getBitWidth();
+  auto Min = Range.getSignedMin().sdiv(APInt(BW, ElementSize, false));
+  auto Max = (Range.getSignedMax() - APInt(BW, 1, false))
+                 .sdiv(APInt(BW, ElementSize, false));
+
+  isl_set *AccessRange = isl_map_range(isl_map_copy(AccessRelation));
+  AccessRange =
+      addRangeBoundsToSet(AccessRange, ConstantRange(Min, Max), 0, isl_dim_set);
+  AccessRelation = isl_map_intersect_range(AccessRelation, AccessRange);
+}
+
 MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
                            ScopStmt *Statement, const ScopArrayInfo *SAI)
     : AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst),
@@ -529,6 +580,8 @@ MemoryAccess::MemoryAccess(const IRAcces
     AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
     AccessRelation =
         isl_map_set_tuple_id(AccessRelation, isl_dim_out, BaseAddrId);
+
+    computeBoundsOnAccessRelation(Access.getElemSizeInBytes());
     return;
   }
 
@@ -1188,7 +1241,6 @@ void Scop::buildContext() {
 
 void Scop::addParameterBounds() {
   for (const auto &ParamID : ParameterIds) {
-    isl_val *V;
     int dim = ParamID.second;
 
     ConstantRange SRange = SE->getSignedRange(ParamID.first);
@@ -1197,19 +1249,7 @@ void Scop::addParameterBounds() {
     if (SRange.isFullSet())
       continue;
 
-    V = isl_valFromAPInt(IslCtx, SRange.getLower(), true);
-    isl_set *ContextLB =
-        isl_set_lower_bound_val(isl_set_copy(Context), isl_dim_param, dim, V);
-
-    V = isl_valFromAPInt(IslCtx, SRange.getUpper(), true);
-    V = isl_val_sub_ui(V, 1);
-    isl_set *ContextUB =
-        isl_set_upper_bound_val(Context, isl_dim_param, dim, V);
-
-    if (SRange.isSignWrappedSet())
-      Context = isl_set_union(ContextLB, ContextUB);
-    else
-      Context = isl_set_intersect(ContextLB, ContextUB);
+    Context = addRangeBoundsToSet(Context, SRange, dim, isl_dim_param);
   }
 }
 

Added: polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range.ll?rev=230328&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range.ll (added)
+++ polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range.ll Tue Feb 24 05:58:30 2015
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s
+;
+;    void f(int *A, char c) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i * c]++;
+;    }
+;
+; CHECK: ReadAccess := [Reduction Type: +] [Scalar: 0]
+; CHECK:     { Stmt_bb2[i0] -> MemRef_A[o0] : o0 <= 261115 and o0 >= -3 };
+; CHECK: MayWriteAccess := [Reduction Type: +] [Scalar: 0]
+; CHECK:     { Stmt_bb2[i0] -> MemRef_A[o0] : o0 <= 261115 and o0 >= -3 };
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A, i8 %c) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb8, %bb
+  %indvars.iv = phi i64 [ %indvars.iv.next, %bb8 ], [ 0, %bb ]
+  %exitcond = icmp ne i64 %indvars.iv, 1024
+  br i1 %exitcond, label %bb2, label %bb9
+
+bb2:                                              ; preds = %bb1
+  %tmp = zext i8 %c to i32
+  %tmp3 = zext i32 %tmp to i64
+  %tmp4 = mul nuw nsw i64 %indvars.iv, %tmp3
+  %tmp4b = add nsw nuw i64 %tmp4, -3
+  %tmp5 = getelementptr inbounds i32* %A, i64 %tmp4b
+  %tmp6 = load i32* %tmp5, align 4
+  %tmp7 = add nsw i32 %tmp6, 1
+  store i32 %tmp7, i32* %tmp5, align 4
+  br label %bb8
+
+bb8:                                              ; preds = %bb2
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %bb1
+
+bb9:                                              ; preds = %bb1
+  ret void
+}

Added: polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range_2.ll?rev=230328&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range_2.ll (added)
+++ polly/trunk/test/ScopInfo/NonAffine/non_affine_access_with_range_2.ll Tue Feb 24 05:58:30 2015
@@ -0,0 +1,54 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s
+;
+;    void f(int *A) {
+;      for (int i = 0; i < 128; i++)
+;        for (int j = 0; j < 16; j++)
+;          A[i * j]++;
+;    }
+;
+; CHECK: ReadAccess := [Reduction Type: +] [Scalar: 0]
+; CHECK:     { Stmt_bb7[i0, i1] -> MemRef_A[o0] : o0 <= 2046 and o0 >= 0 };
+; CHECK: MayWriteAccess := [Reduction Type: +] [Scalar: 0]
+; CHECK:     { Stmt_bb7[i0, i1] -> MemRef_A[o0] : o0 <= 2046 and o0 >= 0 };
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A) {
+bb:
+  br label %bb4
+
+bb4:                                              ; preds = %bb13, %bb
+  %indvars.iv1 = phi i64 [ %indvars.iv.next2, %bb13 ], [ 0, %bb ]
+  %exitcond3 = icmp ne i64 %indvars.iv1, 128
+  br i1 %exitcond3, label %bb5, label %bb14
+
+bb5:                                              ; preds = %bb4
+  br label %bb6
+
+bb6:                                              ; preds = %bb11, %bb5
+  %indvars.iv = phi i64 [ %indvars.iv.next, %bb11 ], [ 0, %bb5 ]
+  %exitcond = icmp ne i64 %indvars.iv, 16
+  br i1 %exitcond, label %bb7, label %bb12
+
+bb7:                                              ; preds = %bb6
+  %tmp = mul nsw i64 %indvars.iv1, %indvars.iv
+  %tmp8 = getelementptr inbounds i32* %A, i64 %tmp
+  %tmp9 = load i32* %tmp8, align 4
+  %tmp10 = add nsw i32 %tmp9, 1
+  store i32 %tmp10, i32* %tmp8, align 4
+  br label %bb11
+
+bb11:                                             ; preds = %bb7
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %bb6
+
+bb12:                                             ; preds = %bb6
+  br label %bb13
+
+bb13:                                             ; preds = %bb12
+  %indvars.iv.next2 = add nuw nsw i64 %indvars.iv1, 1
+  br label %bb4
+
+bb14:                                             ; preds = %bb4
+  ret void
+}

Modified: polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll?rev=230328&r1=230327&r2=230328&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll Tue Feb 24 05:58:30 2015
@@ -24,7 +24,7 @@ target datalayout = "e-m:e-i64:64-f80:12
 ; NONAFFINE: Statements {
 ; NONAFFINE:   Stmt_for_i_1
 ; NONAFFINE:         MayWriteAccess :=   [Reduction Type: NONE]
-; NONAFFINE:             [n, p_1] -> { Stmt_for_i_1[i0] -> MemRef_X[o0] };
+; NONAFFINE:             [n, p_1] -> { Stmt_for_i_1[i0] -> MemRef_X[o0] : o0 >= -2305843009213693952 and o0 <= 2305843009213693949 };
 ; NONAFFINE:   Stmt_for_i_2
 ; NONAFFINE:         MustWriteAccess :=  [Reduction Type: NONE]
 ; NONAFFINE:             [n, p_1] -> { Stmt_for_i_2[i0] -> MemRef_X[o0] : 4o0 = p_1 + 4i0 };

Modified: polly/trunk/test/ScopInfo/non_affine_access.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/non_affine_access.ll?rev=230328&r1=230327&r2=230328&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/non_affine_access.ll (original)
+++ polly/trunk/test/ScopInfo/non_affine_access.ll Tue Feb 24 05:58:30 2015
@@ -31,4 +31,4 @@ for.end:
 }
 
 ; CHECK-NOT: Stmt_for_body
-; NONAFFINE: { Stmt_for_body[i0] -> MemRef_A[o0] };
+; NONAFFINE: { Stmt_for_body[i0] -> MemRef_A[o0] :  o0 >= -1152921504606846976 and o0 <= 1152921504606846973 };

Modified: polly/trunk/test/ScopInfo/non_affine_parametric_loop.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/non_affine_parametric_loop.ll?rev=230328&r1=230327&r2=230328&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/non_affine_parametric_loop.ll (original)
+++ polly/trunk/test/ScopInfo/non_affine_parametric_loop.ll Tue Feb 24 05:58:30 2015
@@ -34,4 +34,4 @@ for.end:
 ; CHECK: ReadAccess
 ; CHECK:   [n] -> { Stmt_for_body[i0] -> MemRef_INDEX[i0] };
 ; CHECK: WriteAccess
-; CHECK:   [n] -> { Stmt_for_body[i0] -> MemRef_A[o0] };
+; CHECK:   [n] -> { Stmt_for_body[i0] -> MemRef_A[o0] : o0 >= -1152921504606846976 and o0 <= 1152921504606846973 };





More information about the llvm-commits mailing list