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
This commit is contained in:
Richard Sandiford 2011-05-03 07:46:10 +00:00 committed by Richard Sandiford
parent b15eacc7da
commit 0f6d54f720
8 changed files with 133 additions and 8 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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)))

View File

@ -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