diff mbox series

Refactor vect_get_and_check_slp_defs some more

Message ID nycvar.YFH.7.76.2010161024001.26100@elmra.sevgm.obk
State New
Headers show
Series Refactor vect_get_and_check_slp_defs some more | expand

Commit Message

Richard Biener Oct. 16, 2020, 8:24 a.m. UTC
This refactors vect_get_and_check_slp_defs so that the ops and def_stmts
arrays are filled for all stmts and operands even when we signal failure.
This allows later changes for BB vectorization SLP discovery heuristics.

Bootstrapped / tested on x86_64-unknown-linux-gnu, pushed.

2020-10-16  Richard Biener  <rguenther@suse.de>

	* tree-vect-slp.c (vect_get_and_check_slp_defs): First analyze
	all operands and fill in the def_stmts and ops entries.
	(vect_def_types_match): New helper.
---
 gcc/tree-vect-slp.c | 141 ++++++++++++++++++++++++++------------------
 1 file changed, 82 insertions(+), 59 deletions(-)
diff mbox series

Patch

diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 8037b27cddd..cfb79e2651f 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -356,6 +356,16 @@  can_duplicate_and_interleave_p (vec_info *vinfo, unsigned int count,
     }
 }
 
+/* Return true if DTA and DTB match.  */
+
+static bool
+vect_def_types_match (enum vect_def_type dta, enum vect_def_type dtb)
+{
+  return (dta == dtb
+	  || ((dta == vect_external_def || dta == vect_constant_def)
+	      && (dtb == vect_external_def || dtb == vect_constant_def)));
+}
+
 /* Get the defs for the rhs of STMT (collect them in OPRNDS_INFO), check that
    they are of a valid type and that they match the defs of the first stmt of
    the SLP group (stored in OPRNDS_INFO).  This function tries to match stmts
@@ -421,9 +431,9 @@  vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char swap,
 
   bool swapped = (swap != 0);
   gcc_assert (!swapped || first_op_cond);
+  enum vect_def_type *dts = XALLOCAVEC (enum vect_def_type, number_of_oprnds);
   for (i = 0; i < number_of_oprnds; i++)
     {
-again:
       if (first_op_cond)
 	{
 	  /* Map indicating how operands of cond_expr should be swapped.  */
@@ -444,7 +454,7 @@  again:
       oprnd_info = (*oprnds_info)[i];
 
       stmt_vec_info def_stmt_info;
-      if (!vect_is_simple_use (oprnd, vinfo, &dt, &def_stmt_info))
+      if (!vect_is_simple_use (oprnd, vinfo, &dts[i], &def_stmt_info))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -457,9 +467,13 @@  again:
       if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
 	oprnd_info->any_pattern = true;
 
-      tree type = TREE_TYPE (oprnd);
+      oprnd_info->def_stmts.quick_push (def_stmt_info);
+      oprnd_info->ops.quick_push (oprnd);
+
       if (first)
 	{
+	  tree type = TREE_TYPE (oprnd);
+	  dt = dts[i];
 	  if ((dt == vect_constant_def
 	       || dt == vect_external_def)
 	      && !GET_MODE_SIZE (vinfo->vector_mode).is_constant ()
@@ -480,14 +494,48 @@  again:
 	      && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
 	      && (int)i == STMT_VINFO_REDUC_IDX (stmt_info)
 	      && def_stmt_info)
-	    dt = vect_reduction_def;
+	    dts[i] = dt = vect_reduction_def;
+
+	  /* Check the types of the definition.  */
+	  switch (dt)
+	    {
+	    case vect_external_def:
+	    case vect_constant_def:
+	    case vect_internal_def:
+	    case vect_reduction_def:
+	    case vect_induction_def:
+	      break;
+
+	    default:
+	      /* FORNOW: Not supported.  */
+	      if (dump_enabled_p ())
+		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+				 "Build SLP failed: illegal type of def %T\n",
+				 oprnd);
+	      return -1;
+	    }
+
 	  oprnd_info->first_dt = dt;
 	  oprnd_info->first_op_type = type;
 	}
-      else
-	{
+    }
+  if (first)
+    return 0;
+
+  /* Now match the operand definition types to that of the first stmt.  */
+  for (i = 0; i < number_of_oprnds;)
+    {
+      oprnd_info = (*oprnds_info)[i];
+      dt = dts[i];
+      stmt_vec_info def_stmt_info = oprnd_info->def_stmts[stmt_num];
+      oprnd = oprnd_info->ops[stmt_num];
+      tree type = TREE_TYPE (oprnd);
+
 	  if (!types_compatible_p (oprnd_info->first_op_type, type))
 	    {
+	      gcc_assert ((i != commutative_op
+			   && (commutative_op == -1U
+			       || i != commutative_op + 1)));
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 				 "Build SLP failed: different operand types\n");
@@ -499,18 +547,14 @@  again:
 	     types for reduction chains: the first stmt must be a
 	     vect_reduction_def (a phi node), and the rest
 	     end in the reduction chain.  */
-	  if ((oprnd_info->first_dt != dt
+	  if ((!vect_def_types_match (oprnd_info->first_dt, dt)
 	       && !(oprnd_info->first_dt == vect_reduction_def
 		    && !STMT_VINFO_DATA_REF (stmt_info)
 		    && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
 		    && def_stmt_info
 		    && !STMT_VINFO_DATA_REF (def_stmt_info)
 		    && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
-			== REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
-	       && !((oprnd_info->first_dt == vect_external_def
-		     || oprnd_info->first_dt == vect_constant_def)
-		    && (dt == vect_external_def
-			|| dt == vect_constant_def)))
+			== REDUC_GROUP_FIRST_ELEMENT (stmt_info))))
 	      || (!STMT_VINFO_DATA_REF (stmt_info)
 		  && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
 		  && ((!def_stmt_info
@@ -519,69 +563,48 @@  again:
 			   != REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
 		      != (oprnd_info->first_dt != vect_reduction_def))))
 	    {
-	      /* Try swapping operands if we got a mismatch.  */
+	      /* Try swapping operands if we got a mismatch.  For BB
+		 vectorization only in case that will improve things.  */
 	      if (i == commutative_op && !swapped)
 		{
 		  if (dump_enabled_p ())
 		    dump_printf_loc (MSG_NOTE, vect_location,
 				     "trying swapped operands\n");
+		  std::swap (dts[i], dts[i+1]);
+		  std::swap ((*oprnds_info)[i]->def_stmts[stmt_num],
+			     (*oprnds_info)[i+1]->def_stmts[stmt_num]);
+		  std::swap ((*oprnds_info)[i]->ops[stmt_num],
+			     (*oprnds_info)[i+1]->ops[stmt_num]);
 		  swapped = true;
-		  goto again;
+		  continue;
 		}
 
 	      if (dump_enabled_p ())
 		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
 				 "Build SLP failed: different types\n");
-
 	      return 1;
 	    }
-	}
 
-      /* Check the types of the definitions.  */
-      switch (dt)
+      /* Make sure to demote the overall operand to external.  */
+      if (dt == vect_external_def)
+	oprnd_info->first_dt = vect_external_def;
+      /* For a SLP reduction chain we want to duplicate the reduction to
+	 each of the chain members.  That gets us a sane SLP graph (still
+	 the stmts are not 100% correct wrt the initial values).  */
+      else if ((dt == vect_internal_def
+		|| dt == vect_reduction_def)
+	       && oprnd_info->first_dt == vect_reduction_def
+	       && !STMT_VINFO_DATA_REF (stmt_info)
+	       && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
+	       && !STMT_VINFO_DATA_REF (def_stmt_info)
+	       && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
+		   == REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
 	{
-	case vect_external_def:
-	  /* Make sure to demote the overall operand to external.  */
-	  oprnd_info->first_dt = vect_external_def;
-	  /* Fallthru.  */
-	case vect_constant_def:
-	  oprnd_info->def_stmts.quick_push (NULL);
-	  oprnd_info->ops.quick_push (oprnd);
-	  break;
-
-	case vect_internal_def:
-	case vect_reduction_def:
-	  if (oprnd_info->first_dt == vect_reduction_def
-	      && !STMT_VINFO_DATA_REF (stmt_info)
-	      && REDUC_GROUP_FIRST_ELEMENT (stmt_info)
-	      && !STMT_VINFO_DATA_REF (def_stmt_info)
-	      && (REDUC_GROUP_FIRST_ELEMENT (def_stmt_info)
-		  == REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
-	    {
-	      /* For a SLP reduction chain we want to duplicate the
-	         reduction to each of the chain members.  That gets
-		 us a sane SLP graph (still the stmts are not 100%
-		 correct wrt the initial values).  */
-	      gcc_assert (!first);
-	      oprnd_info->def_stmts.quick_push (oprnd_info->def_stmts[0]);
-	      oprnd_info->ops.quick_push (oprnd_info->ops[0]);
-	      break;
-	    }
-	  /* Fallthru.  */
-	case vect_induction_def:
-	  oprnd_info->def_stmts.quick_push (def_stmt_info);
-	  oprnd_info->ops.quick_push (oprnd);
-	  break;
-
-	default:
-	  /* FORNOW: Not supported.  */
-	  if (dump_enabled_p ())
-	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			     "Build SLP failed: illegal type of def %T\n",
-			     oprnd);
-
-	  return -1;
+	  oprnd_info->def_stmts[stmt_num] = oprnd_info->def_stmts[0];
+	  oprnd_info->ops[stmt_num] = oprnd_info->ops[0];
 	}
+
+      ++i;
     }
 
   /* Swap operands.  */