diff options
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 14 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/hooks.c | 8 | ||||
-rw-r--r-- | gcc/hooks.h | 3 | ||||
-rw-r--r-- | gcc/stor-layout.c | 19 | ||||
-rw-r--r-- | gcc/target.def | 16 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 23 |
8 files changed, 81 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d965d8f..ed20d31 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,20 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * 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. + +2018-01-13 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * fold-const.c (fold_binary_loc): Check the argument types rather than the result type when testing for a vector operation. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 4cd8dce..25b0a1b 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4250,6 +4250,20 @@ insns involving vector mode @var{mode}. At the very least, it 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}. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 3a2c2f2..b0ac8b2 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3329,6 +3329,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 diff --git a/gcc/hooks.c b/gcc/hooks.c index 90d74bb..6171960 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -525,3 +525,11 @@ hook_bool_mode_reg_class_t_reg_class_t_false (machine_mode, reg_class_t, 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 (); +} diff --git a/gcc/hooks.h b/gcc/hooks.h index d6c894f..8caedd4 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -124,4 +124,7 @@ extern const char *hook_constcharptr_const_rtx_insn_null (const rtx_insn *); 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 diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 58ebd6c..0f65e16 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -546,7 +546,8 @@ static machine_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. */ @@ -555,14 +556,16 @@ mode_for_array (tree elem_type, tree size) 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) + && maybe_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 (); diff --git a/gcc/target.def b/gcc/target.def index 0a4f5fe..783ac99 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3426,6 +3426,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 diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index eb82594..759c1e3 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -61,20 +61,23 @@ static bool 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) |