===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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}.
===================================================================
@@ -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
===================================================================
@@ -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 ();
+}
===================================================================
@@ -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)
===================================================================
@@ -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 ();