[PATCH] First attempt at unwind epilogue support for powerpc{,64} (take 2)

Jakub Jelinek jakub@redhat.com
Fri Jun 5 07:10:00 GMT 2009


On Thu, Jun 04, 2009 at 09:36:42PM -0400, David Edelsohn wrote:
> In trying to figure out why this patch causes bootstrap failures on AIX...
> 
> 
> > @@ -17028,7 +17037,13 @@ rs6000_emit_epilogue (int sibcall)
> >            addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
> >            mem = gen_frame_mem (V4SImode, addr);
> >
> > -           emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
> > +           reg = gen_rtx_REG (V4SImode, i);
> > +           emit_move_insn (reg, mem);
> > +           if (offset_below_red_zone_p (info->altivec_save_offset
> > +                                        + (i - info->first_altivec_reg_save)
> > +                                          * 16))
> > +             cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
> > +                                            cfa_restores);
> >          }
> >     }
> 
> Why isn't this guarded by DEFAULT_ABI == ABI_V4?

Because we want the REG_CFA_RESTORE notes whenever something is below
the red zone.  For DEFAULT_ABI != ABI_V4 those are just some of the
altivec restoring instructions, offset_below_red_zone_p
returns true if the offset is below the stack cushion.
For DEFAULT_ABI == ABI_V4, offset_below_red_zone_p returns true
whenever the offset is negative (all offsets except for lr_offset).
The reason why the if guards around the altivec restoration before first
stack pop mention DEFAULT_ABI is because they check it for different reason
than offset_below_red_zone_p, they usually don't want to restore altivec
stuff in ABI_V4 before first stack pop, as that is not really needed - the
first stack pop doesn't pop the stack, just sets r11.

Before the first stack pop (which is r1 = something for DEFAULT_ABI != ABI_V4
and r11 = something for DEFAULT_ABI == ABI_V4) thus we want REG_CFA_RESTORE
notes even for DEFAULT_ABI != ABI_V4.  My understanding is that
the first stack pop for DEFAULT_ABI != ABI_V4 will in all cases end up
with frame_reg_rtx == sp_reg_rtx && sp_offset == 0.
After the first stack pop there are further register pops, but as
DEFAULT_ABI != ABI_V4 has already popped the stack, they must necessarily
be from the stack cushion only.  Only DEFAULT_ABI == ABI_V4, which doesn't
have the red zone at all and hasn't really popped the stack yet, needs
REG_CFA_RESTORE notes at those points.

> > @@ -17326,8 +17372,22 @@ rs6000_emit_epilogue (int sibcall)
> >             back.  */
> >          return;
> >        }
> > -      else
> > -       emit_insn (par);
> > +
> > +      insn = emit_insn (par);
> > +      if (DEFAULT_ABI == ABI_V4)
> > +       {
> > +         if (frame_pointer_needed)
> > +           {
> > +             add_reg_note (insn, REG_CFA_DEF_CFA,
> > +                           plus_constant (frame_reg_rtx, sp_offset));
> > +             RTX_FRAME_RELATED_P (insn) = 1;
> > +           }
> > +
> > +         for (i = info->first_gp_reg_save; i < 32; i++)
> > +           cfa_restores
> > +             = alloc_reg_note (REG_CFA_RESTORE,
> > +                               gen_rtx_REG (reg_mode, i), cfa_restores);
> > +       }
> 
> Why is this block no longer in an "else" clause?

Because the if block has return; at the end.

> >   /* If this is V.4, unwind the stack pointer after all of the loads
> >      have been done.  */
> > -  rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
> > -                          sp_offset, !restoring_FPRs_inline);
> > +  insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
> > +                                 sp_offset, !restoring_FPRs_inline);
> > +  if (insn)
> > +    {
> > +      if (cfa_restores)
> > +       {
> > +         REG_NOTES (insn) = cfa_restores;
> > +         cfa_restores = NULL_RTX;
> > +       }
> > +      add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
> > +      RTX_FRAME_RELATED_P (insn) = 1;
> > +    }
> 
> Why isn't this guarded by DEFAULT_ABI == ABI_V4?

Because insn will be NULL for DEFAULT_ABI != ABI_V4.  See above, for
DEFAULT_ABI != ABI_V4 I believe frame_reg_rtx == sp_reg_rtx and
sp_offset == 0 at this point.

	Jakub



More information about the Gcc-patches mailing list