aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2017-05-08 17:44:36 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2017-05-08 17:44:36 +0000
commit29eb9a442b145c3b637e7b41000e51148969c989 (patch)
tree25451e4bef78a2286c4eb70717dba908095ae3b5 /gcc
parent9057edd30c40ea77707650699f38734eb949b7d6 (diff)
downloadgcc-29eb9a442b145c3b637e7b41000e51148969c989.zip
gcc-29eb9a442b145c3b637e7b41000e51148969c989.tar.gz
gcc-29eb9a442b145c3b637e7b41000e51148969c989.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/arm/arm.c34
-rw-r--r--gcc/doc/tm.texi9
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/lra-eliminations.c2
-rw-r--r--gcc/reload1.c2
-rw-r--r--gcc/target.def12
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 <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.
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 < &reg_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 < &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);
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,