Hi, on 2024/5/25 20:13, Alexandre Oliva wrote: > On Apr 27, 2023, Alexandre Oliva <ol...@adacore.com> wrote: > >> On Apr 14, 2023, Alexandre Oliva <ol...@adacore.com> wrote: >>> On Mar 23, 2023, Alexandre Oliva <ol...@adacore.com> wrote: >>>> This patch introduces infrastructure for targets to add an offset to >>>> the label issued after the call_insn to set the call_return_pc >>>> attribute. This will be used on rs6000, that sometimes issues another >>>> instruction after the call proper as part of a call insn. > >>> Ping? >>> https://gcc.gnu.org/pipermail/gcc-patches/2023-March/614453.html > >> Ping? > > Ping? > Refreshed, retested on ppc64le-linux-gnu. Ok to install? > > > Some of the rs6000 call patterns, on some ABIs, issue multiple opcodes > out of a single call insn, but the call (bl) or jump (b) is not always > the last opcode in the sequence. > > This does not seem to be a problem for exception handling tables, but > the return_pc attribute in the call graph output in dwarf2+ debug > information, that takes the address of a label output right after the > call, does not match the value of the link register even for non-tail > calls. E.g., with ABI_AIX or ABI_ELFv2, such code as: > > foo (); > > outputs: > > bl foo > nop > LVL#: > [...] > .8byte .LVL# # DW_AT_call_return_pc > > but debug info consumers may rely on the return_pc address, and draw > incorrect conclusions from its off-by-4 value. > > This patch uses the infrastructure for targets to add an offset to the > label issued after the call_insn to set the call_return_pc attribute, > on rs6000, to account for opcodes issued after actual call opcode as > part of call insns output patterns.
I wonder if it's possible to have a test case for this? BR, Kewen > > > for gcc/ChangeLog > > * config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL): > Override. > (rs6000_call_offset_return_label): New. > --- > gcc/config/rs6000/rs6000.cc | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc > index e4dc629ddcc9a..77e6b94a539da 100644 > --- a/gcc/config/rs6000/rs6000.cc > +++ b/gcc/config/rs6000/rs6000.cc > @@ -1779,6 +1779,8 @@ static const scoped_attribute_specs *const > rs6000_attribute_table[] = > #undef TARGET_OVERLAP_OP_BY_PIECES_P > #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true > > +#undef TARGET_CALL_OFFSET_RETURN_LABEL > +#define TARGET_CALL_OFFSET_RETURN_LABEL rs6000_call_offset_return_label > > > /* Processor table. */ > @@ -14822,6 +14824,22 @@ rs6000_assemble_integer (rtx x, unsigned int size, > int aligned_p) > return default_assemble_integer (x, size, aligned_p); > } > > +/* Return the offset to be added to the label output after CALL_INSN > + to compute the address to be placed in DW_AT_call_return_pc. */ > + > +static int > +rs6000_call_offset_return_label (rtx_insn *call_insn) > +{ > + /* All rs6000 CALL_INSN output patterns start with a b or bl, always > + a 4-byte instruction, but some output patterns issue other > + opcodes afterwards. The return label is issued after the entire > + call insn, including any such post-call opcodes. Instead of > + figuring out which cases need adjustments, we compute the offset > + back to the address of the call opcode proper, then add the > + constant 4 bytes, to get the address after that opcode. */ > + return 4 - get_attr_length (call_insn); > +} > + > /* Return a template string for assembly to emit when making an > external call. FUNOP is the call mem argument operand number. */ > > >