diff mbox series

[10/n] PR85694: Split out check for vectorizable associative reductions

Message ID 878t7cf7zy.fsf@arm.com
State New
Headers show
Series [10/n] PR85694: Split out check for vectorizable associative reductions | expand

Commit Message

Richard Sandiford June 18, 2018, 3:07 p.m. UTC
This patch adds an overload of vect_reassociating_reduction_p
that checks for a vectorizable associative reduction,
since the check was duplicated in three functions.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?

Richard


2018-06-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* tree-vect-patterns.c (vect_reassociating_reduction_p): New function.
	(vect_recog_dot_prod_pattern, vect_recog_sad_pattern)
	(vect_recog_widen_sum_pattern): Use it.

Comments

Jeff Law June 23, 2018, 4:53 a.m. UTC | #1
On 06/18/2018 09:07 AM, Richard Sandiford wrote:
> This patch adds an overload of vect_reassociating_reduction_p
> that checks for a vectorizable associative reduction,
> since the check was duplicated in three functions.
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?
> 
> Richard
> 
> 
> 2018-06-18  Richard Sandiford  <richard.sandiford@arm.com>
> 
> gcc/
> 	* tree-vect-patterns.c (vect_reassociating_reduction_p): New function.
> 	(vect_recog_dot_prod_pattern, vect_recog_sad_pattern)
> 	(vect_recog_widen_sum_pattern): Use it.
OK.
jeff
diff mbox series

Patch

Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	2018-06-18 15:44:05.522927566 +0100
+++ gcc/tree-vect-patterns.c	2018-06-18 15:44:24.922756050 +0100
@@ -242,6 +242,36 @@  vect_reassociating_reduction_p (stmt_vec
 	  : REDUC_GROUP_FIRST_ELEMENT (stmt_vinfo) != NULL);
 }
 
+/* As above, but also require it to have code CODE and to be a reduction
+   in the outermost loop.  When returning true, store the operands in
+   *OP0_OUT and *OP1_OUT.  */
+
+static bool
+vect_reassociating_reduction_p (stmt_vec_info stmt_info, tree_code code,
+				tree *op0_out, tree *op1_out)
+{
+  loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info);
+  if (!loop_info)
+    return false;
+
+  gassign *assign = dyn_cast <gassign *> (stmt_info->stmt);
+  if (!assign || gimple_assign_rhs_code (assign) != code)
+    return false;
+
+  /* We don't allow changing the order of the computation in the inner-loop
+     when doing outer-loop vectorization.  */
+  struct loop *loop = LOOP_VINFO_LOOP (loop_info);
+  if (loop && nested_in_vect_loop_p (loop, assign))
+    return false;
+
+  if (!vect_reassociating_reduction_p (stmt_info))
+    return false;
+
+  *op0_out = gimple_assign_rhs1 (assign);
+  *op1_out = gimple_assign_rhs2 (assign);
+  return true;
+}
+
 /* Function vect_recog_dot_prod_pattern
 
    Try to find the following pattern:
@@ -296,26 +326,9 @@  vect_recog_dot_prod_pattern (vec<gimple
   tree type, half_type;
   gimple *pattern_stmt;
   tree prod_type;
-  loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  struct loop *loop;
   tree var;
   bool promotion;
 
-  if (!loop_info)
-    return NULL;
-
-  loop = LOOP_VINFO_LOOP (loop_info);
-
-  /* We don't allow changing the order of the computation in the inner-loop
-     when doing outer-loop vectorization.  */
-  if (loop && nested_in_vect_loop_p (loop, last_stmt))
-    return NULL;
-
-  if (!is_gimple_assign (last_stmt))
-    return NULL;
-
-  type = gimple_expr_type (last_stmt);
-
   /* Look for the following pattern
           DX = (TYPE1) X;
           DY = (TYPE1) Y;
@@ -340,17 +353,14 @@  vect_recog_dot_prod_pattern (vec<gimple
   /* Starting from LAST_STMT, follow the defs of its uses in search
      of the above pattern.  */
 
-  if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
-    return NULL;
-
   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
     return NULL;
 
-  if (!vect_reassociating_reduction_p (stmt_vinfo))
+  if (!vect_reassociating_reduction_p (stmt_vinfo, PLUS_EXPR,
+				       &oprnd0, &oprnd1))
     return NULL;
 
-  oprnd0 = gimple_assign_rhs1 (last_stmt);
-  oprnd1 = gimple_assign_rhs2 (last_stmt);
+  type = gimple_expr_type (last_stmt);
   stmt = last_stmt;
 
   gimple *def_stmt;
@@ -474,25 +484,8 @@  vect_recog_sad_pattern (vec<gimple *> *s
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
   vec_info *vinfo = stmt_vinfo->vinfo;
   tree half_type;
-  loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  struct loop *loop;
   bool promotion;
 
-  if (!loop_info)
-    return NULL;
-
-  loop = LOOP_VINFO_LOOP (loop_info);
-
-  /* We don't allow changing the order of the computation in the inner-loop
-     when doing outer-loop vectorization.  */
-  if (loop && nested_in_vect_loop_p (loop, last_stmt))
-    return NULL;
-
-  if (!is_gimple_assign (last_stmt))
-    return NULL;
-
-  tree sum_type = gimple_expr_type (last_stmt);
-
   /* Look for the following pattern
           DX = (TYPE1) X;
           DY = (TYPE1) Y;
@@ -520,19 +513,15 @@  vect_recog_sad_pattern (vec<gimple *> *s
   /* Starting from LAST_STMT, follow the defs of its uses in search
      of the above pattern.  */
 
-  if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
-    return NULL;
-
-  tree plus_oprnd0, plus_oprnd1;
-
   if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
     return NULL;
 
-  if (!vect_reassociating_reduction_p (stmt_vinfo))
+  tree plus_oprnd0, plus_oprnd1;
+  if (!vect_reassociating_reduction_p (stmt_vinfo, PLUS_EXPR,
+				       &plus_oprnd0, &plus_oprnd1))
     return NULL;
 
-  plus_oprnd0 = gimple_assign_rhs1 (last_stmt);
-  plus_oprnd1 = gimple_assign_rhs2 (last_stmt);
+  tree sum_type = gimple_expr_type (last_stmt);
 
   /* The type conversion could be promotion, demotion,
      or just signed -> unsigned.  */
@@ -1136,26 +1125,12 @@  vect_recog_widen_sum_pattern (vec<gimple
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
   tree type, half_type;
   gimple *pattern_stmt;
-  loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  struct loop *loop;
   tree var;
   bool promotion;
 
-  if (!loop_info)
-    return NULL;
-
-  loop = LOOP_VINFO_LOOP (loop_info);
-
-  /* We don't allow changing the order of the computation in the inner-loop
-     when doing outer-loop vectorization.  */
-  if (loop && nested_in_vect_loop_p (loop, last_stmt))
-    return NULL;
-
-  if (!is_gimple_assign (last_stmt))
+  if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
     return NULL;
 
-  type = gimple_expr_type (last_stmt);
-
   /* Look for the following pattern
           DX = (TYPE) X;
           sum_1 = DX + sum_0;
@@ -1166,14 +1141,11 @@  vect_recog_widen_sum_pattern (vec<gimple
   /* Starting from LAST_STMT, follow the defs of its uses in search
      of the above pattern.  */
 
-  if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
-    return NULL;
-
-  if (!vect_reassociating_reduction_p (stmt_vinfo))
+  if (!vect_reassociating_reduction_p (stmt_vinfo, PLUS_EXPR,
+				       &oprnd0, &oprnd1))
     return NULL;
 
-  oprnd0 = gimple_assign_rhs1 (last_stmt);
-  oprnd1 = gimple_assign_rhs2 (last_stmt);
+  type = gimple_expr_type (last_stmt);
 
   /* So far so good.  Since last_stmt was detected as a (summation) reduction,
      we know that oprnd1 is the reduction variable (defined by a loop-header