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