On Mon, Jan 29, 2024 at 8:30 AM Jakub Jelinek <ja...@redhat.com> wrote:
>
> On Mon, Jan 29, 2024 at 08:00:26AM -0800, H.J. Lu wrote:
> > Attach REG_CFA_UNDEFINED notes for unsaved callee-saved registers which
> > have been used in the function to an instruction in prologue.
> >
> > gcc/
> >
> >       PR target/38534
> >       * dwarf2cfi.cc (add_cfi_undefined): New.
> >       (dwarf2out_frame_debug_cfa_undefined): Likewise.
> >       (dwarf2out_frame_debug): Handle REG_CFA_UNDEFINED.
> >       * reg-notes.def (REG_CFA_UNDEFINED): New.
> >       * config/i386/i386.cc (ix86_expand_prologue): Attach
> >       REG_CFA_UNDEFINED notes for unsaved callee-saved registers
> >       which have been used in the function to an instruction in
> >       prologue.
> >
> > gcc/testsuite/
> >
> >       PR target/38534
> >       * gcc.target/i386/no-callee-saved-19.c: New test.
> >       * gcc.target/i386/no-callee-saved-20.c: Likewise.
> >       * gcc.target/i386/pr38534-7.c: Likewise.
> >       * gcc.target/i386/pr38534-8.c: Likewise.
> > ---
> >  gcc/config/i386/i386.cc                       | 20 +++++++
> >  gcc/dwarf2cfi.cc                              | 55 +++++++++++++++++++
> >  gcc/reg-notes.def                             |  4 ++
> >  .../gcc.target/i386/no-callee-saved-19.c      | 17 ++++++
> >  .../gcc.target/i386/no-callee-saved-20.c      | 12 ++++
> >  gcc/testsuite/gcc.target/i386/pr38534-7.c     | 18 ++++++
> >  gcc/testsuite/gcc.target/i386/pr38534-8.c     | 13 +++++
> >  7 files changed, 139 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-19.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-20.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr38534-7.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr38534-8.c
> >
> > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> > index b3e7c74846e..6ec87b6a16f 100644
> > --- a/gcc/config/i386/i386.cc
> > +++ b/gcc/config/i386/i386.cc
> > @@ -9304,6 +9304,26 @@ ix86_expand_prologue (void)
> >       combined with prologue modifications.  */
> >    if (TARGET_SEH)
> >      emit_insn (gen_prologue_use (stack_pointer_rtx));
> > +
> > +  if (cfun->machine->call_saved_registers
> > +      != TYPE_NO_CALLEE_SAVED_REGISTERS)
> > +    return;
> > +
> > +  insn = get_insns ();
> > +  if (!insn)
> > +    return;
>
> You can't attach the notes to a random instruction that happens to be first
> in the function.
> 1) it needs to be a real instruction, not a note

Will fix it.

> 2) it needs to be RTX_FRAME_RELATED_P

This should work:

  insn = nullptr;
  rtx_insn *next;
  for (next = get_insns (); next; next = NEXT_INSN (next))
    {
      if (!RTX_FRAME_RELATED_P (next))
        continue;
      insn = next;
    }

  if (!insn)
    return;

> 3) if it is RTX_FRAME_RELATED_P, but doesn't contain any previous REG_CFA_*
>    notes:
>    3a) if it has REG_FRAME_RELATED_EXPR note, then I believe just that
>        note argument is processed instead of the instruction pattern and
>        I think REG_CFA_* notes which precede REG_FRAME_RELATED_EXPR are
>        processed, but REG_CFA_* notes after it are not; so adding
>        REG_CFA_UNDEFINED notes at least if the adding is after the existing
>        notes instead of before them may be problematic

Since register note is added to the head:

/* Add register note with kind KIND and datum DATUM to INSN.  */

void
add_reg_note (rtx insn, enum reg_note kind, rtx datum)
{
  REG_NOTES (insn) = alloc_reg_note (kind, datum, REG_NOTES (insn));
}

it isn't an issue.

>    3b) if it has neither REG_CFA_* nor REG_FRAME_RELATED_EXPR notes, then
>        normally the pattern of the insn would be processed in dwarf2cfi.
>        But with the REG_CFA_* notes that part will be ignored.
>
> > --- a/gcc/dwarf2cfi.cc
> > +++ b/gcc/dwarf2cfi.cc
> > @@ -517,6 +517,17 @@ add_cfi_restore (unsigned reg)
> >    add_cfi (cfi);
> >  }
> >
>
> Function comment missing.

Will fix it in the v3 patch.

Thanks.

> > +static void
> > +add_cfi_undefined (unsigned reg)
> > +{
> > +  dw_cfi_ref cfi = new_cfi ();
> > +
> > +  cfi->dw_cfi_opc = DW_CFA_undefined;
> > +  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
> > +
> > +  add_cfi (cfi);
> > +}
> > +
> >  /* Perform ROW->REG_SAVE[COLUMN] = CFI.  CFI may be null, indicating
> >     that the register column is no longer saved.  */
>
>         Jakub
>


-- 
H.J.

Reply via email to