[PATCH 2/3] [amdgcn] Use frame pointer for CFA expressions.
Andrew Stubbs
ams@codesourcery.com
Wed Jun 23 09:32:21 GMT 2021
On 22/06/2021 18:14, Hafiz Abid Qadeer wrote:
> As size of address is bigger than registers in amdgcn, we are forced to use
> DW_CFA_def_cfa_expression to make an expression that concatenates multiple
> registers for the value of the CFA. This then prohibits us from using many
> of the dwarf ops which expect CFA rule to be a single regsiter plus an offset.
> Using frame pointer in the CFA rule is only real possibility as it is saved
> in every frame and it is easy to unwind its value.
>
> So unless user gives fomit-frame-pointer, we use frame pointer for the
> cfi information. This options also has a different default now.
>
> gcc/
>
> * common/config/gcn/gcn-common.c
> (gcn_option_optimization_table): Change OPT_fomit_frame_pointer to -O3.
> (gcn_expand_prologue): Prefer the frame pointer when emitting CFI.
> (gcn_frame_pointer_rqd): New function.
> (TARGET_FRAME_POINTER_REQUIRED): New hook.
> ---
> gcc/common/config/gcn/gcn-common.c | 2 +-
> gcc/config/gcn/gcn.c | 60 +++++++++++++++++++++++-------
> 2 files changed, 47 insertions(+), 15 deletions(-)
>
> diff --git a/gcc/common/config/gcn/gcn-common.c b/gcc/common/config/gcn/gcn-common.c
> index 305c310f940..695eb467e34 100644
> --- a/gcc/common/config/gcn/gcn-common.c
> +++ b/gcc/common/config/gcn/gcn-common.c
> @@ -27,7 +27,7 @@
> /* Set default optimization options. */
> static const struct default_options gcn_option_optimization_table[] =
> {
> - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> + { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> { OPT_LEVELS_NONE, 0, NULL, 0 }
> };
>
> diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
> index 3ab16548aad..0eac3aa3844 100644
> --- a/gcc/config/gcn/gcn.c
> +++ b/gcc/config/gcn/gcn.c
> @@ -2900,10 +2900,14 @@ gcn_expand_prologue ()
> rtx adjustment = gen_int_mode (sp_adjust, SImode);
> rtx insn = emit_insn (gen_addsi3_scalar_carry (sp_lo, sp_lo,
> adjustment, scc));
> - RTX_FRAME_RELATED_P (insn) = 1;
> - add_reg_note (insn, REG_FRAME_RELATED_EXPR,
> - gen_rtx_SET (sp,
> - gen_rtx_PLUS (DImode, sp, adjustment)));
> + if (!offsets->need_frame_pointer)
> + {
> + RTX_FRAME_RELATED_P (insn) = 1;
> + add_reg_note (insn, REG_FRAME_RELATED_EXPR,
> + gen_rtx_SET (sp,
> + gen_rtx_PLUS (DImode, sp,
> + adjustment)));
> + }
> emit_insn (gen_addcsi3_scalar_zero (sp_hi, sp_hi, scc));
> }
>
> @@ -2917,25 +2921,24 @@ gcn_expand_prologue ()
> rtx adjustment = gen_int_mode (fp_adjust, SImode);
> rtx insn = emit_insn (gen_addsi3_scalar_carry(fp_lo, sp_lo,
> adjustment, scc));
> - RTX_FRAME_RELATED_P (insn) = 1;
> - add_reg_note (insn, REG_FRAME_RELATED_EXPR,
> - gen_rtx_SET (fp,
> - gen_rtx_PLUS (DImode, sp, adjustment)));
> emit_insn (gen_addcsi3_scalar (fp_hi, sp_hi,
> (fp_adjust < 0 ? GEN_INT (-1)
> : const0_rtx),
> scc, scc));
> +
> + /* Set the CFA to the entry stack address, as an offset from the
> + frame pointer. This is preferred because the frame pointer is
> + saved in each frame, whereas the stack pointer is not. */
> + RTX_FRAME_RELATED_P (insn) = 1;
> + add_reg_note (insn, REG_CFA_DEF_CFA,
> + gen_rtx_PLUS (DImode, fp,
> + GEN_INT (-(offsets->pretend_size
> + + offsets->callee_saves))));
> }
>
> rtx_insn *seq = get_insns ();
> end_sequence ();
>
> - /* FIXME: Prologue insns should have this flag set for debug output, etc.
> - but it causes issues for now.
> - for (insn = seq; insn; insn = NEXT_INSN (insn))
> - if (INSN_P (insn))
> - RTX_FRAME_RELATED_P (insn) = 1;*/
> -
> emit_insn (seq);
> }
> else
> @@ -3011,6 +3014,16 @@ gcn_expand_prologue ()
> gen_rtx_SET (sp, gen_rtx_PLUS (DImode, sp,
> dbg_adjustment)));
>
> + if (offsets->need_frame_pointer)
> + {
> + /* Set the CFA to the entry stack address, as an offset from the
> + frame pointer. This is necessary when alloca is used, and
> + harmless otherwise. */
> + rtx neg_adjust = gen_int_mode (-offsets->callee_saves, DImode);
> + add_reg_note (insn, REG_CFA_DEF_CFA,
> + gen_rtx_PLUS (DImode, fp, neg_adjust));
> + }
> +
> /* Make sure the flat scratch reg doesn't get optimised away. */
> emit_insn (gen_prologue_use (gen_rtx_REG (DImode, FLAT_SCRATCH_REG)));
> }
> @@ -3114,6 +3127,23 @@ gcn_expand_epilogue (void)
> emit_jump_insn (gen_gcn_return ());
> }
>
> +/* Implement TARGET_FRAME_POINTER_REQUIRED.
> +
> + Return true if the frame pointer should not be eliminated. */
> +
> +bool
> +gcn_frame_pointer_rqd (void)
> +{
> + /* GDB needs the frame pointer in order to unwind properly,
> + but that's not important for the entry point, unless alloca is used.
> + It's not important for code execution, so we should repect the
> + -fomit-frame-pointer flag. */
> + return (!flag_omit_frame_pointer
> + && cfun
> + && (cfun->calls_alloca
> + || (cfun->machine && cfun->machine->normal_function)));
> +}
> +
> /* Implement TARGET_CAN_ELIMINATE.
>
> Return true if the compiler is allowed to try to replace register number
> @@ -6373,6 +6403,8 @@ gcn_dwarf_register_span (rtx rtl)
> #define TARGET_EMUTLS_VAR_INIT gcn_emutls_var_init
> #undef TARGET_EXPAND_BUILTIN
> #define TARGET_EXPAND_BUILTIN gcn_expand_builtin
> +#undef TARGET_FRAME_POINTER_REQUIRED
> +#define TARGET_FRAME_POINTER_REQUIRED gcn_frame_pointer_rqd
> #undef TARGET_FUNCTION_ARG
> #undef TARGET_FUNCTION_ARG_ADVANCE
> #define TARGET_FUNCTION_ARG_ADVANCE gcn_function_arg_advance
>
OK.
Andrew
More information about the Gcc-patches
mailing list