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:
parent
b15eacc7da
commit
0f6d54f720
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue