This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [DWARF] Fix multiple register spanning location.
- From: Christian Bruel <christian dot bruel at st dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>, Ramana Radhakrishnan <ramana dot radhakrishnan at arm dot com>, rmansfield at qnx dot com <gcc-bugzilla at gcc dot gnu dot org>, ktkachov at gcc dot gnu.org <gcc-bugzilla at gcc dot gnu dot org>, Cary Coutant <ccoutant at google dot com>
- Date: Mon, 27 May 2013 17:46:22 +0200
- Subject: Re: [DWARF] Fix multiple register spanning location.
- References: <5188AFC2 dot 1000105 at st dot com> <CAHACq4qimMoZ3xZdU8_Mq=bLi0q0s=Wa2=5HLWuEx7HvqRnEAA at mail dot gmail dot com>
On 05/16/2013 12:27 AM, Cary Coutant wrote:
>>> How about using dbx_reg_number (XVECEXP (regs, 0, i)) instead? The
>>> bare use of DBX_REGISTER_NUMBER earlier in that function is protected
>>> by a gcc_assert, but this one isn't.
>>
For the respective targets maintainers that drop into the thread: Here
is a summary of the problem:
Since http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00209.html, dwarf
double floating point registers are not correctly described for the SH.
But this patch was needed to fix an assertion in the dwarf2cfi.
Therefore, we have a discrepancy between the different targets, that can
result in assertions, (or possibly silent wrong unwind code I believe)
SH,MIPS,C6X ; dwarf_register_span returns hard_reg numbers. regno is
never translated for DBX
ARM NEON ; converts regno into DBX
numbers
POWERPC ; ? returns boths.
So a second set of patches
http://gcc.gnu.org/ml/gcc-patches/2013-05/msg01230.html
http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00312.html
fixed it with a common rule. All interfaces are changed to return
hard_reg numbers only. multiple_reg_location is in charge of calling
DBX_REGISTER_NUMBER with an assertion check.
Well, in fact this was not doing some good for the powerpc, that now
asserts here. The problem is that rs6000_dwarf_register_span stores in
the PARALLEL rtx both the hard reg and the dbx reg, so we can't call
dbx_reg_number in it.
Using DBX_REGISTER_NUMBER instead of dbx_reg_number restores the
previous working status for all targets. This is
dwarf-span-assert-rs6000.patch for reference.
However I feel a little bit uncomfortable with this solution that
doesn't seem to fix the root cause. The dbx_register_number hooks is
called basically from two places : dwarf2cfi.c and dwarf2out.c. That
show different uses: either we want to refer to the hard regno when
dealing with the cfa description (whereas we want DWARF_FRAME_REGNUM,
not DBX_REGISTER_NUMBER). or we use the DBX_REGISTER_NUMBER for output
register locations.
Since this information cannot be detected contextually, I'd like to
extend the dwarf_register_span target hook to return a dbx number or
not. This is dwarf-span-target-dbx.patch
build tested with the configurations that failed at one time or the other:
- sh64-unknown-elf (The original sh64-elf build failure assertion in
dwarf2cfi is fixed.)
- arm-none-eabi -with-fpu=neon-vfpv4
- powerpc-e500v2-linux-gnuspe
- x86_64-unknown-linux-gnu sanity build OK
Is dwarf-span-target-dbx.patch OK for trunk ?. More comments ?
Many Thanks,
Christian
2013-05-23 Christian Bruel <christian.bruel@st.com>
PR debug/57351
PR debug/57389
* config/arm/arm.c (arm_dwarf_register_span): Add bool dbx parameter.
* config/c6x/c6x.c (c6x_dwarf_register_span): Likewise.
* config/mips/mips (mips_dwarf_register_span): Likewise.
* config/rs6000/rs6000.c (rs6000_dwarf_register_span): Likewise.
* config/sh/sh.c (sh_dwarf_register_span): Likewise. Declare static.
* config/sh/sh-protos.h (sh_dwarf_register_span): Remove declaration.
* gcc/doc/tm.texi: Add bool dbx parameter.
* gcc/target.def: Likewise,
* gcc/dwarf2cfi.c (dwarf2out_frame_debug_cfa_offset): Don't span dbx.
(dwarf2out_frame_debug_cfa_expression): Don't span dbx.
* gcc/dwarf2out.c (reg_loc_descriptor): Span dbx.
* gcc/hooks.c: (hook_rtx_bool_null): Define.
* gcc/hooks.h: (hook_rtx_bool_null): Declare.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c (revision 199354)
+++ gcc/config/arm/arm.c (working copy)
@@ -213,7 +213,7 @@ static bool arm_output_ttype (rtx);
static void arm_asm_emit_except_personality (rtx);
static void arm_asm_init_sections (void);
#endif
-static rtx arm_dwarf_register_span (rtx);
+static rtx arm_dwarf_register_span (rtx, bool);
static tree arm_cxx_guard_type (void);
static bool arm_cxx_guard_mask_bit (void);
@@ -25855,7 +25855,7 @@ arm_dbx_register_number (unsigned int regno)
GCC models tham as 64 32-bit registers, so we need to describe this to
the DWARF generation code. Other registers can use the default. */
static rtx
-arm_dwarf_register_span (rtx rtl)
+arm_dwarf_register_span (rtx rtl, bool dbx)
{
unsigned regno;
int nregs;
@@ -25878,6 +25878,8 @@ static rtx
nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8;
p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs));
+ if (dbx)
+ regno = 256 + (regno - FIRST_VFP_REGNUM) / 2;
for (i = 0; i < nregs; i++)
XVECEXP (p, 0, i) = gen_rtx_REG (DImode, regno + i);
Index: gcc/config/c6x/c6x.c
===================================================================
--- gcc/config/c6x/c6x.c (revision 199354)
+++ gcc/config/c6x/c6x.c (working copy)
@@ -6304,7 +6304,7 @@ c6x_set_return_address (rtx source, rtx scratch)
registers for DWARF generation code. */
static rtx
-c6x_dwarf_register_span (rtx rtl)
+c6x_dwarf_register_span (rtx rtl, bool dbx ATTRIBUTE_UNUSED)
{
unsigned regno;
unsigned real_regno;
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c (revision 199354)
+++ gcc/config/mips/mips.c (working copy)
@@ -8533,7 +8533,7 @@ mips_output_dwarf_dtprel (FILE *file, int size, rt
/* Implement TARGET_DWARF_REGISTER_SPAN. */
static rtx
-mips_dwarf_register_span (rtx reg)
+mips_dwarf_register_span (rtx reg, bool dbx ATTRIBUTE_UNUSED)
{
rtx high, low;
enum machine_mode mode;
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 199354)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -27738,7 +27738,7 @@ rs6000_initial_elimination_offset (int from, int t
}
static rtx
-rs6000_dwarf_register_span (rtx reg)
+rs6000_dwarf_register_span (rtx reg, bool dbx ATTRIBUTE_UNUSED)
{
rtx parts[8];
int i, words;
Index: gcc/config/sh/sh-protos.h
===================================================================
--- gcc/config/sh/sh-protos.h (revision 199354)
+++ gcc/config/sh/sh-protos.h (working copy)
@@ -214,7 +214,6 @@ extern rtx sh_get_pr_initial_val (void);
extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
signed int, enum machine_mode);
-extern rtx sh_dwarf_register_span (rtx);
extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
extern int shmedia_cleanup_truncate (rtx *, void *);
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c (revision 199354)
+++ gcc/config/sh/sh.c (working copy)
@@ -303,6 +303,7 @@ static rtx sh_function_arg (cumulative_args_t, enu
const_tree, bool);
static bool sh_scalar_mode_supported_p (enum machine_mode);
static int sh_dwarf_calling_convention (const_tree);
+static rtx sh_dwarf_register_span (rtx, bool);
static void sh_encode_section_info (tree, rtx, int);
static bool sh2a_function_vector_p (tree);
static void sh_trampoline_init (rtx, tree, rtx);
@@ -8760,14 +8761,17 @@ sh_gimplify_va_arg_expr (tree valist, tree type, g
/* 64 bit floating points memory transfers are paired single precision loads
or store. So DWARF information needs fixing in little endian (unless
PR=SZ=1 in FPSCR). */
-rtx
-sh_dwarf_register_span (rtx reg)
+static rtx
+sh_dwarf_register_span (rtx reg, bool dbx)
{
unsigned regno = REGNO (reg);
if (WORDS_BIG_ENDIAN || GET_MODE (reg) != DFmode)
return NULL_RTX;
+ if (dbx)
+ regno = DBX_REGISTER_NUMBER (regno);
+
return
gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (2,
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi (revision 199354)
+++ gcc/doc/tm.texi (working copy)
@@ -8971,7 +8971,7 @@ Default value is false if @code{EH_FRAME_SECTION_N
true otherwise.
@end deftypevr
-@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg})
+@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg}, @var{bool})
Given a register, this hook should return a parallel of registers to
represent where to find the register pieces. Define this hook if the
register and its mode are represented in Dwarf in non-contiguous
Index: gcc/dwarf2cfi.c
===================================================================
--- gcc/dwarf2cfi.c (revision 199354)
+++ gcc/dwarf2cfi.c (working copy)
@@ -1134,7 +1134,7 @@ dwarf2out_frame_debug_cfa_offset (rtx set)
}
else
{
- span = targetm.dwarf_register_span (src);
+ span = targetm.dwarf_register_span (src, false);
sregno = dwf_regno (src);
}
@@ -1203,7 +1203,7 @@ dwarf2out_frame_debug_cfa_expression (rtx set)
gcc_assert (REG_P (src));
gcc_assert (MEM_P (dest));
- span = targetm.dwarf_register_span (src);
+ span = targetm.dwarf_register_span (src, false);
gcc_assert (!span);
regno = dwf_regno (src);
@@ -1882,7 +1882,7 @@ dwarf2out_frame_debug_expr (rtx expr)
span = NULL;
if (REG_P (src))
- span = targetm.dwarf_register_span (src);
+ span = targetm.dwarf_register_span (src, false);
if (!span)
queue_reg_save (src, NULL_RTX, offset);
else
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c (revision 199354)
+++ gcc/dwarf2out.c (working copy)
@@ -10572,7 +10572,7 @@ reg_loc_descriptor (rtx rtl, enum var_init_status
return result;
}
- regs = targetm.dwarf_register_span (rtl);
+ regs = targetm.dwarf_register_span (rtl, true);
if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
return multiple_reg_loc_descriptor (rtl, regs, initialized);
@@ -10660,7 +10660,7 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
{
dw_loc_descr_ref t;
- t = one_reg_loc_descriptor (dbx_reg_number (XVECEXP (regs, 0, i)),
+ t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)),
VAR_INIT_STATUS_INITIALIZED);
add_loc_descr (&loc_result, t);
add_loc_descr_op_piece (&loc_result, size);
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c (revision 199354)
+++ gcc/hooks.c (working copy)
@@ -338,13 +338,20 @@ hook_rtx_rtx_identity (rtx x)
return x;
}
-/* Generic hook that takes an rtx and returns NULL_RTX. */
+/* Generic hook that takes a rtx and returns NULL_RTX. */
rtx
hook_rtx_rtx_null (rtx x ATTRIBUTE_UNUSED)
{
return NULL;
}
+/* Generic hook that takes a rtx and a bool and returns NULL_RTX. */
+rtx
+hook_rtx_bool_null (rtx x ATTRIBUTE_UNUSED, bool dbx ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
/* Generic hook that takes a tree and an int and returns NULL_RTX. */
rtx
hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h (revision 199354)
+++ gcc/hooks.h (working copy)
@@ -95,6 +95,7 @@ extern bool default_can_output_mi_thunk_no_vcall (
extern rtx hook_rtx_rtx_identity (rtx);
extern rtx hook_rtx_rtx_null (rtx);
+extern rtx hook_rtx_bool_null (rtx, bool dbx);
extern rtx hook_rtx_tree_int_null (tree, int);
extern const char *hook_constcharptr_void_null (void);
Index: gcc/target.def
===================================================================
--- gcc/target.def (revision 199354)
+++ gcc/target.def (working copy)
@@ -1850,8 +1850,8 @@ DEFHOOK
DEFHOOK
(dwarf_register_span,
"",
- rtx, (rtx reg),
- hook_rtx_rtx_null)
+ rtx, (rtx reg, bool),
+ hook_rtx_bool_null)
/* If expand_builtin_init_dwarf_reg_sizes needs to fill in table
entries not corresponding directly to registers below
2013-05-23 Christian Bruel <christian.bruel@st.com>
PR debug/57389
* dwarf2out.c (multiple_reg_loc_descriptor): Use DBX_REGISTER_NUMBER
instead of dbx_reg_number.
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c (revision 199354)
+++ gcc/dwarf2out.c (working copy)
@@ -10660,8 +10660,11 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
{
dw_loc_descr_ref t;
- t = one_reg_loc_descriptor (dbx_reg_number (XVECEXP (regs, 0, i)),
+ /* Cannot use dbx_reg_number here because regno could be out of the hard-reg
+ range and not handled by DBX_REGISTER_NUMBER. See rs6000.h. */
+ t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (REGNO (XVECEXP (regs, 0, i))),
VAR_INIT_STATUS_INITIALIZED);
+
add_loc_descr (&loc_result, t);
add_loc_descr_op_piece (&loc_result, size);
}