[polly] r245680 - Manually check a loop form

Roman Gareev via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 02:08:14 PDT 2015


Author: romangareev
Date: Fri Aug 21 04:08:14 2015
New Revision: 245680

URL: http://llvm.org/viewvc/llvm-project?rev=245680&view=rev
Log:
Manually check a loop form

Add manual check of a loop form and return non-negative number of iterations
in case of trivially vectorizable loop.

Added:
    polly/trunk/test/Isl/CodeGen/getNumberOfIterations.ll
Modified:
    polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
    polly/trunk/lib/CodeGen/IslNodeBuilder.cpp

Modified: polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslNodeBuilder.h?rev=245680&r1=245679&r2=245680&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslNodeBuilder.h (original)
+++ polly/trunk/include/polly/CodeGen/IslNodeBuilder.h Fri Aug 21 04:08:14 2015
@@ -129,7 +129,16 @@ private:
   __isl_give isl_ast_expr *getUpperBound(__isl_keep isl_ast_node *For,
                                          CmpInst::Predicate &Predicate);
 
-  unsigned getNumberOfIterations(__isl_keep isl_ast_node *For);
+  /// Return non-negative number of iterations in case of the following form
+  /// of a loop and -1 otherwise.
+  ///
+  /// for (i = 0; i <= NumIter; i++) {
+  ///   loop body;
+  /// }
+  ///
+  /// NumIter is a non-negative integer value. Condition can have
+  /// isl_ast_op_lt type.
+  int getNumberOfIterations(__isl_keep isl_ast_node *For);
 
   /// Compute the values and loops referenced in this subtree.
   ///

Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=245680&r1=245679&r2=245680&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Fri Aug 21 04:08:14 2015
@@ -101,51 +101,48 @@ IslNodeBuilder::getUpperBound(__isl_keep
   return UB;
 }
 
-unsigned IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
-  isl_union_map *Schedule = IslAstInfo::getSchedule(For);
-  isl_set *LoopDomain = isl_set_from_union_set(isl_union_map_range(Schedule));
-  if (isl_set_is_wrapping(LoopDomain))
-    LoopDomain = isl_map_range(isl_set_unwrap(LoopDomain));
-  int Dim = isl_set_dim(LoopDomain, isl_dim_set);
-
-  // Calculate a map similar to the identity map, but with the last input
-  // and output dimension not related.
-  //  [i0, i1, i2, i3] -> [i0, i1, i2, o0]
-  isl_space *Space = isl_set_get_space(LoopDomain);
-  Space = isl_space_drop_dims(Space, isl_dim_out, Dim - 1, 1);
-  Space = isl_space_map_from_set(Space);
-  isl_map *Identity = isl_map_identity(Space);
-  Identity = isl_map_add_dims(Identity, isl_dim_in, 1);
-  Identity = isl_map_add_dims(Identity, isl_dim_out, 1);
-
-  LoopDomain = isl_set_reset_tuple_id(LoopDomain);
-
-  isl_map *Map = isl_map_from_domain_and_range(isl_set_copy(LoopDomain),
-                                               isl_set_copy(LoopDomain));
-  isl_set_free(LoopDomain);
-  Map = isl_map_intersect(Map, Identity);
-
-  isl_map *LexMax = isl_map_lexmax(isl_map_copy(Map));
-  isl_map *LexMin = isl_map_lexmin(Map);
-  isl_map *Sub = isl_map_sum(LexMax, isl_map_neg(LexMin));
-
-  isl_set *Elements = isl_map_range(Sub);
+/// @brief Return true if a return value of Predicate is true for the value
+/// represented by passed isl_ast_expr_int.
+static bool checkIslAstExprInt(__isl_take isl_ast_expr *Expr,
+                               isl_bool (*Predicate)(__isl_keep isl_val *)) {
+  if (isl_ast_expr_get_type(Expr) != isl_ast_expr_int) {
+    isl_ast_expr_free(Expr);
+    return false;
+  }
+  auto ExprVal = isl_ast_expr_get_val(Expr);
+  isl_ast_expr_free(Expr);
+  if (Predicate(ExprVal) != true) {
+    isl_val_free(ExprVal);
+    return false;
+  }
+  isl_val_free(ExprVal);
+  return true;
+}
 
-  if (!isl_set_is_singleton(Elements)) {
-    isl_set_free(Elements);
+int IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
+  assert(isl_ast_node_get_type(For) == isl_ast_node_for);
+  auto Init = isl_ast_node_for_get_init(For);
+  if (!checkIslAstExprInt(Init, isl_val_is_zero))
+    return -1;
+  auto Inc = isl_ast_node_for_get_inc(For);
+  if (!checkIslAstExprInt(Inc, isl_val_is_one))
+    return -1;
+  CmpInst::Predicate Predicate;
+  auto UB = getUpperBound(For, Predicate);
+  if (isl_ast_expr_get_type(UB) != isl_ast_expr_int) {
+    isl_ast_expr_free(UB);
     return -1;
   }
-
-  isl_point *P = isl_set_sample_point(Elements);
-
-  isl_val *V;
-  V = isl_point_get_coordinate_val(P, isl_dim_set, Dim - 1);
-  int NumberIterations = isl_val_get_num_si(V);
-  isl_val_free(V);
-  isl_point_free(P);
-  if (NumberIterations == -1)
+  auto UpVal = isl_ast_expr_get_val(UB);
+  isl_ast_expr_free(UB);
+  int NumberIterations = isl_val_get_num_si(UpVal);
+  isl_val_free(UpVal);
+  if (NumberIterations < 0)
     return -1;
-  return NumberIterations + 1;
+  if (Predicate == CmpInst::ICMP_SLT)
+    return NumberIterations;
+  else
+    return NumberIterations + 1;
 }
 
 struct FindValuesUser {

Added: polly/trunk/test/Isl/CodeGen/getNumberOfIterations.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/getNumberOfIterations.ll?rev=245680&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/getNumberOfIterations.ll (added)
+++ polly/trunk/test/Isl/CodeGen/getNumberOfIterations.ll Fri Aug 21 04:08:14 2015
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-vectorizer=polly -polly-codegen < %s -S | FileCheck %s
+
+; #pragma known-parallel
+; for (int c0 = 0; c0 <= min(15, N - 1); c0 += 1)
+;   Stmt_if_then(c0);
+
+; CHECK: polly.stmt.if.then:                               ; preds = %polly.loop_header
+; CHECK:   %p_conv = sitofp i64 %polly.indvar to float
+; CHECK:   %scevgep = getelementptr float, float* %A, i64 %polly.indvar
+; CHECK:   %_p_scalar_ = load float, float* %scevgep, align 4, !alias.scope !0, !noalias !2, !llvm.mem.parallel_loop_access !3
+; CHECK:   %p_add = fadd float %p_conv, %_p_scalar_
+; CHECK:   store float %p_add, float* %scevgep, align 4, !alias.scope !0, !noalias !2, !llvm.mem.parallel_loop_access !3
+
+define void @foo(float* %A, i64 %N) #0 {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %entry, %for.inc
+  %i.02 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
+  %cmp1 = icmp slt i64 %i.02, %N
+  br i1 %cmp1, label %if.then, label %for.inc
+
+if.then:                                          ; preds = %for.body
+  %conv = sitofp i64 %i.02 to float
+  %arrayidx = getelementptr inbounds float, float* %A, i64 %i.02
+  %0 = load float, float* %arrayidx, align 4
+  %add = fadd float %conv, %0
+  store float %add, float* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body, %if.then
+  %inc = add nuw nsw i64 %i.02, 1
+  %exitcond = icmp ne i64 %inc, 16
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.inc
+  ret void
+}




More information about the llvm-commits mailing list