aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-13 17:57:25 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-13 17:57:25 +0000
commit695da53448dcc40e1e5db83bcf14d16217ffbd4a (patch)
tree653ae8366d4a3351466cfc904a7623b71b73a233 /gcc
parent779fed5fdb6098e67213a82dfd27f5b326a75e88 (diff)
downloadgcc-695da53448dcc40e1e5db83bcf14d16217ffbd4a.zip
gcc-695da53448dcc40e1e5db83bcf14d16217ffbd4a.tar.gz
gcc-695da53448dcc40e1e5db83bcf14d16217ffbd4a.tar.bz2
Give the target more control over ARRAY_TYPE modes
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. 2018-01-13 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. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r256617
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/doc/tm.texi14
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/hooks.c8
-rw-r--r--gcc/hooks.h3
-rw-r--r--gcc/stor-layout.c19
-rw-r--r--gcc/target.def16
-rw-r--r--gcc/tree-vect-data-refs.c23
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)