target.def (compute_frame_layout): New optional target hook.
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 8 May 2017 17:44:36 +0000 (17:44 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Mon, 8 May 2017 17:44:36 +0000 (17:44 +0000)
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

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/lra-eliminations.c
gcc/reload1.c
gcc/target.def

index 58693c5a4760b9c1a3236f4d9f5de31ba667c86d..dc2d9df83db907a202a23661fde1d6b497b3aa35 100644 (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.
index 55bfcd227888df67ea1945369169c2c4ff0f467a..3ae999cb723a234332bd1ca2e80b09df240c67f0 100644 (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;
 }
 
 
index c4f2c893c8e63b7c9df6626ca3a0710c6aad6933..2790dd6a5d5faea9b451fa05398e13960dd05e14 100644 (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
index 1c471d8da35f3640d9a34f4a760b4e25969a7ad0..dff6cf8e038701215ab81d0ac153231a68554adb 100644 (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
index 695f99ad317cba8a4546a735c7145fe7a315794b..ab51b6738261274e22779d677b503cd52eda6afc 100644 (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;
index 4dc118ef9f3364e54f84e4b82c972b9f5063ce6d..e993749a0000cf66bae14c9d8f6eec6e44555988 100644 (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);
index 6bebfd5b9d6b7001a19fd5a41700ac3667408c00..bd60484c4fdfacded2c7d68106328173b4ec571b 100644 (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,