explow: Allow dynamic allocations after vregs

Message ID mptfs1k9hla.fsf@arm.com
State Accepted
Headers
Series explow: Allow dynamic allocations after vregs |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Richard Sandiford Nov. 5, 2023, 6:32 p.m. UTC
  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

Richard Biener Nov. 6, 2023, 7:17 a.m. UTC | #1
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
>
  

Patch

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);