Message ID | mptfs1k9hla.fsf@arm.com |
---|---|
State | New |
Headers | show |
Series | explow: Allow dynamic allocations after vregs | expand |
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 >
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);