From 29eb9a442b145c3b637e7b41000e51148969c989 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 8 May 2017 17:44:36 +0000 Subject: [PATCH] target.def (compute_frame_layout): New optional target hook. 2017-05-08 Bernd Edlinger * 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 --- gcc/ChangeLog | 13 +++++++++++++ gcc/config/arm/arm.c | 34 +++++++++++++++++++++++++--------- gcc/doc/tm.texi | 9 +++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/lra-eliminations.c | 2 ++ gcc/reload1.c | 2 ++ gcc/target.def | 12 ++++++++++++ 7 files changed, 65 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 58693c5..dc2d9df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2017-05-08 Bernd Edlinger + + * 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 * config/aarch64/constraints.md (Usa): New constraint. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 55bfcd2..3ae999c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c4f2c89..2790dd6 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 1c471d8..dff6cf8 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -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 diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c index 695f99a..ab51b67 100644 --- a/gcc/lra-eliminations.c +++ b/gcc/lra-eliminations.c @@ -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 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) self_elim_offsets[ep->from] = 0; diff --git a/gcc/reload1.c b/gcc/reload1.c index 4dc118e..e993749 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -3821,6 +3821,7 @@ verify_initial_elim_offsets (void) if (!num_eliminable) return true; + targetm.compute_frame_layout (); for (ep = reg_eliminate; ep < ®_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 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) { INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset); diff --git a/gcc/target.def b/gcc/target.def index 6bebfd5..bd60484 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -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, -- 2.7.4