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>
|
2011-05-03 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
PR target/48723
|
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 cortex_a9_sched_adjust_cost (rtx, rtx, rtx, int *);
|
||||||
static bool xscale_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 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 enum machine_mode arm_preferred_simd_mode (enum machine_mode);
|
||||||
static bool arm_class_likely_spilled_p (reg_class_t);
|
static bool arm_class_likely_spilled_p (reg_class_t);
|
||||||
static bool arm_vector_alignment_reachable (const_tree type, bool is_packed);
|
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
|
#define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask
|
||||||
#undef TARGET_VECTOR_MODE_SUPPORTED_P
|
#undef TARGET_VECTOR_MODE_SUPPORTED_P
|
||||||
#define TARGET_VECTOR_MODE_SUPPORTED_P arm_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
|
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
|
||||||
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arm_preferred_simd_mode
|
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arm_preferred_simd_mode
|
||||||
#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
|
#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
|
||||||
|
@ -22453,6 +22457,20 @@ arm_vector_mode_supported_p (enum machine_mode mode)
|
||||||
return false;
|
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
|
/* Use the option -mvectorize-with-neon-quad to override the use of doubleword
|
||||||
registers when autovectorizing for Neon, at least until multiple vector
|
registers when autovectorizing for Neon, at least until multiple vector
|
||||||
widths are supported properly by the middle-end. */
|
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.
|
must have move patterns for this mode.
|
||||||
@end deftypefn
|
@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})
|
@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
|
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
|
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.
|
must have move patterns for this mode.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@hook TARGET_ARRAY_MODE_SUPPORTED_P
|
||||||
|
|
||||||
@hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
|
@hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
|
||||||
Define this to return nonzero for machine modes for which the port has
|
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
|
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;
|
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. */
|
/* Generic hook that takes (FILE *, const char *) and does nothing. */
|
||||||
void
|
void
|
||||||
hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED)
|
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_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_false (enum machine_mode, rtx);
|
||||||
extern bool hook_bool_mode_rtx_true (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_tree_false (tree);
|
||||||
extern bool hook_bool_const_tree_false (const_tree);
|
extern bool hook_bool_const_tree_false (const_tree);
|
||||||
extern bool hook_bool_tree_true (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 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.
|
/* Subroutine of layout_decl: Force alignment required for the data type.
|
||||||
But if the decl itself wants greater alignment, don't override that. */
|
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_MODE (TREE_TYPE (type)) != BLKmode
|
||||||
|| TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
|
|| TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
|
||||||
{
|
{
|
||||||
/* One-element arrays get the component type's mode. */
|
SET_TYPE_MODE (type, mode_for_array (TREE_TYPE (type),
|
||||||
if (simple_cst_equal (TYPE_SIZE (type),
|
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));
|
|
||||||
|
|
||||||
if (TYPE_MODE (type) != BLKmode
|
if (TYPE_MODE (type) != BLKmode
|
||||||
&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
|
&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
|
||||||
&& TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
|
&& TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
|
||||||
|
|
|
@ -1565,6 +1565,38 @@ DEFHOOK
|
||||||
bool, (enum machine_mode mode),
|
bool, (enum machine_mode mode),
|
||||||
hook_bool_mode_false)
|
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
|
/* Compute cost of moving data from a register of class FROM to one of
|
||||||
TO, using MODE. */
|
TO, using MODE. */
|
||||||
DEFHOOK
|
DEFHOOK
|
||||||
|
|
Loading…
Reference in New Issue