diff mbox series

[1/2] arm: Factorize several occurrences of the same code into reg_needs_saving_p

Message ID 1589468303-7890-1-git-send-email-christophe.lyon@linaro.org
State New
Headers show
Series [1/2] arm: Factorize several occurrences of the same code into reg_needs_saving_p | expand

Commit Message

Christophe Lyon May 14, 2020, 2:58 p.m. UTC
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.lyon@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(-)

Comments

Ramana Radhakrishnan May 14, 2020, 3:07 p.m. UTC | #1
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.lyon@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
Christophe Lyon May 14, 2020, 3:22 p.m. UTC | #2
On Thu, 14 May 2020 at 17:07, Ramana Radhakrishnan
<ramana.gcc@googlemail.com> wrote:
>
> 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.lyon@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 ?
>
OK

> > +{
> > +  unsigned long func_type = arm_current_func_type ();
>
> Why is this needed here when it's not used further ?
>
Ha, because I forgot to move this to
https://gcc.gnu.org/pipermail/gcc-patches/2020-May/545749.html

> > +
> > +  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.
>

Thanks

> Ramana
diff mbox series

Patch

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)
+{
+  unsigned long func_type = arm_current_func_type ();
+
+  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,