This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[11/46] Pass back a stmt_vec_info from vect_is_simple_use


This patch makes vect_is_simple_use pass back a stmt_vec_info to
those callers that want it.  Most users only need the stmt_vec_info
but some need the gimple stmt too.

It's probably high time we added a class to represent "simple operands"
instead, but I have a separate series that tries to clean up how
operands are handled (with a view to allowing mixed vector sizes).


2018-07-24  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* tree-vectorizer.h (vect_is_simple_use): Add an optional
	stmt_vec_info * parameter before the optional gimple **.
	* tree-vect-stmts.c (vect_is_simple_use): Likewise.
	(process_use, vect_get_vec_def_for_operand_1): Update callers.
	(vect_get_vec_def_for_operand, vectorizable_shift): Likewise.
	* tree-vect-loop.c (vectorizable_reduction): Likewise.
	(vectorizable_live_operation): Likewise.
	* tree-vect-patterns.c (type_conversion_p): Likewise.
	(vect_look_through_possible_promotion): Likewise.
	(vect_recog_rotate_pattern): Likewise.
	* tree-vect-slp.c (vect_get_and_check_slp_defs): Likewise.

Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h	2018-07-24 10:22:33.829278607 +0100
+++ gcc/tree-vectorizer.h	2018-07-24 10:22:37.257248166 +0100
@@ -1532,9 +1532,10 @@ extern tree get_mask_type_for_scalar_typ
 extern tree get_same_sized_vectype (tree, tree);
 extern bool vect_get_loop_mask_type (loop_vec_info);
 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
-				gimple ** = NULL);
+				stmt_vec_info * = NULL, gimple ** = NULL);
 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
-				tree *, gimple ** = NULL);
+				tree *, stmt_vec_info * = NULL,
+				gimple ** = NULL);
 extern bool supportable_widening_operation (enum tree_code, gimple *, tree,
 					    tree, enum tree_code *,
 					    enum tree_code *, int *,
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	2018-07-24 10:22:33.829278607 +0100
+++ gcc/tree-vect-stmts.c	2018-07-24 10:22:37.257248166 +0100
@@ -459,11 +459,9 @@ process_use (gimple *stmt, tree use, loo
 	     enum vect_relevant relevant, vec<gimple *> *worklist,
 	     bool force)
 {
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
   stmt_vec_info dstmt_vinfo;
   basic_block bb, def_bb;
-  gimple *def_stmt;
   enum vect_def_type dt;
 
   /* case 1: we are only interested in uses that need to be vectorized.  Uses
@@ -471,7 +469,7 @@ process_use (gimple *stmt, tree use, loo
   if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
      return true;
 
-  if (!vect_is_simple_use (use, loop_vinfo, &dt, &def_stmt))
+  if (!vect_is_simple_use (use, loop_vinfo, &dt, &dstmt_vinfo))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -479,27 +477,20 @@ process_use (gimple *stmt, tree use, loo
       return false;
     }
 
-  if (!def_stmt || gimple_nop_p (def_stmt))
+  if (!dstmt_vinfo)
     return true;
 
-  def_bb = gimple_bb (def_stmt);
-  if (!flow_bb_inside_loop_p (loop, def_bb))
-    {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n");
-      return true;
-    }
+  def_bb = gimple_bb (dstmt_vinfo->stmt);
 
-  /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT).
-     DEF_STMT must have already been processed, because this should be the
+  /* case 2: A reduction phi (STMT) defined by a reduction stmt (DSTMT_VINFO).
+     DSTMT_VINFO must have already been processed, because this should be the
      only way that STMT, which is a reduction-phi, was put in the worklist,
-     as there should be no other uses for DEF_STMT in the loop.  So we just
+     as there should be no other uses for DSTMT_VINFO in the loop.  So we just
      check that everything is as expected, and we are done.  */
-  dstmt_vinfo = vinfo_for_stmt (def_stmt);
   bb = gimple_bb (stmt);
   if (gimple_code (stmt) == GIMPLE_PHI
       && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
-      && gimple_code (def_stmt) != GIMPLE_PHI
+      && gimple_code (dstmt_vinfo->stmt) != GIMPLE_PHI
       && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
       && bb->loop_father == def_bb->loop_father)
     {
@@ -514,7 +505,7 @@ process_use (gimple *stmt, tree use, loo
 
   /* case 3a: outer-loop stmt defining an inner-loop stmt:
 	outer-loop-header-bb:
-		d = def_stmt
+		d = dstmt_vinfo
 	inner-loop:
 		stmt # use (d)
 	outer-loop-tail-bb:
@@ -554,7 +545,7 @@ process_use (gimple *stmt, tree use, loo
 	outer-loop-header-bb:
 		...
 	inner-loop:
-		d = def_stmt
+		d = dstmt_vinfo
 	outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
 		stmt # use (d)		*/
   else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
@@ -601,7 +592,7 @@ process_use (gimple *stmt, tree use, loo
     }
 
 
-  vect_mark_relevant (worklist, def_stmt, relevant, false);
+  vect_mark_relevant (worklist, dstmt_vinfo, relevant, false);
   return true;
 }
 
@@ -1563,7 +1554,9 @@ vect_get_vec_def_for_operand (tree op, g
       dump_printf (MSG_NOTE, "\n");
     }
 
-  is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt, &def_stmt);
+  stmt_vec_info def_stmt_info;
+  is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt,
+				      &def_stmt_info, &def_stmt);
   gcc_assert (is_simple_use);
   if (def_stmt && dump_enabled_p ())
     {
@@ -1588,7 +1581,7 @@ vect_get_vec_def_for_operand (tree op, g
       return vect_init_vector (stmt, op, vector_type, NULL);
     }
   else
-    return vect_get_vec_def_for_operand_1 (def_stmt, dt);
+    return vect_get_vec_def_for_operand_1 (def_stmt_info, dt);
 }
 
 
@@ -5479,7 +5472,9 @@ vectorizable_shift (gimple *stmt, gimple
     return false;
 
   op1 = gimple_assign_rhs2 (stmt);
-  if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype))
+  stmt_vec_info op1_def_stmt_info;
+  if (!vect_is_simple_use (op1, vinfo, &dt[1], &op1_vectype,
+			   &op1_def_stmt_info))
     {
       if (dump_enabled_p ())
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5524,12 +5519,8 @@ vectorizable_shift (gimple *stmt, gimple
       /* If the shift amount is computed by a pattern stmt we cannot
          use the scalar amount directly thus give up and use a vector
 	 shift.  */
-      if (dt[1] == vect_internal_def)
-	{
-	  gimple *def = SSA_NAME_DEF_STMT (op1);
-	  if (is_pattern_stmt_p (vinfo_for_stmt (def)))
-	    scalar_shift_arg = false;
-	}
+      if (op1_def_stmt_info && is_pattern_stmt_p (op1_def_stmt_info))
+	scalar_shift_arg = false;
     }
   else
     {
@@ -10051,7 +10042,10 @@ get_same_sized_vectype (tree scalar_type
    VINFO - the vect info of the loop or basic block that is being vectorized.
    OPERAND - operand in the loop or bb.
    Output:
-   DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME.
+   DEF_STMT_INFO_OUT (optional) - information about the defining stmt in
+     case OPERAND is an SSA_NAME that is defined in the vectorizable region
+   DEF_STMT_OUT (optional) - the defining stmt in case OPERAND is an SSA_NAME;
+     the definition could be anywhere in the function
    DT - the type of definition
 
    Returns whether a stmt with OPERAND can be vectorized.
@@ -10064,8 +10058,10 @@ get_same_sized_vectype (tree scalar_type
 
 bool
 vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
-		    gimple **def_stmt_out)
+		    stmt_vec_info *def_stmt_info_out, gimple **def_stmt_out)
 {
+  if (def_stmt_info_out)
+    *def_stmt_info_out = NULL;
   if (def_stmt_out)
     *def_stmt_out = NULL;
   *dt = vect_unknown_def_type;
@@ -10113,6 +10109,8 @@ vect_is_simple_use (tree operand, vec_in
 	      *dt = vect_unknown_def_type;
 	      break;
 	    }
+	  if (def_stmt_info_out)
+	    *def_stmt_info_out = stmt_vinfo;
 	}
       if (def_stmt_out)
 	*def_stmt_out = def_stmt;
@@ -10175,14 +10173,18 @@ vect_is_simple_use (tree operand, vec_in
 
 bool
 vect_is_simple_use (tree operand, vec_info *vinfo, enum vect_def_type *dt,
-		    tree *vectype, gimple **def_stmt_out)
+		    tree *vectype, stmt_vec_info *def_stmt_info_out,
+		    gimple **def_stmt_out)
 {
+  stmt_vec_info def_stmt_info;
   gimple *def_stmt;
-  if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt))
+  if (!vect_is_simple_use (operand, vinfo, dt, &def_stmt_info, &def_stmt))
     return false;
 
   if (def_stmt_out)
     *def_stmt_out = def_stmt;
+  if (def_stmt_info_out)
+    *def_stmt_info_out = def_stmt_info;
 
   /* Now get a vector type if the def is internal, otherwise supply
      NULL_TREE and leave it up to the caller to figure out a proper
@@ -10193,8 +10195,7 @@ vect_is_simple_use (tree operand, vec_in
       || *dt == vect_double_reduction_def
       || *dt == vect_nested_cycle)
     {
-      stmt_vec_info stmt_info = vinfo_for_stmt (def_stmt);
-      *vectype = STMT_VINFO_VECTYPE (stmt_info);
+      *vectype = STMT_VINFO_VECTYPE (def_stmt_info);
       gcc_assert (*vectype != NULL_TREE);
       if (dump_enabled_p ())
 	{
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	2018-07-24 10:22:33.821278677 +0100
+++ gcc/tree-vect-loop.c	2018-07-24 10:22:37.253248202 +0100
@@ -6090,7 +6090,6 @@ vectorizable_reduction (gimple *stmt, gi
   int op_type;
   optab optab;
   tree new_temp = NULL_TREE;
-  gimple *def_stmt;
   enum vect_def_type dt, cond_reduc_dt = vect_unknown_def_type;
   gimple *cond_reduc_def_stmt = NULL;
   enum tree_code cond_reduc_op_code = ERROR_MARK;
@@ -6324,13 +6323,14 @@ vectorizable_reduction (gimple *stmt, gi
       if (i == 0 && code == COND_EXPR)
         continue;
 
-      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo,
-					  &dts[i], &tem, &def_stmt);
+      stmt_vec_info def_stmt_info;
+      is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &dts[i], &tem,
+					  &def_stmt_info);
       dt = dts[i];
       gcc_assert (is_simple_use);
       if (dt == vect_reduction_def)
 	{
-          reduc_def_stmt = def_stmt;
+	  reduc_def_stmt = def_stmt_info;
 	  reduc_index = i;
 	  continue;
 	}
@@ -6352,11 +6352,11 @@ vectorizable_reduction (gimple *stmt, gi
 	return false;
 
       if (dt == vect_nested_cycle)
-        {
-          found_nested_cycle_def = true;
-          reduc_def_stmt = def_stmt;
-          reduc_index = i;
-        }
+	{
+	  found_nested_cycle_def = true;
+	  reduc_def_stmt = def_stmt_info;
+	  reduc_index = i;
+	}
 
       if (i == 1 && code == COND_EXPR)
 	{
@@ -6367,11 +6367,11 @@ vectorizable_reduction (gimple *stmt, gi
 	      cond_reduc_val = ops[i];
 	    }
 	  if (dt == vect_induction_def
-	      && def_stmt != NULL
-	      && is_nonwrapping_integer_induction (def_stmt, loop))
+	      && def_stmt_info
+	      && is_nonwrapping_integer_induction (def_stmt_info, loop))
 	    {
 	      cond_reduc_dt = dt;
-	      cond_reduc_def_stmt = def_stmt;
+	      cond_reduc_def_stmt = def_stmt_info;
 	    }
 	}
     }
@@ -7958,7 +7958,7 @@ vectorizable_live_operation (gimple *stm
   else
     {
       enum vect_def_type dt = STMT_VINFO_DEF_TYPE (stmt_info);
-      vec_lhs = vect_get_vec_def_for_operand_1 (stmt, dt);
+      vec_lhs = vect_get_vec_def_for_operand_1 (stmt_info, dt);
       gcc_checking_assert (ncopies == 1
 			   || !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo));
 
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	2018-07-24 10:22:33.825278642 +0100
+++ gcc/tree-vect-patterns.c	2018-07-24 10:22:37.253248202 +0100
@@ -250,7 +250,9 @@ type_conversion_p (tree name, gimple *us
   enum vect_def_type dt;
 
   stmt_vinfo = vinfo_for_stmt (use_stmt);
-  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, def_stmt))
+  stmt_vec_info def_stmt_info;
+  if (!vect_is_simple_use (name, stmt_vinfo->vinfo, &dt, &def_stmt_info,
+			   def_stmt))
     return false;
 
   if (dt != vect_internal_def
@@ -371,9 +373,10 @@ vect_look_through_possible_promotion (ve
   while (TREE_CODE (op) == SSA_NAME && INTEGRAL_TYPE_P (op_type))
     {
       /* See whether OP is simple enough to vectorize.  */
+      stmt_vec_info def_stmt_info;
       gimple *def_stmt;
       vect_def_type dt;
-      if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt))
+      if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt_info, &def_stmt))
 	break;
 
       /* If OP is the input of a demotion, skip over it to see whether
@@ -407,17 +410,15 @@ vect_look_through_possible_promotion (ve
 	 the cast is potentially vectorizable.  */
       if (!def_stmt)
 	break;
-      if (dt == vect_internal_def)
-	{
-	  caster = vinfo_for_stmt (def_stmt);
-	  /* Ignore pattern statements, since we don't link uses for them.  */
-	  if (single_use_p
-	      && !STMT_VINFO_RELATED_STMT (caster)
-	      && !has_single_use (res))
-	    *single_use_p = false;
-	}
-      else
-	caster = NULL;
+      caster = def_stmt_info;
+
+      /* Ignore pattern statements, since we don't link uses for them.  */
+      if (caster
+	  && single_use_p
+	  && !STMT_VINFO_RELATED_STMT (caster)
+	  && !has_single_use (res))
+	*single_use_p = false;
+
       gassign *assign = dyn_cast <gassign *> (def_stmt);
       if (!assign || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
 	break;
@@ -1988,7 +1989,8 @@ vect_recog_rotate_pattern (stmt_vec_info
       || !TYPE_UNSIGNED (type))
     return NULL;
 
-  if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt))
+  stmt_vec_info def_stmt_info;
+  if (!vect_is_simple_use (oprnd1, vinfo, &dt, &def_stmt_info, &def_stmt))
     return NULL;
 
   if (dt != vect_internal_def
Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c	2018-07-24 10:22:33.825278642 +0100
+++ gcc/tree-vect-slp.c	2018-07-24 10:22:37.253248202 +0100
@@ -303,7 +303,6 @@ vect_get_and_check_slp_defs (vec_info *v
   gimple *stmt = stmts[stmt_num];
   tree oprnd;
   unsigned int i, number_of_oprnds;
-  gimple *def_stmt;
   enum vect_def_type dt = vect_uninitialized_def;
   bool pattern = false;
   slp_oprnd_info oprnd_info;
@@ -357,7 +356,8 @@ vect_get_and_check_slp_defs (vec_info *v
 
       oprnd_info = (*oprnds_info)[i];
 
-      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt))
+      stmt_vec_info def_stmt_info;
+      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt_info))
 	{
 	  if (dump_enabled_p ())
 	    {
@@ -370,13 +370,10 @@ vect_get_and_check_slp_defs (vec_info *v
 	  return -1;
 	}
 
-      /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
-         from the pattern.  Check that all the stmts of the node are in the
-         pattern.  */
-      if (def_stmt && gimple_bb (def_stmt)
-	  && vect_stmt_in_region_p (vinfo, def_stmt)
-	  && vinfo_for_stmt (def_stmt)
-	  && is_pattern_stmt_p (vinfo_for_stmt (def_stmt)))
+      /* Check if DEF_STMT_INFO is a part of a pattern in LOOP and get
+	 the def stmt from the pattern.  Check that all the stmts of the
+	 node are in the pattern.  */
+      if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
         {
           pattern = true;
           if (!first && !oprnd_info->first_pattern
@@ -405,7 +402,7 @@ vect_get_and_check_slp_defs (vec_info *v
 	      return 1;
             }
 
-          dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt));
+	  dt = STMT_VINFO_DEF_TYPE (def_stmt_info);
 
           if (dt == vect_unknown_def_type)
             {
@@ -415,7 +412,7 @@ vect_get_and_check_slp_defs (vec_info *v
               return -1;
             }
 
-          switch (gimple_code (def_stmt))
+	  switch (gimple_code (def_stmt_info->stmt))
             {
             case GIMPLE_PHI:
             case GIMPLE_ASSIGN:
@@ -499,7 +496,7 @@ vect_get_and_check_slp_defs (vec_info *v
 	case vect_reduction_def:
 	case vect_induction_def:
 	case vect_internal_def:
-	  oprnd_info->def_stmts.quick_push (def_stmt);
+	  oprnd_info->def_stmts.quick_push (def_stmt_info);
 	  break;
 
 	default:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]