From: Richard Sandiford Date: Mon, 6 Nov 2023 10:49:58 +0000 (+0000) Subject: explow: Allow dynamic allocations after vregs X-Git-Tag: basepoints/gcc-15~4990 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a7a45364dddef399bfb550235166df51108a3142;p=thirdparty%2Fgcc.git explow: Allow dynamic allocations after vregs 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. 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. --- diff --git a/gcc/explow.cc b/gcc/explow.cc index 0c03ac350bbe..aa64d5e906cf 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 afb0b33da9e3..527ea4807b0c 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 5caf1e153eab..29846564bc6f 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -715,6 +715,7 @@ extern vec 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);