aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2011-05-03 07:46:10 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2011-05-03 07:46:10 +0000
commit0f6d54f720796f2ebcb15764ac0d0b174529367d (patch)
tree0a9929f4d33aeb581d3ef899196493bcc28993e8
parentb15eacc7da352ad393b29bd35b71019f1da2af7d (diff)
downloadgcc-0f6d54f720796f2ebcb15764ac0d0b174529367d.zip
gcc-0f6d54f720796f2ebcb15764ac0d0b174529367d.tar.gz
gcc-0f6d54f720796f2ebcb15764ac0d0b174529367d.tar.bz2
hooks.h (hook_bool_mode_uhwi_false): Declare.
gcc/ * hooks.h (hook_bool_mode_uhwi_false): Declare. * hooks.c (hook_bool_mode_uhwi_false): New function. * target.def (array_mode_supported_p): New hook. * doc/tm.texi.in (TARGET_ARRAY_MODE_SUPPORTED_P): Add @hook. * doc/tm.texi: Regenerate. * stor-layout.c (mode_for_array): New function. (layout_type): Use it. * config/arm/arm.c (arm_array_mode_supported_p): New function. (TARGET_ARRAY_MODE_SUPPORTED_P): Define. From-SVN: r173290
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/arm/arm.c18
-rw-r--r--gcc/doc/tm.texi28
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/hooks.c9
-rw-r--r--gcc/hooks.h2
-rw-r--r--gcc/stor-layout.c38
-rw-r--r--gcc/target.def32
8 files changed, 133 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 043f73a..f67a0db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2011-05-03 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * hooks.h (hook_bool_mode_uhwi_false): Declare.
+ * hooks.c (hook_bool_mode_uhwi_false): New function.
+ * target.def (array_mode_supported_p): New hook.
+ * doc/tm.texi.in (TARGET_ARRAY_MODE_SUPPORTED_P): Add @hook.
+ * doc/tm.texi: Regenerate.
+ * stor-layout.c (mode_for_array): New function.
+ (layout_type): Use it.
+ * config/arm/arm.c (arm_array_mode_supported_p): New function.
+ (TARGET_ARRAY_MODE_SUPPORTED_P): Define.
+
2011-05-03 Eric Botcazou <ebotcazou@adacore.com>
PR target/48723
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1affbd3..4f9c2aa 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -243,6 +243,8 @@ static rtx arm_pic_static_addr (rtx orig, rtx reg);
static bool cortex_a9_sched_adjust_cost (rtx, rtx, rtx, int *);
static bool xscale_sched_adjust_cost (rtx, rtx, rtx, int *);
static bool fa726te_sched_adjust_cost (rtx, rtx, rtx, int *);
+static bool arm_array_mode_supported_p (enum machine_mode,
+ unsigned HOST_WIDE_INT);
static enum machine_mode arm_preferred_simd_mode (enum machine_mode);
static bool arm_class_likely_spilled_p (reg_class_t);
static bool arm_vector_alignment_reachable (const_tree type, bool is_packed);
@@ -399,6 +401,8 @@ static const struct default_options arm_option_optimization_table[] =
#define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P arm_vector_mode_supported_p
+#undef TARGET_ARRAY_MODE_SUPPORTED_P
+#define TARGET_ARRAY_MODE_SUPPORTED_P arm_array_mode_supported_p
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arm_preferred_simd_mode
#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
@@ -22453,6 +22457,20 @@ arm_vector_mode_supported_p (enum machine_mode mode)
return false;
}
+/* Implements target hook array_mode_supported_p. */
+
+static bool
+arm_array_mode_supported_p (enum machine_mode mode,
+ unsigned HOST_WIDE_INT nelems)
+{
+ if (TARGET_NEON
+ && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode))
+ && (nelems >= 2 && nelems <= 4))
+ return true;
+
+ return false;
+}
+
/* Use the option -mvectorize-with-neon-quad to override the use of doubleword
registers when autovectorizing for Neon, at least until multiple vector
widths are supported properly by the middle-end. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a89d0ec..7351e83 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4277,6 +4277,34 @@ insns involving vector mode @var{mode}. At the very least, it
must have move patterns for this mode.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_ARRAY_MODE_SUPPORTED_P (enum 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}.
+Returning true here overrides the usual @code{MAX_FIXED_MODE} limit
+and allows GCC to use any defined integer mode.
+
+One use of this hook is to support vector load and store operations
+that operate on several homogeneous vectors. For example, ARM NEON
+has operations like:
+
+@smallexample
+int8x8x3_t vld3_s8 (const int8_t *)
+@end smallexample
+
+where the return type is defined as:
+
+@smallexample
+typedef struct int8x8x3_t
+@{
+ int8x8_t val[3];
+@} int8x8x3_t;
+@end smallexample
+
+If this hook allows @code{val} to have a scalar mode, then
+@code{int8x8x3_t} can have the same mode. GCC can then store
+@code{int8x8x3_t}s in registers rather than forcing them onto the stack.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P (enum machine_mode @var{mode})
Define this to return nonzero for machine modes for which the port has
small register classes. If this target hook returns nonzero for a given
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 4637088..45d5982 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4263,6 +4263,8 @@ insns involving vector mode @var{mode}. At the very least, it
must have move patterns for this mode.
@end deftypefn
+@hook TARGET_ARRAY_MODE_SUPPORTED_P
+
@hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
Define this to return nonzero for machine modes for which the port has
small register classes. If this target hook returns nonzero for a given
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 7791a14..9dfde82 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -117,6 +117,15 @@ hook_bool_mode_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED,
return true;
}
+/* Generic hook that takes (enum machine_mode, unsigned HOST_WIDE_INT)
+ and returns false. */
+bool
+hook_bool_mode_uhwi_false (enum machine_mode mode ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT value ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
/* Generic hook that takes (FILE *, const char *) and does nothing. */
void
hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED)
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 11dd7a9..a1b0112 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -36,6 +36,8 @@ extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx);
extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx);
extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx);
extern bool hook_bool_mode_rtx_true (enum machine_mode, rtx);
+extern bool hook_bool_mode_uhwi_false (enum machine_mode,
+ unsigned HOST_WIDE_INT);
extern bool hook_bool_tree_false (tree);
extern bool hook_bool_const_tree_false (const_tree);
extern bool hook_bool_tree_true (tree);
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index ea0d44d..62de10d 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -546,6 +546,34 @@ get_mode_alignment (enum machine_mode mode)
return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
}
+/* Return the natural mode of an array, given that it is SIZE bytes in
+ total and has elements of type ELEM_TYPE. */
+
+static enum machine_mode
+mode_for_array (tree elem_type, tree size)
+{
+ tree elem_size;
+ unsigned HOST_WIDE_INT int_size, int_elem_size;
+ bool limit_p;
+
+ /* One-element arrays get the component type's mode. */
+ elem_size = TYPE_SIZE (elem_type);
+ if (simple_cst_equal (size, elem_size))
+ return TYPE_MODE (elem_type);
+
+ limit_p = true;
+ if (host_integerp (size, 1) && host_integerp (elem_size, 1))
+ {
+ int_size = tree_low_cst (size, 1);
+ int_elem_size = tree_low_cst (elem_size, 1);
+ 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))
+ limit_p = false;
+ }
+ return mode_for_size_tree (size, MODE_INT, limit_p);
+}
/* Subroutine of layout_decl: Force alignment required for the data type.
But if the decl itself wants greater alignment, don't override that. */
@@ -2040,14 +2068,8 @@ layout_type (tree type)
&& (TYPE_MODE (TREE_TYPE (type)) != BLKmode
|| TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
{
- /* One-element arrays get the component type's mode. */
- if (simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (type))))
- SET_TYPE_MODE (type, TYPE_MODE (TREE_TYPE (type)));
- else
- SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type),
- MODE_INT, 1));
-
+ SET_TYPE_MODE (type, mode_for_array (TREE_TYPE (type),
+ TYPE_SIZE (type)));
if (TYPE_MODE (type) != BLKmode
&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
&& TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
diff --git a/gcc/target.def b/gcc/target.def
index ea4d3e9..754713f 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1565,6 +1565,38 @@ DEFHOOK
bool, (enum machine_mode mode),
hook_bool_mode_false)
+/* True if we should try to use a scalar mode to represent an array,
+ overriding the usual MAX_FIXED_MODE limit. */
+DEFHOOK
+(array_mode_supported_p,
+ "Return true if GCC should try to use a scalar mode to store an array\n\
+of @var{nelems} elements, given that each element has mode @var{mode}.\n\
+Returning true here overrides the usual @code{MAX_FIXED_MODE} limit\n\
+and allows GCC to use any defined integer mode.\n\
+\n\
+One use of this hook is to support vector load and store operations\n\
+that operate on several homogeneous vectors. For example, ARM NEON\n\
+has operations like:\n\
+\n\
+@smallexample\n\
+int8x8x3_t vld3_s8 (const int8_t *)\n\
+@end smallexample\n\
+\n\
+where the return type is defined as:\n\
+\n\
+@smallexample\n\
+typedef struct int8x8x3_t\n\
+@{\n\
+ int8x8_t val[3];\n\
+@} int8x8x3_t;\n\
+@end smallexample\n\
+\n\
+If this hook allows @code{val} to have a scalar mode, then\n\
+@code{int8x8x3_t} can have the same mode. GCC can then store\n\
+@code{int8x8x3_t}s in registers rather than forcing them onto the stack.",
+ bool, (enum machine_mode mode, unsigned HOST_WIDE_INT nelems),
+ hook_bool_mode_uhwi_false)
+
/* Compute cost of moving data from a register of class FROM to one of
TO, using MODE. */
DEFHOOK