target.def (compute_frame_layout): New optional target hook.

2017-05-08  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        * target.def (compute_frame_layout): New optional target hook.
        * doc/tm.texi.in (TARGET_COMPUTE_FRAME_LAYOUT): Add hook.
        * doc/tm.texi (TARGET_COMPUTE_FRAME_LAYOUT): Add documentation.
        * lra-eliminations.c (update_reg_eliminate): Call compute_frame_layout
        target hook.
        * reload1.c (verify_initial_elim_offsets): Likewise.
        * config/arm/arm.c (TARGET_COMPUTE_FRAME_LAYOUT): Define.
        (use_simple_return_p): Call arm_compute_frame_layout if needed.
        (arm_get_frame_offsets): Split up into this ...
        (arm_compute_frame_layout): ... and this function.

From-SVN: r247750
This commit is contained in:
Bernd Edlinger 2017-05-08 17:44:36 +00:00 committed by Bernd Edlinger
parent 9057edd30c
commit 29eb9a442b
7 changed files with 65 additions and 9 deletions

View file

@ -1,3 +1,16 @@
2017-05-08 Bernd Edlinger <bernd.edlinger@hotmail.de>
* target.def (compute_frame_layout): New optional target hook.
* doc/tm.texi.in (TARGET_COMPUTE_FRAME_LAYOUT): Add hook.
* doc/tm.texi (TARGET_COMPUTE_FRAME_LAYOUT): Add documentation.
* lra-eliminations.c (update_reg_eliminate): Call compute_frame_layout
target hook.
* reload1.c (verify_initial_elim_offsets): Likewise.
* config/arm/arm.c (TARGET_COMPUTE_FRAME_LAYOUT): Define.
(use_simple_return_p): Call arm_compute_frame_layout if needed.
(arm_get_frame_offsets): Split up into this ...
(arm_compute_frame_layout): ... and this function.
2017-05-08 Richard Sandiford <richard.sandiford@arm.com>
* config/aarch64/constraints.md (Usa): New constraint.

View file

@ -85,6 +85,7 @@ static bool arm_const_not_ok_for_debug_p (rtx);
static int arm_needs_doubleword_align (machine_mode, const_tree);
static int arm_compute_static_chain_stack_bytes (void);
static arm_stack_offsets *arm_get_frame_offsets (void);
static void arm_compute_frame_layout (void);
static void arm_add_gc_roots (void);
static int arm_gen_constant (enum rtx_code, machine_mode, rtx,
unsigned HOST_WIDE_INT, rtx, rtx, int, int);
@ -680,6 +681,9 @@ static const struct attribute_spec arm_attribute_table[] =
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P arm_scalar_mode_supported_p
#undef TARGET_COMPUTE_FRAME_LAYOUT
#define TARGET_COMPUTE_FRAME_LAYOUT arm_compute_frame_layout
#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED arm_frame_pointer_required
@ -4031,6 +4035,10 @@ use_simple_return_p (void)
{
arm_stack_offsets *offsets;
/* Note this function can be called before or after reload. */
if (!reload_completed)
arm_compute_frame_layout ();
offsets = arm_get_frame_offsets ();
return offsets->outgoing_args != 0;
}
@ -19138,7 +19146,7 @@ arm_compute_static_chain_stack_bytes (void)
/* Compute a bit mask of which registers need to be
saved on the stack for the current function.
This is used by arm_get_frame_offsets, which may add extra registers. */
This is used by arm_compute_frame_layout, which may add extra registers. */
static unsigned long
arm_compute_save_reg_mask (void)
@ -20772,12 +20780,25 @@ any_sibcall_could_use_r3 (void)
alignment. */
/* Return cached stack offsets. */
static arm_stack_offsets *
arm_get_frame_offsets (void)
{
struct arm_stack_offsets *offsets;
offsets = &cfun->machine->stack_offsets;
return offsets;
}
/* Calculate stack offsets. These are used to calculate register elimination
offsets and in prologue/epilogue code. Also calculates which registers
should be saved. */
static arm_stack_offsets *
arm_get_frame_offsets (void)
static void
arm_compute_frame_layout (void)
{
struct arm_stack_offsets *offsets;
unsigned long func_type;
@ -20788,9 +20809,6 @@ arm_get_frame_offsets (void)
offsets = &cfun->machine->stack_offsets;
if (reload_completed)
return offsets;
/* Initially this is the size of the local variables. It will translated
into an offset once we have determined the size of preceding data. */
frame_size = ROUND_UP_WORD (get_frame_size ());
@ -20855,7 +20873,7 @@ arm_get_frame_offsets (void)
{
offsets->outgoing_args = offsets->soft_frame;
offsets->locals_base = offsets->soft_frame;
return offsets;
return;
}
/* Ensure SFP has the correct alignment. */
@ -20931,8 +20949,6 @@ arm_get_frame_offsets (void)
offsets->outgoing_args += 4;
gcc_assert (!(offsets->outgoing_args & 7));
}
return offsets;
}

View file

@ -3684,6 +3684,15 @@ such as the result of @code{get_frame_size ()} and the tables of
registers @code{df_regs_ever_live_p} and @code{call_used_regs}.
@end defmac
@deftypefn {Target Hook} void TARGET_COMPUTE_FRAME_LAYOUT (void)
This target hook is called once each time the frame layout needs to be
recalculated. The calculations can be cached by the target and can then
be used by @code{INITIAL_ELIMINATION_OFFSET} instead of re-computing the
layout on every invocation of that hook. This is particularly useful
for targets that have an expensive frame layout function. Implementing
this callback is optional.
@end deftypefn
@node Stack Arguments
@subsection Passing Function Arguments on the Stack
@cindex arguments on stack

View file

@ -3213,6 +3213,8 @@ such as the result of @code{get_frame_size ()} and the tables of
registers @code{df_regs_ever_live_p} and @code{call_used_regs}.
@end defmac
@hook TARGET_COMPUTE_FRAME_LAYOUT
@node Stack Arguments
@subsection Passing Function Arguments on the Stack
@cindex arguments on stack

View file

@ -1196,6 +1196,8 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
struct lra_elim_table *ep, *ep1;
HARD_REG_SET temp_hard_reg_set;
targetm.compute_frame_layout ();
/* Clear self elimination offsets. */
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
self_elim_offsets[ep->from] = 0;

View file

@ -3821,6 +3821,7 @@ verify_initial_elim_offsets (void)
if (!num_eliminable)
return true;
targetm.compute_frame_layout ();
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
@ -3838,6 +3839,7 @@ set_initial_elim_offsets (void)
{
struct elim_table *ep = reg_eliminate;
targetm.compute_frame_layout ();
for (; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset);

View file

@ -5395,6 +5395,18 @@ five otherwise. This is best for most machines.",
unsigned int, (void),
default_case_values_threshold)
/* Optional callback to advise the target to compute the frame layout. */
DEFHOOK
(compute_frame_layout,
"This target hook is called once each time the frame layout needs to be\n\
recalculated. The calculations can be cached by the target and can then\n\
be used by @code{INITIAL_ELIMINATION_OFFSET} instead of re-computing the\n\
layout on every invocation of that hook. This is particularly useful\n\
for targets that have an expensive frame layout function. Implementing\n\
this callback is optional.",
void, (void),
hook_void_void)
/* Return true if a function must have and use a frame pointer. */
DEFHOOK
(frame_pointer_required,