On Thu, May 14, 2020 at 3:58 PM Christophe Lyon via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > The same code pattern occurs in several functions, so it seems cleaner > to move it into a dedicated function. > > 2020-05-14 Christophe Lyon <christophe.l...@linaro.org> > > gcc/ > * config/arm/arm.c (reg_needs_saving_p): New function. > (use_return_insn): Use reg_needs_saving_p. > (arm_get_vfp_saved_size): Likewise. > (arm_compute_frame_layout): Likewise. > (arm_save_coproc_regs): Likewise. > (thumb1_expand_epilogue): Likewise. > (arm_expand_epilogue_apcs_frame): Likewise. > (arm_expand_epilogue): Likewise. > --- > gcc/config/arm/arm.c | 46 ++++++++++++++++++++++++---------------------- > 1 file changed, 24 insertions(+), 22 deletions(-) > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index c88de3e..694c1bb 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -4188,6 +4188,18 @@ arm_trampoline_adjust_address (rtx addr) > return addr; > } > > +/* Return 1 if REG needs to be saved. */ > +static bool reg_needs_saving_p (unsigned reg)
static inline ? > +{ > + unsigned long func_type = arm_current_func_type (); Why is this needed here when it's not used further ? > + > + if (!df_regs_ever_live_p (reg) > + || call_used_or_fixed_reg_p (reg)) > + return false; > + else > + return true; > +} > + > /* Return 1 if it is possible to return using a single instruction. > If SIBLING is non-null, this is a test for a return before a sibling > call. SIBLING is the call insn, so we can examine its register usage. */ > @@ -4317,12 +4329,12 @@ use_return_insn (int iscond, rtx sibling) > since this also requires an insn. */ > if (TARGET_VFP_BASE) > for (regno = FIRST_VFP_REGNUM; regno <= LAST_VFP_REGNUM; regno++) > - if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) > + if (reg_needs_saving_p (regno)) > return 0; > > if (TARGET_REALLY_IWMMXT) > for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++) > - if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno)) > + if (reg_needs_saving_p (regno)) > return 0; > > return 1; > @@ -20943,7 +20955,6 @@ thumb1_compute_save_core_reg_mask (void) > return mask; > } > > - > /* Return the number of bytes required to save VFP registers. */ > static int > arm_get_vfp_saved_size (void) > @@ -20961,10 +20972,7 @@ arm_get_vfp_saved_size (void) > regno < LAST_VFP_REGNUM; > regno += 2) > { > - if ((!df_regs_ever_live_p (regno) > - || call_used_or_fixed_reg_p (regno)) > - && (!df_regs_ever_live_p (regno + 1) > - || call_used_or_fixed_reg_p (regno + 1))) > + if (!reg_needs_saving_p (regno) && !reg_needs_saving_p (regno + 1)) > { > if (count > 0) > { > @@ -22489,8 +22497,7 @@ arm_compute_frame_layout (void) > for (regno = FIRST_IWMMXT_REGNUM; > regno <= LAST_IWMMXT_REGNUM; > regno++) > - if (df_regs_ever_live_p (regno) > - && !call_used_or_fixed_reg_p (regno)) > + if (reg_needs_saving_p (regno)) > saved += 8; > } > > @@ -22711,8 +22718,9 @@ arm_save_coproc_regs(void) > unsigned start_reg; > rtx insn; > > + if (TARGET_REALLY_IWMMXT) > for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--) > - if (df_regs_ever_live_p (reg) && !call_used_or_fixed_reg_p (reg)) > + if (reg_needs_saving_p (reg)) > { > insn = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx); > insn = gen_rtx_MEM (V2SImode, insn); > @@ -22727,9 +22735,7 @@ arm_save_coproc_regs(void) > > for (reg = FIRST_VFP_REGNUM; reg < LAST_VFP_REGNUM; reg += 2) > { > - if ((!df_regs_ever_live_p (reg) || call_used_or_fixed_reg_p (reg)) > - && (!df_regs_ever_live_p (reg + 1) > - || call_used_or_fixed_reg_p (reg + 1))) > + if (!reg_needs_saving_p (reg) && !reg_needs_saving_p (reg + 1)) > { > if (start_reg != reg) > saved_size += vfp_emit_fstmd (start_reg, > @@ -27024,7 +27030,7 @@ thumb1_expand_epilogue (void) > /* Emit a clobber for each insn that will be restored in the epilogue, > so that flow2 will get register lifetimes correct. */ > for (regno = 0; regno < 13; regno++) > - if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) > + if (reg_needs_saving_p (regno)) > emit_clobber (gen_rtx_REG (SImode, regno)); > > if (! df_regs_ever_live_p (LR_REGNUM)) > @@ -27090,9 +27096,7 @@ arm_expand_epilogue_apcs_frame (bool really_return) > > for (i = FIRST_VFP_REGNUM; i < LAST_VFP_REGNUM; i += 2) > /* Look for a case where a reg does not need restoring. */ > - if ((!df_regs_ever_live_p (i) || call_used_or_fixed_reg_p (i)) > - && (!df_regs_ever_live_p (i + 1) > - || call_used_or_fixed_reg_p (i + 1))) > + if (!reg_needs_saving_p (i) && !reg_needs_saving_p (i + 1)) > { > if (start_reg != i) > arm_emit_vfp_multi_reg_pop (start_reg, > @@ -27119,7 +27123,7 @@ arm_expand_epilogue_apcs_frame (bool really_return) > int lrm_count = (num_regs % 2) ? (num_regs + 2) : (num_regs + 1); > > for (i = LAST_IWMMXT_REGNUM; i >= FIRST_IWMMXT_REGNUM; i--) > - if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) > + if (reg_needs_saving_p (i)) > { > rtx addr = gen_frame_mem (V2SImode, > plus_constant (Pmode, > hard_frame_pointer_rtx, > @@ -27324,9 +27328,7 @@ arm_expand_epilogue (bool really_return) > unlike pop, vldm can only do consecutive regs. */ > for (i = LAST_VFP_REGNUM - 1; i >= FIRST_VFP_REGNUM; i -= 2) > /* Look for a case where a reg does not need restoring. */ > - if ((!df_regs_ever_live_p (i) || call_used_or_fixed_reg_p (i)) > - && (!df_regs_ever_live_p (i + 1) > - || call_used_or_fixed_reg_p (i + 1))) > + if (!reg_needs_saving_p (i) && !reg_needs_saving_p (i + 1)) > { > /* Restore the regs discovered so far (from reg+2 to > end_reg). */ > @@ -27348,7 +27350,7 @@ arm_expand_epilogue (bool really_return) > > if (TARGET_IWMMXT) > for (i = FIRST_IWMMXT_REGNUM; i <= LAST_IWMMXT_REGNUM; i++) > - if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) > + if (reg_needs_saving_p (i)) > { > rtx_insn *insn; > rtx addr = gen_rtx_MEM (V2SImode, > -- > 2.7.4 > OK with those changes. Ramana