explow: Allow dynamic allocations after vregs
Checks
Commit Message
This patch allows allocate_dynamic_stack_space to be called before
or after virtual registers have been instantiated. It uses the
same approach as allocate_stack_local, which already supported this.
Tested on aarch64-linux-gnu & x86_64-linux-gnu. OK to install?
Richard
gcc/
* function.h (get_stack_dynamic_offset): Declare.
* function.cc (get_stack_dynamic_offset): New function,
split out from...
(get_stack_dynamic_offset): ...here.
* explow.cc (allocate_dynamic_stack_space): Handle calls made
after virtual registers have been instantiated.
---
gcc/explow.cc | 10 +++++++---
gcc/function.cc | 12 +++++++++++-
gcc/function.h | 1 +
3 files changed, 19 insertions(+), 4 deletions(-)
Comments
On Sun, Nov 5, 2023 at 7:32 PM Richard Sandiford
<richard.sandiford@arm.com> wrote:
>
> This patch allows allocate_dynamic_stack_space to be called before
> or after virtual registers have been instantiated. It uses the
> same approach as allocate_stack_local, which already supported this.
>
> Tested on aarch64-linux-gnu & x86_64-linux-gnu. OK to install?
OK
> Richard
>
>
> gcc/
> * function.h (get_stack_dynamic_offset): Declare.
> * function.cc (get_stack_dynamic_offset): New function,
> split out from...
> (get_stack_dynamic_offset): ...here.
> * explow.cc (allocate_dynamic_stack_space): Handle calls made
> after virtual registers have been instantiated.
> ---
> gcc/explow.cc | 10 +++++++---
> gcc/function.cc | 12 +++++++++++-
> gcc/function.h | 1 +
> 3 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/explow.cc b/gcc/explow.cc
> index 0c03ac350bb..aa64d5e906c 100644
> --- a/gcc/explow.cc
> +++ b/gcc/explow.cc
> @@ -1375,12 +1375,16 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
> HOST_WIDE_INT stack_usage_size = -1;
> rtx_code_label *final_label;
> rtx final_target, target;
> + rtx addr = (virtuals_instantiated
> + ? plus_constant (Pmode, stack_pointer_rtx,
> + get_stack_dynamic_offset ())
> + : virtual_stack_dynamic_rtx);
>
> /* If we're asking for zero bytes, it doesn't matter what we point
> to since we can't dereference it. But return a reasonable
> address anyway. */
> if (size == const0_rtx)
> - return virtual_stack_dynamic_rtx;
> + return addr;
>
> /* Otherwise, show we're calling alloca or equivalent. */
> cfun->calls_alloca = 1;
> @@ -1532,7 +1536,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
> poly_int64 saved_stack_pointer_delta;
>
> if (!STACK_GROWS_DOWNWARD)
> - emit_move_insn (target, virtual_stack_dynamic_rtx);
> + emit_move_insn (target, force_operand (addr, target));
>
> /* Check stack bounds if necessary. */
> if (crtl->limit_stack)
> @@ -1575,7 +1579,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
> stack_pointer_delta = saved_stack_pointer_delta;
>
> if (STACK_GROWS_DOWNWARD)
> - emit_move_insn (target, virtual_stack_dynamic_rtx);
> + emit_move_insn (target, force_operand (addr, target));
> }
>
> suppress_reg_args_size = false;
> diff --git a/gcc/function.cc b/gcc/function.cc
> index afb0b33da9e..527ea4807b0 100644
> --- a/gcc/function.cc
> +++ b/gcc/function.cc
> @@ -1943,6 +1943,16 @@ instantiate_decls (tree fndecl)
> vec_free (cfun->local_decls);
> }
>
> +/* Return the value of STACK_DYNAMIC_OFFSET for the current function.
> + This is done through a function wrapper so that the macro sees a
> + predictable set of included files. */
> +
> +poly_int64
> +get_stack_dynamic_offset ()
> +{
> + return STACK_DYNAMIC_OFFSET (current_function_decl);
> +}
> +
> /* Pass through the INSNS of function FNDECL and convert virtual register
> references to hard register references. */
>
> @@ -1954,7 +1964,7 @@ instantiate_virtual_regs (void)
> /* Compute the offsets to use for this function. */
> in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
> var_offset = targetm.starting_frame_offset ();
> - dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
> + dynamic_offset = get_stack_dynamic_offset ();
> out_arg_offset = STACK_POINTER_OFFSET;
> #ifdef FRAME_POINTER_CFA_OFFSET
> cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
> diff --git a/gcc/function.h b/gcc/function.h
> index 5caf1e153ea..29846564bc6 100644
> --- a/gcc/function.h
> +++ b/gcc/function.h
> @@ -715,6 +715,7 @@ extern vec<edge> convert_jumps_to_returns (basic_block last_bb, bool simple_p,
> extern basic_block emit_return_for_exit (edge exit_fallthru_edge,
> bool simple_p);
> extern void reposition_prologue_and_epilogue_notes (void);
> +extern poly_int64 get_stack_dynamic_offset ();
>
> /* Returns the name of the current function. */
> extern const char *fndecl_name (tree);
> --
> 2.25.1
>
@@ -1375,12 +1375,16 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
HOST_WIDE_INT stack_usage_size = -1;
rtx_code_label *final_label;
rtx final_target, target;
+ rtx addr = (virtuals_instantiated
+ ? plus_constant (Pmode, stack_pointer_rtx,
+ get_stack_dynamic_offset ())
+ : virtual_stack_dynamic_rtx);
/* If we're asking for zero bytes, it doesn't matter what we point
to since we can't dereference it. But return a reasonable
address anyway. */
if (size == const0_rtx)
- return virtual_stack_dynamic_rtx;
+ return addr;
/* Otherwise, show we're calling alloca or equivalent. */
cfun->calls_alloca = 1;
@@ -1532,7 +1536,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
poly_int64 saved_stack_pointer_delta;
if (!STACK_GROWS_DOWNWARD)
- emit_move_insn (target, virtual_stack_dynamic_rtx);
+ emit_move_insn (target, force_operand (addr, target));
/* Check stack bounds if necessary. */
if (crtl->limit_stack)
@@ -1575,7 +1579,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
stack_pointer_delta = saved_stack_pointer_delta;
if (STACK_GROWS_DOWNWARD)
- emit_move_insn (target, virtual_stack_dynamic_rtx);
+ emit_move_insn (target, force_operand (addr, target));
}
suppress_reg_args_size = false;
@@ -1943,6 +1943,16 @@ instantiate_decls (tree fndecl)
vec_free (cfun->local_decls);
}
+/* Return the value of STACK_DYNAMIC_OFFSET for the current function.
+ This is done through a function wrapper so that the macro sees a
+ predictable set of included files. */
+
+poly_int64
+get_stack_dynamic_offset ()
+{
+ return STACK_DYNAMIC_OFFSET (current_function_decl);
+}
+
/* Pass through the INSNS of function FNDECL and convert virtual register
references to hard register references. */
@@ -1954,7 +1964,7 @@ instantiate_virtual_regs (void)
/* Compute the offsets to use for this function. */
in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
var_offset = targetm.starting_frame_offset ();
- dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
+ dynamic_offset = get_stack_dynamic_offset ();
out_arg_offset = STACK_POINTER_OFFSET;
#ifdef FRAME_POINTER_CFA_OFFSET
cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
@@ -715,6 +715,7 @@ extern vec<edge> convert_jumps_to_returns (basic_block last_bb, bool simple_p,
extern basic_block emit_return_for_exit (edge exit_fallthru_edge,
bool simple_p);
extern void reposition_prologue_and_epilogue_notes (void);
+extern poly_int64 get_stack_dynamic_offset ();
/* Returns the name of the current function. */
extern const char *fndecl_name (tree);