diff mbox series

[1/4] Give the target more control over ARRAY_TYPE modes

Message ID 87y3ngx0rs.fsf@linaro.org
State New
Headers show
Series Add SVE support for load/store_lanes | expand

Commit Message

Richard Sandiford Nov. 8, 2017, 3:12 p.m. UTC
So far we've used integer modes for LD[234] and ST[234] arrays.
That doesn't scale well to SVE, since the sizes aren't fixed at
compile time (and even if they were, we wouldn't want integers
to be so wide).

This patch lets the target use double-, triple- and quadruple-length
vectors instead.


2017-11-08  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* target.def (array_mode): New target hook.
	* doc/tm.texi.in (TARGET_ARRAY_MODE): New hook.
	* doc/tm.texi: Regenerate.
	* hooks.h (hook_optmode_mode_uhwi_none): Declare.
	* hooks.c (hook_optmode_mode_uhwi_none): New function.
	* tree-vect-data-refs.c (vect_lanes_optab_supported_p): Use
	targetm.array_mode.
	* stor-layout.c (mode_for_array): Likewise.  Support polynomial
	type sizes.

Comments

Jeff Law Nov. 21, 2017, 4:25 p.m. UTC | #1
On 11/08/2017 08:12 AM, Richard Sandiford wrote:
> So far we've used integer modes for LD[234] and ST[234] arrays.

> That doesn't scale well to SVE, since the sizes aren't fixed at

> compile time (and even if they were, we wouldn't want integers

> to be so wide).

> 

> This patch lets the target use double-, triple- and quadruple-length

> vectors instead.

> 

> 

> 2017-11-08  Richard Sandiford  <richard.sandiford@linaro.org>

> 	    Alan Hayward  <alan.hayward@arm.com>

> 	    David Sherwood  <david.sherwood@arm.com>

> 

> gcc/

> 	* target.def (array_mode): New target hook.

> 	* doc/tm.texi.in (TARGET_ARRAY_MODE): New hook.

> 	* doc/tm.texi: Regenerate.

> 	* hooks.h (hook_optmode_mode_uhwi_none): Declare.

> 	* hooks.c (hook_optmode_mode_uhwi_none): New function.

> 	* tree-vect-data-refs.c (vect_lanes_optab_supported_p): Use

> 	targetm.array_mode.

> 	* stor-layout.c (mode_for_array): Likewise.  Support polynomial

> 	type sizes.

> 

Whoops.  I'd started, but not completed review on this one a few days ago.

OK.  I think this covers the target independent bits from the series, right?

jeff
diff mbox series

Patch

Index: gcc/target.def
===================================================================
--- gcc/target.def	2017-11-08 15:05:33.783582091 +0000
+++ gcc/target.def	2017-11-08 15:06:16.086850270 +0000
@@ -3400,6 +3400,22 @@  the vector element type.",
  HOST_WIDE_INT, (const_tree type),
  default_vector_alignment)
 
+DEFHOOK
+(array_mode,
+ "Return the mode that GCC should use for an array that has\n\
+@var{nelems} elements, with each element having mode @var{mode}.\n\
+Return no mode if the target has no special requirements.  In the\n\
+latter case, GCC looks for an integer mode of the appropriate size\n\
+if available and uses BLKmode otherwise.  Usually the search for the\n\
+integer mode is limited to @code{MAX_FIXED_MODE_SIZE}, but the\n\
+@code{TARGET_ARRAY_MODE_SUPPORTED_P} hook allows a larger mode to be\n\
+used in specific cases.\n\
+\n\
+The main use of this hook is to specify that an array of vectors should\n\
+also have a vector mode.  The default implementation returns no mode.",
+ opt_machine_mode, (machine_mode mode, unsigned HOST_WIDE_INT nelems),
+ hook_optmode_mode_uhwi_none)
+
 /* True if we should try to use a scalar mode to represent an array,
    overriding the usual MAX_FIXED_MODE limit.  */
 DEFHOOK
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	2017-11-08 15:05:32.663824754 +0000
+++ gcc/doc/tm.texi.in	2017-11-08 15:06:16.085850270 +0000
@@ -3322,6 +3322,8 @@  stack.
 
 @hook TARGET_VECTOR_MODE_SUPPORTED_P
 
+@hook TARGET_ARRAY_MODE
+
 @hook TARGET_ARRAY_MODE_SUPPORTED_P
 
 @hook TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	2017-11-08 15:05:33.777173014 +0000
+++ gcc/doc/tm.texi	2017-11-08 15:06:16.084850270 +0000
@@ -4243,6 +4243,20 @@  insns involving vector mode @var{mode}.
 must have move patterns for this mode.
 @end deftypefn
 
+@deftypefn {Target Hook} opt_machine_mode TARGET_ARRAY_MODE (machine_mode @var{mode}, unsigned HOST_WIDE_INT @var{nelems})
+Return the mode that GCC should use for an array that has
+@var{nelems} elements, with each element having mode @var{mode}.
+Return no mode if the target has no special requirements.  In the
+latter case, GCC looks for an integer mode of the appropriate size
+if available and uses BLKmode otherwise.  Usually the search for the
+integer mode is limited to @code{MAX_FIXED_MODE_SIZE}, but the
+@code{TARGET_ARRAY_MODE_SUPPORTED_P} hook allows a larger mode to be
+used in specific cases.
+
+The main use of this hook is to specify that an array of vectors should
+also have a vector mode.  The default implementation returns no mode.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_ARRAY_MODE_SUPPORTED_P (machine_mode @var{mode}, unsigned HOST_WIDE_INT @var{nelems})
 Return true if GCC should try to use a scalar mode to store an array
 of @var{nelems} elements, given that each element has mode @var{mode}.
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h	2017-11-08 15:05:32.622623544 +0000
+++ gcc/hooks.h	2017-11-08 15:06:16.085850270 +0000
@@ -124,4 +124,7 @@  extern const char *hook_constcharptr_con
 extern const char *hook_constcharptr_const_tree_const_tree_null (const_tree, const_tree);
 extern const char *hook_constcharptr_int_const_tree_null (int, const_tree);
 extern const char *hook_constcharptr_int_const_tree_const_tree_null (int, const_tree, const_tree);
+
+extern opt_machine_mode hook_optmode_mode_uhwi_none (machine_mode,
+						     unsigned HOST_WIDE_INT);
 #endif
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c	2017-11-08 15:05:32.622623544 +0000
+++ gcc/hooks.c	2017-11-08 15:06:16.085850270 +0000
@@ -525,3 +525,11 @@  hook_bool_mode_reg_class_t_reg_class_t_f
   return false;
 }
 
+/* Generic hook that takes a mode and an unsigned HOST_WIDE_INT and
+   returns no mode.  */
+
+opt_machine_mode
+hook_optmode_mode_uhwi_none (machine_mode, unsigned HOST_WIDE_INT)
+{
+  return opt_machine_mode ();
+}
Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c	2017-11-08 15:05:36.346297369 +0000
+++ gcc/tree-vect-data-refs.c	2017-11-08 15:06:16.087850270 +0000
@@ -60,20 +60,23 @@  Software Foundation; either version 3, o
 vect_lanes_optab_supported_p (const char *name, convert_optab optab,
 			      tree vectype, unsigned HOST_WIDE_INT count)
 {
-  machine_mode mode;
-  scalar_int_mode array_mode;
+  machine_mode mode, array_mode;
   bool limit_p;
 
   mode = TYPE_MODE (vectype);
-  limit_p = !targetm.array_mode_supported_p (mode, count);
-  if (!int_mode_for_size (count * GET_MODE_BITSIZE (mode),
-			  limit_p).exists (&array_mode))
+  if (!targetm.array_mode (mode, count).exists (&array_mode))
     {
-      if (dump_enabled_p ())
-	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                         "no array mode for %s[" HOST_WIDE_INT_PRINT_DEC "]\n",
-                         GET_MODE_NAME (mode), count);
-      return false;
+      poly_uint64 bits = count * GET_MODE_BITSIZE (mode);
+      limit_p = !targetm.array_mode_supported_p (mode, count);
+      if (!int_mode_for_size (bits, limit_p).exists (&array_mode))
+	{
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			     "no array mode for %s["
+			     HOST_WIDE_INT_PRINT_DEC "]\n",
+			     GET_MODE_NAME (mode), count);
+	  return false;
+	}
     }
 
   if (convert_optab_handler (optab, array_mode, mode) == CODE_FOR_nothing)
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c	2017-11-08 15:05:36.974386931 +0000
+++ gcc/stor-layout.c	2017-11-08 15:06:16.086850270 +0000
@@ -545,7 +545,8 @@  get_mode_alignment (machine_mode mode)
 mode_for_array (tree elem_type, tree size)
 {
   tree elem_size;
-  unsigned HOST_WIDE_INT int_size, int_elem_size;
+  poly_uint64 int_size, int_elem_size;
+  unsigned HOST_WIDE_INT num_elems;
   bool limit_p;
 
   /* One-element arrays get the component type's mode.  */
@@ -554,14 +555,16 @@  mode_for_array (tree elem_type, tree siz
     return TYPE_MODE (elem_type);
 
   limit_p = true;
-  if (tree_fits_uhwi_p (size) && tree_fits_uhwi_p (elem_size))
+  if (poly_int_tree_p (size, &int_size)
+      && poly_int_tree_p (elem_size, &int_elem_size)
+      && may_ne (int_elem_size, 0U)
+      && constant_multiple_p (int_size, int_elem_size, &num_elems))
     {
-      int_size = tree_to_uhwi (size);
-      int_elem_size = tree_to_uhwi (elem_size);
-      if (int_elem_size > 0
-	  && int_size % int_elem_size == 0
-	  && targetm.array_mode_supported_p (TYPE_MODE (elem_type),
-					     int_size / int_elem_size))
+      machine_mode elem_mode = TYPE_MODE (elem_type);
+      machine_mode mode;
+      if (targetm.array_mode (elem_mode, num_elems).exists (&mode))
+	return mode;
+      if (targetm.array_mode_supported_p (elem_mode, num_elems))
 	limit_p = false;
     }
   return mode_for_size_tree (size, MODE_INT, limit_p).else_blk ();