diff mbox

[GCC8,31/33] Set range information for niter bound of vectorized loop

Message ID VI1PR0802MB2176DFC4FDDB5C365B2F8E3FE7190@VI1PR0802MB2176.eurprd08.prod.outlook.com
State New
Headers show

Commit Message

Bin Cheng April 18, 2017, 10:54 a.m. UTC
Hi,
Based on vect_peeling algorithm, we know for sure that vectorized loop must iterates at least once.
This patch sets range information for niter bounds of vectorized loop.  This helps niter analysis,
so iv elimination too.
Is it OK?

Thanks,
bin
2017-04-11  Bin Cheng  <bin.cheng@arm.com>

	* tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
	Set range information for vector loop bound variable.
	(vect_do_peeling): Ditto.
From 0962735526bf474591e410104d6c9576691e0a1f Mon Sep 17 00:00:00 2001
From: Bin Cheng <binche01@e108451-lin.cambridge.arm.com>
Date: Tue, 14 Mar 2017 17:46:55 +0000
Subject: [PATCH 31/33] range_info-for-vect_loop-niters-20170224.txt

---
 gcc/tree-vect-loop-manip.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

Comments

Richard Biener May 11, 2017, 11:02 a.m. UTC | #1
On Tue, Apr 18, 2017 at 12:54 PM, Bin Cheng <Bin.Cheng@arm.com> wrote
> Hi,
> Based on vect_peeling algorithm, we know for sure that vectorized loop must iterates at least once.
> This patch sets range information for niter bounds of vectorized loop.  This helps niter analysis,
> so iv elimination too.
> Is it OK?

       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 (TREE_CODE (niters_vector) == SSA_NAME)
+       set_range_info (niters_vector, VR_RANGE, build_int_cst (type, 1),
+                       fold_build2 (RSHIFT_EXPR, type,
+                                    TYPE_MAX_VALUE (type), log_vf));

if all of niters_vector folds to an original SSA name then
niters_vector after gimplification
is not a new SSA name and thus you can't set range-info on it.

Likewise for the other case where LOOP_VINFO_NITERS is just an SSA name.

Richard.

> Thanks,
> bin
> 2017-04-11  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-vect-loop-manip.c (vect_gen_vector_loop_niters): Refactor.
>         Set range information for vector loop bound variable.
>         (vect_do_peeling): Ditto.
diff mbox

Patch

diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index faeaa6d..0fc8cd3 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1177,22 +1177,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 +1207,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");
+      var = create_tmp_var (type, "bnd");
       gimple *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 (TREE_CODE (niters_vector) == SSA_NAME)
+	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;
 
@@ -1773,6 +1775,11 @@  vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
 	= fold_build2 (MINUS_EXPR, type,
 		       LOOP_VINFO_NITERSM1 (loop_vinfo), niters_prolog);
       niters = vect_build_loop_niters (loop_vinfo);
+      /* It's guaranteed that vector loop bound before vectorization is at
+	 least VF, so set range information.  */
+      if (TREE_CODE (niters) == SSA_NAME)
+	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.  */