public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-03-30 14:07 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-03-30 14:07 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8ad5a5106a4d5032f129c52a5d9761bf9d15d857
commit 8ad5a5106a4d5032f129c52a5d9761bf9d15d857
Author: Alexandre Oliva <oliva@adacore.com>
Date: Thu Mar 30 05:07:18 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
gcc/config/rs6000/rs6000.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index fa5f93a874f..385ef667d74 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
\f
/* Processor table. */
@@ -14547,6 +14550,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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2024-05-29 6:59 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2024-05-29 6:59 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0bb10f149bfcbe874d348814c623b36e9232cb3f
commit 0bb10f149bfcbe874d348814c623b36e9232cb3f
Author: Alexandre Oliva <oliva@adacore.com>
Date: Wed May 29 02:52:10 2024 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
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 e4dc629ddcc..77e6b94a539 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
\f
/* 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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2024-05-25 8:07 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2024-05-25 8:07 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:3bcf4294d8937a47886d2694a5888006f5d82741
commit 3bcf4294d8937a47886d2694a5888006f5d82741
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Apr 14 23:53:35 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
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 e4dc629ddcc..77e6b94a539 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
\f
/* 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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-04-06 6:35 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-04-06 6:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:93ebc9cd2a4b0e299b9f0b9667e7ccfd9e580ef4
commit 93ebc9cd2a4b0e299b9f0b9667e7ccfd9e580ef4
Author: Alexandre Oliva <oliva@adacore.com>
Date: Wed Apr 5 11:27:09 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
gcc/config/rs6000/rs6000.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 3be5860dd9b..3d781699869 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
\f
/* Processor table. */
@@ -14557,6 +14560,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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-03-24 6:25 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-03-24 6:25 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9e9af74b8599cbea2e968181ba3d1ed4cf4fff19
commit 9e9af74b8599cbea2e968181ba3d1ed4cf4fff19
Author: Alexandre Oliva <oliva@adacore.com>
Date: Thu Mar 23 00:45:00 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
gcc/config/rs6000/rs6000.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index fa5f93a874f..385ef667d74 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
\f
/* Processor table. */
@@ -14547,6 +14550,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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-03-23 3:48 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-03-23 3:48 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:864f3e61227ea45dbf6c171156a8a3778e371cc3
commit 864f3e61227ea45dbf6c171156a8a3778e371cc3
Author: Alexandre Oliva <oliva@adacore.com>
Date: Thu Mar 23 00:45:00 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
gcc/config/rs6000/rs6000.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index fa5f93a874f..385ef667d74 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
\f
/* Processor table. */
@@ -14547,6 +14550,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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-03-16 15:57 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-03-16 15:57 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:27c4da58ae953b21b7f446016fa8cec223e4bf85
commit 27c4da58ae953b21b7f446016fa8cec223e4bf85
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Mar 3 10:10:30 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
gcc/config/rs6000/rs6000.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8e0b0d022db..e55117159b2 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
\f
/* 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. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-03-16 14:23 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-03-16 14:23 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:d28a844533d182799fd6e5aeee859d88673b4317
commit d28a844533d182799fd6e5aeee859d88673b4317
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Mar 3 10:10:30 2023 -0300
[rs6000] adjust return_pc debug attrs
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.
for gcc/ChangeLog
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
Diff:
---
gcc/config/rs6000/rs6000.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8e0b0d022db..35f2220867d 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
\f
/* 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 - INSN_LENGTH (call_insn);
+}
+
/* Return a template string for assembly to emit when making an
external call. FUNOP is the call mem argument operand number. */
^ permalink raw reply [flat|nested] 9+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs
@ 2023-03-03 13:11 Alexandre Oliva
0 siblings, 0 replies; 9+ messages in thread
From: Alexandre Oliva @ 2023-03-03 13:11 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:1c8edeb6ea81dfb571eb32de2a2569764ba47185
commit 1c8edeb6ea81dfb571eb32de2a2569764ba47185
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Mar 3 10:10:30 2023 -0300
[rs6000] adjust return_pc debug attrs
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 introduces infrastructure for targets to add an offset to
the label issued after the call_insn to set the call_return_pc
attribute, and uses that on rs6000 to account for nop and l opcodes
issued after actual call opcode as part of call insns output patterns.
for gcc/ChangeLog
* target.def (call_offset_return_label): New hook.
* gcc/doc/tm.texi.in (TARGET_CALL_OFFSET_RETURN_LABEL): Add
placeholder.
* gcc/doc/tm.texi: Rebuild.
* dwarf2out.cc (struct call_arg_loc_node): Record call_insn
instad of call_arg_loc_note.
(add_AT_lbl_id): Add optional offset argument.
(gen_call_site_die): Compute and pass on a return pc offset.
(gen_subprogram_die): Move call_arg_loc_note computation...
(dwarf2out_var_location): ... from here. Set call_insn.
* config/rs6000/rs6000.cc (TARGET_CALL_OFFSET_RETURN_LABEL):
Override.
(rs6000_call_offset_return_label): New.
* config/rs6000/rs6000.md (call_needs_return_offset): New
attribute. Set it on call patterns that may require
offsetting.
Change-Id: Ic77d8c502469c62399519a6344ff38901bb8c5d0
TN: W224-033
Diff:
---
gcc/config/rs6000/rs6000.cc | 32 ++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000.md | 24 ++++++++++++++++++++++++
gcc/doc/tm.texi | 7 +++++++
gcc/doc/tm.texi.in | 2 ++
gcc/dwarf2out.cc | 26 +++++++++++++++++---------
gcc/target.def | 9 +++++++++
6 files changed, 91 insertions(+), 9 deletions(-)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 8e0b0d022db..0352fbc62b9 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
\f
/* Processor table. */
@@ -14593,6 +14596,35 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
return default_assemble_integer (x, size, aligned_p);
}
+static int
+rs6000_call_offset_return_label (rtx_insn *call_insn)
+{
+ /* We don't expect SEQUENCEs in this port. */
+ gcc_checking_assert (GET_CODE (call_insn) == CALL_INSN);
+
+ enum attr_call_needs_return_offset cnro
+ = get_attr_call_needs_return_offset (call_insn);
+
+ if (cnro == CALL_NEEDS_RETURN_OFFSET_NONE)
+ return 0;
+
+ if (rs6000_pcrel_p ())
+ return 0;
+ else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ /* rs6000_call_template_1 outputs a nop after non-sibcall insns;
+ we mark sibcall insns with NONE rather than DIRECT, so we
+ should have returned zero above.
+ rs6000_indirect_call_template_1 outputs an l insn after
+ indirect calls in these ABIs. */
+ return -4;
+ else if (DEFAULT_ABI == ABI_V4)
+ return 0;
+ else if (DEFAULT_ABI == ABI_DARWIN)
+ return 0;
+ else
+ return 0;
+}
+
/* Return a template string for assembly to emit when making an
external call. FUNOP is the call mem argument operand number. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 81bffb04ceb..7dc73b21af7 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -342,6 +342,12 @@
;; num_insns and recurse).
(define_attr "length" "" (const_int 4))
+;; Calls that output insns after bl need DW_AT_call_return_pc to be
+;; adjusted. rs6000_call_offset_return_label uses this attribute to
+;; conservatively recognize the relevant patterns.
+(define_attr "call_needs_return_offset" "none,direct,indirect"
+ (const_string "none"))
+
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000-opts.h.
(define_attr "cpu"
@@ -11355,6 +11361,7 @@
return rs6000_indirect_call_template (operands, 0);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11384,6 +11391,7 @@
return rs6000_call_template (operands, 0);
}
[(set_attr "type" "branch,branch")
+ (set_attr "call_needs_return_offset" "direct")
(set_attr "length" "4,8")])
(define_insn "*call_nonlocal_sysv_secure<mode>"
@@ -11405,6 +11413,7 @@
return rs6000_call_template (operands, 0);
}
[(set_attr "type" "branch,branch")
+ (set_attr "call_needs_return_offset" "direct")
(set_attr "length" "4,8")])
(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
@@ -11425,6 +11434,7 @@
return rs6000_indirect_call_template (operands, 1);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(plus
(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
@@ -11454,6 +11464,7 @@
return rs6000_call_template (operands, 1);
}
[(set_attr "type" "branch")
+ (set_attr "call_needs_return_offset" "direct")
(set (attr "length")
(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
(const_int 8)
@@ -11479,6 +11490,7 @@
return rs6000_call_template (operands, 1);
}
[(set_attr "type" "branch")
+ (set_attr "call_needs_return_offset" "direct")
(set (attr "length")
(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
(const_int 8)
@@ -11498,6 +11510,7 @@
return rs6000_call_template (operands, 0);
}
[(set_attr "type" "branch")
+ (set_attr "call_needs_return_offset" "direct")
(set (attr "length")
(if_then_else (match_test "rs6000_pcrel_p ()")
(const_int 4)
@@ -11515,6 +11528,7 @@
return rs6000_call_template (operands, 1);
}
[(set_attr "type" "branch")
+ (set_attr "call_needs_return_offset" "direct")
(set (attr "length")
(if_then_else (match_test "rs6000_pcrel_p ()")
(const_int 4)
@@ -11537,6 +11551,7 @@
return rs6000_indirect_call_template (operands, 0);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11558,6 +11573,7 @@
return rs6000_indirect_call_template (operands, 1);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11579,6 +11595,7 @@
return rs6000_indirect_call_template (operands, 0);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11595,6 +11612,7 @@
return rs6000_indirect_call_template (operands, 0);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11615,6 +11633,7 @@
return rs6000_indirect_call_template (operands, 1);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11632,6 +11651,7 @@
return rs6000_indirect_call_template (operands, 1);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11783,6 +11803,7 @@
return rs6000_indirect_sibcall_template (operands, 0);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11812,6 +11833,7 @@
return rs6000_sibcall_template (operands, 0);
}
[(set_attr "type" "branch")
+ (set_attr "call_needs_return_offset" "none")
(set_attr "length" "4,8")])
(define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
@@ -11832,6 +11854,7 @@
return rs6000_indirect_sibcall_template (operands, 1);
}
[(set_attr "type" "jmpreg")
+ (set_attr "call_needs_return_offset" "indirect")
(set (attr "length")
(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
(match_test "which_alternative != 1"))
@@ -11862,6 +11885,7 @@
return rs6000_sibcall_template (operands, 1);
}
[(set_attr "type" "branch")
+ (set_attr "call_needs_return_offset" "none")
(set_attr "length" "4,8")])
;; AIX ABI sibling call patterns.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index ec90c46ea2f..16bb089a9a6 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5426,6 +5426,13 @@ except the last are treated as named.
You need not define this hook if it always returns @code{false}.
@end deftypefn
+@deftypefn {Target Hook} int TARGET_CALL_OFFSET_RETURN_LABEL (rtx_insn *@var{call_insn})
+While generating call-site debug info for a CALL insn, or a SEQUENCE
+insn starting with a CALL, this target hook is invoked to compute the
+offset to be added to the debug label emitted after the call to obtain
+the return address that should be recorded as the return PC.
+@end deftypefn
+
@deftypefn {Target Hook} void TARGET_CALL_ARGS (rtx, @var{tree})
While generating RTL for a function call, this target hook is invoked once
for each argument passed to the function, either a register returned by
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 930b109863f..1706965e9a0 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3785,6 +3785,8 @@ These machine description macros help implement varargs:
@hook TARGET_STRICT_ARGUMENT_NAMING
+@hook TARGET_CALL_OFFSET_RETURN_LABEL
+
@hook TARGET_CALL_ARGS
@hook TARGET_END_CALL_ARGS
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 1f39df3b1e2..b706c36b87a 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -3584,7 +3584,7 @@ typedef struct var_loc_list_def var_loc_list;
/* Call argument location list. */
struct GTY ((chain_next ("%h.next"))) call_arg_loc_node {
- rtx GTY (()) call_arg_loc_note;
+ rtx_insn * GTY (()) call_insn;
const char * GTY (()) label;
tree GTY (()) block;
bool tail_call_p;
@@ -3768,7 +3768,8 @@ static void remove_addr_table_entry (addr_table_entry *);
static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool);
static inline rtx AT_addr (dw_attr_node *);
static void add_AT_symview (dw_die_ref, enum dwarf_attribute, const char *);
-static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *,
+ int = 0);
static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
@@ -5327,14 +5328,17 @@ add_AT_symview (dw_die_ref die, enum dwarf_attribute attr_kind,
static inline void
add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind,
- const char *lbl_id)
+ const char *lbl_id, int offset)
{
dw_attr_node attr;
attr.dw_attr = attr_kind;
attr.dw_attr_val.val_class = dw_val_class_lbl_id;
attr.dw_attr_val.val_entry = NULL;
- attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
+ if (!offset)
+ attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
+ else
+ attr.dw_attr_val.v.val_lbl_id = xasprintf ("%s%+i", lbl_id, offset);
if (dwarf_split_debug_info)
attr.dw_attr_val.val_entry
= add_addr_table_entry (attr.dw_attr_val.v.val_lbl_id,
@@ -23405,7 +23409,9 @@ gen_call_site_die (tree decl, dw_die_ref subr_die,
if (stmt_die == NULL)
stmt_die = subr_die;
die = new_die (dwarf_TAG (DW_TAG_call_site), stmt_die, NULL_TREE);
- add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc), ca_loc->label);
+ add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc),
+ ca_loc->label,
+ targetm.calls.call_offset_return_label (ca_loc->call_insn));
if (ca_loc->tail_call_p)
add_AT_flag (die, dwarf_AT (DW_AT_call_tail_call), 1);
if (ca_loc->symbol_ref)
@@ -24092,11 +24098,14 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
dw_die_ref die = NULL;
rtx tloc = NULL_RTX, tlocc = NULL_RTX;
+ rtx call_arg_loc_note
+ = find_reg_note (ca_loc->call_insn,
+ REG_CALL_ARG_LOCATION, NULL_RTX);
rtx arg, next_arg;
tree arg_decl = NULL_TREE;
- for (arg = (ca_loc->call_arg_loc_note != NULL_RTX
- ? XEXP (ca_loc->call_arg_loc_note, 0)
+ for (arg = (call_arg_loc_note != NULL_RTX
+ ? XEXP (call_arg_loc_note, 0)
: NULL_RTX);
arg; arg = next_arg)
{
@@ -28122,8 +28131,7 @@ create_label:
= ggc_cleared_alloc<call_arg_loc_node> ();
rtx_insn *prev = call_insn;
- ca_loc->call_arg_loc_note
- = find_reg_note (call_insn, REG_CALL_ARG_LOCATION, NULL_RTX);
+ ca_loc->call_insn = call_insn;
ca_loc->next = NULL;
ca_loc->label = last_label;
gcc_assert (prev
diff --git a/gcc/target.def b/gcc/target.def
index 4b2c53aba14..a5c2046e982 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4738,6 +4738,15 @@ not generate any instructions in this case.",
int *pretend_args_size, int second_time),
default_setup_incoming_varargs)
+DEFHOOK
+(call_offset_return_label,
+ "While generating call-site debug info for a CALL insn, or a SEQUENCE\n\
+insn starting with a CALL, this target hook is invoked to compute the\n\
+offset to be added to the debug label emitted after the call to obtain\n\
+the return address that should be recorded as the return PC.",
+ int, (rtx_insn *call_insn),
+ hook_int_rtx_insn_0)
+
DEFHOOK
(call_args,
"While generating RTL for a function call, this target hook is invoked once\n\
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-05-29 6:59 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-30 14:07 [gcc(refs/users/aoliva/heads/testme)] [rs6000] adjust return_pc debug attrs Alexandre Oliva
-- strict thread matches above, loose matches on Subject: below --
2024-05-29 6:59 Alexandre Oliva
2024-05-25 8:07 Alexandre Oliva
2023-04-06 6:35 Alexandre Oliva
2023-03-24 6:25 Alexandre Oliva
2023-03-23 3:48 Alexandre Oliva
2023-03-16 15:57 Alexandre Oliva
2023-03-16 14:23 Alexandre Oliva
2023-03-03 13:11 Alexandre Oliva
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).