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]

Include phis in SLP unrolling calculation


Without this we'd pick an unrolling factor based purely on longs,
ignoring the ints.  It's posssible that vect_get_smallest_scalar_type
should also handle shifts, but I think we'd still want this as a
belt-and-braces fix.

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

Richard


2017-09-15  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* tree-vect-slp.c (vect_record_max_nunits): New function,
	split out from...
	(vect_build_slp_tree_1): ...here.
	(vect_build_slp_tree_2): Call it for phis too.

gcc/testsuite/
	* gcc.dg/vect/slp-multitypes-13.c: New test.

Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c	2017-09-15 11:35:46.833592065 +0100
+++ gcc/tree-vect-slp.c	2017-09-15 11:40:10.286573578 +0100
@@ -480,6 +480,48 @@ vect_get_and_check_slp_defs (vec_info *v
   return 0;
 }
 
+/* A subroutine of vect_build_slp_tree for checking VECTYPE, which is the
+   caller's attempt to find the vector type in STMT with the narrowest
+   element type.  Return true if VECTYPE is nonnull and if it is valid
+   for VINFO.  When returning true, update MAX_NUNITS to reflect the
+   number of units in VECTYPE.  VINFO, GORUP_SIZE and MAX_NUNITS are
+   as for vect_build_slp_tree.  */
+
+static bool
+vect_record_max_nunits (vec_info *vinfo, gimple *stmt, unsigned int group_size,
+			tree vectype, unsigned int *max_nunits)
+{
+  if (!vectype)
+    {
+      if (dump_enabled_p ())
+	{
+	  dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			   "Build SLP failed: unsupported data-type in ");
+	  dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+	  dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
+	}
+      /* Fatal mismatch.  */
+      return false;
+    }
+
+  /* If populating the vector type requires unrolling then fail
+     before adjusting *max_nunits for basic-block vectorization.  */
+  if (is_a <bb_vec_info> (vinfo)
+      && TYPE_VECTOR_SUBPARTS (vectype) > group_size)
+    {
+      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+		       "Build SLP failed: unrolling required "
+		       "in basic block SLP\n");
+      /* Fatal mismatch.  */
+      return false;
+    }
+
+  /* In case of multiple types we need to detect the smallest type.  */
+  if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
+    *max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
+
+  return true;
+}
 
 /* Verify if the scalar stmts STMTS are isomorphic, require data
    permutation or are of unsupported types of operation.  Return
@@ -560,38 +602,14 @@ vect_build_slp_tree_1 (vec_info *vinfo,
 
       scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy);
       vectype = get_vectype_for_scalar_type (scalar_type);
-      if (!vectype)
-        {
-          if (dump_enabled_p ())
-            {
-              dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
-			       "Build SLP failed: unsupported data-type ");
-              dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
-				 scalar_type);
-              dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
-            }
+      if (!vect_record_max_nunits (vinfo, stmt, group_size, vectype,
+				   max_nunits))
+	{
 	  /* Fatal mismatch.  */
 	  matches[0] = false;
           return false;
         }
 
-      /* If populating the vector type requires unrolling then fail
-         before adjusting *max_nunits for basic-block vectorization.  */
-      if (is_a <bb_vec_info> (vinfo)
-	  && TYPE_VECTOR_SUBPARTS (vectype) > group_size)
-	{
-	  dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
-			   "Build SLP failed: unrolling required "
-			   "in basic block SLP\n");
-	  /* Fatal mismatch.  */
-	  matches[0] = false;
-	  return false;
-	}
-
-      /* In case of multiple types we need to detect the smallest type.  */
-      if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
-	*max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
-
       if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
 	{
 	  rhs_code = CALL_EXPR;
@@ -1018,6 +1036,12 @@ vect_build_slp_tree_2 (vec_info *vinfo,
      the recursion.  */
   if (gimple_code (stmt) == GIMPLE_PHI)
     {
+      tree scalar_type = TREE_TYPE (PHI_RESULT (stmt));
+      tree vectype = get_vectype_for_scalar_type (scalar_type);
+      if (!vect_record_max_nunits (vinfo, stmt, group_size, vectype,
+				   max_nunits))
+	return NULL;
+
       vect_def_type def_type = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (stmt));
       /* Induction from different IVs is not supported.  */
       if (def_type == vect_induction_def)
Index: gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c
===================================================================
--- /dev/null	2017-09-15 10:12:35.472207962 +0100
+++ gcc/testsuite/gcc.dg/vect/slp-multitypes-13.c	2017-09-15 11:40:10.285573591 +0100
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+void
+f (long *x, int n)
+{
+  for (int i = 0; i < n; i++)
+    {
+      x[i * 2] = 1L << i;
+      x[i * 2 + 1] = 1L << i;
+    }
+}


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