Commit 74c74aa0 by Richard Sandiford Committed by Richard Sandiford

poly_int: DWARF locations

This patch adds support for DWARF location expressions
that involve polynomial offsets.  It adds a target hook that
says how the runtime invariants used in the offsets should be
represented in DWARF.  SVE vectors have to be a multiple of
128 bits in size, so the GCC port uses the number of 128-bit
blocks minus one as the runtime invariant.  However, in DWARF,
the vector length is exposed via a pseudo "VG" register that
holds the number of 64-bit elements in a vector.  Thus:

  indeterminate 1 == (VG / 2) - 1

The hook needs to be general enough to express this.
Note that in most cases the division and subtraction fold
away into surrounding expressions.

2017-12-20  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* target.def (dwarf_poly_indeterminate_value): New hook.
	* targhooks.h (default_dwarf_poly_indeterminate_value): Declare.
	* targhooks.c (default_dwarf_poly_indeterminate_value): New function.
	* doc/tm.texi.in (TARGET_DWARF_POLY_INDETERMINATE_VALUE): Document.
	* doc/tm.texi: Regenerate.
	* dwarf2out.h (build_cfa_loc, build_cfa_aligned_loc): Take the
	offset as a poly_int64.
	* dwarf2out.c (new_reg_loc_descr): Move later in file.  Take the
	offset as a poly_int64.
	(loc_descr_plus_const, loc_list_plus_const, build_cfa_aligned_loc):
	Take the offset as a poly_int64.
	(build_cfa_loc): Likewise.  Use loc_descr_plus_const.
	(frame_pointer_fb_offset): Change to a poly_int64.
	(int_loc_descriptor): Take the offset as a poly_int64.  Use
	targetm.dwarf_poly_indeterminate_value for polynomial offsets.
	(based_loc_descr): Take the offset as a poly_int64.
	Use strip_offset_and_add to handle (plus X (const)).
	Use new_reg_loc_descr instead of an open-coded version of the
	previous implementation.
	(mem_loc_descriptor): Handle CONST_POLY_INT.
	(compute_frame_pointer_to_fb_displacement): Take the offset as a
	poly_int64.  Use strip_offset_and_add to handle (plus X (const)).

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r255868
parent 84bc717b
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org> 2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* target.def (dwarf_poly_indeterminate_value): New hook.
* targhooks.h (default_dwarf_poly_indeterminate_value): Declare.
* targhooks.c (default_dwarf_poly_indeterminate_value): New function.
* doc/tm.texi.in (TARGET_DWARF_POLY_INDETERMINATE_VALUE): Document.
* doc/tm.texi: Regenerate.
* dwarf2out.h (build_cfa_loc, build_cfa_aligned_loc): Take the
offset as a poly_int64.
* dwarf2out.c (new_reg_loc_descr): Move later in file. Take the
offset as a poly_int64.
(loc_descr_plus_const, loc_list_plus_const, build_cfa_aligned_loc):
Take the offset as a poly_int64.
(build_cfa_loc): Likewise. Use loc_descr_plus_const.
(frame_pointer_fb_offset): Change to a poly_int64.
(int_loc_descriptor): Take the offset as a poly_int64. Use
targetm.dwarf_poly_indeterminate_value for polynomial offsets.
(based_loc_descr): Take the offset as a poly_int64.
Use strip_offset_and_add to handle (plus X (const)).
Use new_reg_loc_descr instead of an open-coded version of the
previous implementation.
(mem_loc_descriptor): Handle CONST_POLY_INT.
(compute_frame_pointer_to_fb_displacement): Take the offset as a
poly_int64. Use strip_offset_and_add to handle (plus X (const)).
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
...@@ -3130,6 +3130,19 @@ the CFI label attached to the insn, @var{pattern} is the pattern of ...@@ -3130,6 +3130,19 @@ the CFI label attached to the insn, @var{pattern} is the pattern of
the insn and @var{index} is @code{UNSPEC_INDEX} or @code{UNSPECV_INDEX}. the insn and @var{index} is @code{UNSPEC_INDEX} or @code{UNSPECV_INDEX}.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} {unsigned int} TARGET_DWARF_POLY_INDETERMINATE_VALUE (unsigned int @var{i}, unsigned int *@var{factor}, int *@var{offset})
Express the value of @code{poly_int} indeterminate @var{i} as a DWARF
expression, with @var{i} counting from 1. Return the number of a DWARF
register @var{R} and set @samp{*@var{factor}} and @samp{*@var{offset}} such
that the value of the indeterminate is:
@smallexample
value_of(@var{R}) / @var{factor} - @var{offset}
@end smallexample
A target only needs to define this hook if it sets
@samp{NUM_POLY_INT_COEFFS} to a value greater than 1.
@end deftypefn
@defmac INCOMING_FRAME_SP_OFFSET @defmac INCOMING_FRAME_SP_OFFSET
A C expression whose value is an integer giving the offset, in bytes, A C expression whose value is an integer giving the offset, in bytes,
from the value of the stack pointer register to the top of the stack from the value of the stack pointer register to the top of the stack
......
...@@ -2544,6 +2544,8 @@ terminate the stack backtrace. New ports should avoid this. ...@@ -2544,6 +2544,8 @@ terminate the stack backtrace. New ports should avoid this.
@hook TARGET_DWARF_HANDLE_FRAME_UNSPEC @hook TARGET_DWARF_HANDLE_FRAME_UNSPEC
@hook TARGET_DWARF_POLY_INDETERMINATE_VALUE
@defmac INCOMING_FRAME_SP_OFFSET @defmac INCOMING_FRAME_SP_OFFSET
A C expression whose value is an integer giving the offset, in bytes, A C expression whose value is an integer giving the offset, in bytes,
from the value of the stack pointer register to the top of the stack from the value of the stack pointer register to the top of the stack
......
...@@ -267,9 +267,9 @@ struct GTY(()) dw_discr_list_node { ...@@ -267,9 +267,9 @@ struct GTY(()) dw_discr_list_node {
/* Interface from dwarf2out.c to dwarf2cfi.c. */ /* Interface from dwarf2out.c to dwarf2cfi.c. */
extern struct dw_loc_descr_node *build_cfa_loc extern struct dw_loc_descr_node *build_cfa_loc
(dw_cfa_location *, HOST_WIDE_INT); (dw_cfa_location *, poly_int64);
extern struct dw_loc_descr_node *build_cfa_aligned_loc extern struct dw_loc_descr_node *build_cfa_aligned_loc
(dw_cfa_location *, HOST_WIDE_INT offset, HOST_WIDE_INT alignment); (dw_cfa_location *, poly_int64, HOST_WIDE_INT);
extern struct dw_loc_descr_node *mem_loc_descriptor extern struct dw_loc_descr_node *mem_loc_descriptor
(rtx, machine_mode mode, machine_mode mem_mode, (rtx, machine_mode mode, machine_mode mem_mode,
enum var_init_status); enum var_init_status);
......
...@@ -4136,6 +4136,21 @@ the CFI label attached to the insn, @var{pattern} is the pattern of\n\ ...@@ -4136,6 +4136,21 @@ the CFI label attached to the insn, @var{pattern} is the pattern of\n\
the insn and @var{index} is @code{UNSPEC_INDEX} or @code{UNSPECV_INDEX}.", the insn and @var{index} is @code{UNSPEC_INDEX} or @code{UNSPECV_INDEX}.",
void, (const char *label, rtx pattern, int index), NULL) void, (const char *label, rtx pattern, int index), NULL)
DEFHOOK
(dwarf_poly_indeterminate_value,
"Express the value of @code{poly_int} indeterminate @var{i} as a DWARF\n\
expression, with @var{i} counting from 1. Return the number of a DWARF\n\
register @var{R} and set @samp{*@var{factor}} and @samp{*@var{offset}} such\n\
that the value of the indeterminate is:\n\
@smallexample\n\
value_of(@var{R}) / @var{factor} - @var{offset}\n\
@end smallexample\n\
\n\
A target only needs to define this hook if it sets\n\
@samp{NUM_POLY_INT_COEFFS} to a value greater than 1.",
unsigned int, (unsigned int i, unsigned int *factor, int *offset),
default_dwarf_poly_indeterminate_value)
/* ??? Documenting this hook requires a GFDL license grant. */ /* ??? Documenting this hook requires a GFDL license grant. */
DEFHOOK_UNDOC DEFHOOK_UNDOC
(stdarg_optimize_hook, (stdarg_optimize_hook,
......
...@@ -1874,6 +1874,15 @@ default_debug_unwind_info (void) ...@@ -1874,6 +1874,15 @@ default_debug_unwind_info (void)
return UI_NONE; return UI_NONE;
} }
/* Targets that set NUM_POLY_INT_COEFFS to something greater than 1
must define this hook. */
unsigned int
default_dwarf_poly_indeterminate_value (unsigned int, unsigned int *, int *)
{
gcc_unreachable ();
}
/* Determine the correct mode for a Dwarf frame register that represents /* Determine the correct mode for a Dwarf frame register that represents
register REGNO. */ register REGNO. */
......
...@@ -238,6 +238,9 @@ extern int default_label_align_max_skip (rtx_insn *); ...@@ -238,6 +238,9 @@ extern int default_label_align_max_skip (rtx_insn *);
extern int default_jump_align_max_skip (rtx_insn *); extern int default_jump_align_max_skip (rtx_insn *);
extern section * default_function_section(tree decl, enum node_frequency freq, extern section * default_function_section(tree decl, enum node_frequency freq,
bool startup, bool exit); bool startup, bool exit);
extern unsigned int default_dwarf_poly_indeterminate_value (unsigned int,
unsigned int *,
int *);
extern machine_mode default_dwarf_frame_reg_mode (int); extern machine_mode default_dwarf_frame_reg_mode (int);
extern fixed_size_mode default_get_reg_raw_mode (int); extern fixed_size_mode default_get_reg_raw_mode (int);
extern bool default_keep_leaf_when_profiled (); extern bool default_keep_leaf_when_profiled ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment