This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [DWARF] Fix multiple register spanning location.


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);
     }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]