tree-vectorizer.h (vect_build_loop_niters): New parameter.
authorBin Cheng <bin.cheng@arm.com>
Wed, 7 Jun 2017 10:53:02 +0000 (10:53 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Wed, 7 Jun 2017 10:53:02 +0000 (10:53 +0000)
* tree-vectorizer.h (vect_build_loop_niters): New parameter.
* tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
Set true to new parameter if new ssa variable is defined.
(vect_gen_vector_loop_niters): Refactor.  Set range information
for the new vector loop bound variable.
(vect_do_peeling): Ditto.

From-SVN: r248958

gcc/ChangeLog
gcc/tree-vect-loop-manip.c
gcc/tree-vectorizer.h

index 708051d9b495ed6c591caed26fcff22c2052fdf0..f83e059e05fd84002eb265a015161baf77cd763e 100644 (file)
@@ -1,3 +1,12 @@
+2017-06-07  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-vectorizer.h (vect_build_loop_niters): New parameter.
+       * tree-vect-loop-manip.c (vect_build_loop_niters): New parameter.
+       Set true to new parameter if new ssa variable is defined.
+       (vect_gen_vector_loop_niters): Refactor.  Set range information
+       for the new vector loop bound variable.
+       (vect_do_peeling): Ditto.
+
 2017-06-07  Bin Cheng  <bin.cheng@arm.com>
 
        * tree-affine.c (ssa.h): Include header file.
index 2a7fdca5690483cf987ba5e9c333452405708bc6..0156c97be5c50ea1a7d9a7b3cde94d560c1b2fe9 100644 (file)
@@ -1095,10 +1095,11 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
 
 
 /* This function builds ni_name = number of iterations.  Statements
-   are emitted on the loop preheader edge.  */
+   are emitted on the loop preheader edge.  If NEW_VAR_P is not NULL, set
+   it to TRUE if new ssa_var is generated.  */
 
 tree
-vect_build_loop_niters (loop_vec_info loop_vinfo)
+vect_build_loop_niters (loop_vec_info loop_vinfo, bool *new_var_p)
 {
   tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
   if (TREE_CODE (ni) == INTEGER_CST)
@@ -1112,7 +1113,11 @@ vect_build_loop_niters (loop_vec_info loop_vinfo)
       var = create_tmp_var (TREE_TYPE (ni), "niters");
       ni_name = force_gimple_operand (ni, &stmts, false, var);
       if (stmts)
-       gsi_insert_seq_on_edge_immediate (pe, stmts);
+       {
+         gsi_insert_seq_on_edge_immediate (pe, stmts);
+         if (new_var_p != NULL)
+           *new_var_p = true;
+       }
 
       return ni_name;
     }
@@ -1177,22 +1182,21 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
                             tree *niters_vector_ptr, bool niters_no_overflow)
 {
   tree ni_minus_gap, var;
-  tree niters_vector;
+  tree niters_vector, type = TREE_TYPE (niters);
   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
-  tree log_vf = build_int_cst (TREE_TYPE (niters), exact_log2 (vf));
+  tree log_vf = build_int_cst (type, exact_log2 (vf));
 
   /* If epilogue loop is required because of data accesses with gaps, we
      subtract one iteration from the total number of iterations here for
      correct calculation of RATIO.  */
   if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
     {
-      ni_minus_gap = fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
-                                 niters,
-                                 build_one_cst (TREE_TYPE (niters)));
+      ni_minus_gap = fold_build2 (MINUS_EXPR, type, niters,
+                                 build_one_cst (type));
       if (!is_gimple_val (ni_minus_gap))
        {
-         var = create_tmp_var (TREE_TYPE (niters), "ni_gap");
+         var = create_tmp_var (type, "ni_gap");
          gimple *stmts = NULL;
          ni_minus_gap = force_gimple_operand (ni_minus_gap, &stmts,
                                               true, var);
@@ -1208,25 +1212,28 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters,
      (niters - vf) >> log2(vf) + 1 by using the fact that we know ratio
      will be at least one.  */
   if (niters_no_overflow)
-    niters_vector = fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters),
-                                ni_minus_gap, log_vf);
+    niters_vector = fold_build2 (RSHIFT_EXPR, type, ni_minus_gap, log_vf);
   else
     niters_vector
-      = fold_build2 (PLUS_EXPR, TREE_TYPE (niters),
-                    fold_build2 (RSHIFT_EXPR, TREE_TYPE (niters),
-                                 fold_build2 (MINUS_EXPR, TREE_TYPE (niters),
-                                              ni_minus_gap,
-                                              build_int_cst
-                                                (TREE_TYPE (niters), vf)),
+      = fold_build2 (PLUS_EXPR, type,
+                    fold_build2 (RSHIFT_EXPR, type,
+                                 fold_build2 (MINUS_EXPR, type, ni_minus_gap,
+                                              build_int_cst (type, vf)),
                                  log_vf),
-                    build_int_cst (TREE_TYPE (niters), 1));
+                    build_int_cst (type, 1));
 
   if (!is_gimple_val (niters_vector))
     {
-      var = create_tmp_var (TREE_TYPE (niters), "bnd");
-      gimple *stmts = NULL;
+      var = create_tmp_var (type, "bnd");
+      gimple_seq stmts = NULL;
       niters_vector = force_gimple_operand (niters_vector, &stmts, true, var);
       gsi_insert_seq_on_edge_immediate (pe, stmts);
+      /* Peeling algorithm guarantees that vector loop bound is at least ONE,
+        we set range information to make niters analyzer's life easier.  */
+      if (stmts != NULL)
+       set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
+                       fold_build2 (RSHIFT_EXPR, type,
+                                    TYPE_MAX_VALUE (type), log_vf));
     }
   *niters_vector_ptr = niters_vector;
 
@@ -1771,7 +1778,13 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
       LOOP_VINFO_NITERSM1 (loop_vinfo)
        = fold_build2 (MINUS_EXPR, type,
                       LOOP_VINFO_NITERSM1 (loop_vinfo), niters_prolog);
-      niters = vect_build_loop_niters (loop_vinfo);
+      bool new_var_p = false;
+      niters = vect_build_loop_niters (loop_vinfo, &new_var_p);
+      /* It's guaranteed that vector loop bound before vectorization is at
+        least VF, so set range information for newly generated var.  */
+      if (new_var_p)
+       set_range_info (niters, VR_RANGE,
+                       build_int_cst (type, vf), TYPE_MAX_VALUE (type));
 
       /* Prolog iterates at most bound_prolog times, latch iterates at
         most bound_prolog - 1 times.  */
index 3dacb1aee47e22f52ee108fb1ad4c9600572cc29..2e46467ee3730920476e86490b0d6e7c8a188442 100644 (file)
@@ -1150,7 +1150,7 @@ extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *,
                                            bool *, bool);
 /* Drive for loop analysis stage.  */
 extern loop_vec_info vect_analyze_loop (struct loop *, loop_vec_info);
-extern tree vect_build_loop_niters (loop_vec_info);
+extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL);
 extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, bool);
 /* Drive for loop transformation stage.  */
 extern struct loop *vect_transform_loop (loop_vec_info);