[v2,#2/2,rs6000] adjust return_pc debug attrs

Message ID oro7okma45.fsf@lxoliva.fsfla.org
State New
Headers
Series [v2,#1/2] enable adjustment of return_pc debug attrs |

Commit Message

Alexandre Oliva March 23, 2023, 3:15 a.m. UTC
  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.

Regstrapped on x86_64-linux-gnu and ppc64-linux-gnu.  Ok to install?


for  gcc/ChangeLog

	* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
	Override.
	(rs6000_call_offset_return_label): New.
---
 gcc/config/rs6000/rs6000.cc |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
  

Patch

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8e0b0d022db2f..e55117159b270 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1760,6 +1760,9 @@  static const struct attribute_spec rs6000_attribute_table[] =
 
 #undef TARGET_UPDATE_IPA_FN_TARGET_INFO
 #define TARGET_UPDATE_IPA_FN_TARGET_INFO rs6000_update_ipa_fn_target_info
+
+#undef TARGET_CALL_OFFSET_RETURN_LABEL
+#define TARGET_CALL_OFFSET_RETURN_LABEL rs6000_call_offset_return_label
 
 
 /* Processor table.  */
@@ -14593,6 +14596,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.  */