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: [CFT] re-organize var-tracking frame_base


On Thu, Sep 08, 2005 at 10:00:46PM -0400, John David Anglin wrote:
> ../../gcc/gcc/libgcc2.c:1168: internal compiler error: in dbx_reg_number...

Try number 2.  This one at least builds libgcc on cross.

I noticed a buglet in the unwind info.  As far as I can tell, what
I'm emitting now should be good enough to actually work, if you'd
like to turn on dwarf2 unwinding and try it out...

I also noticed that var-tracking doesn't know how to cope with
memory addresses that might become invalidated, as with your
non-fixed argument pointer.  That's a different kind of bug though.


r~



Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.614
diff -u -p -d -r1.614 dwarf2out.c
--- dwarf2out.c	7 Sep 2005 07:47:08 -0000	1.614
+++ dwarf2out.c	9 Sep 2005 05:04:29 -0000
@@ -214,7 +214,7 @@ enum dw_cfi_oprnd_type {
 
 typedef union dw_cfi_oprnd_struct GTY(())
 {
-  unsigned long GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num;
+  unsigned int GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num;
   HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset;
   const char * GTY ((tag ("dw_cfi_oprnd_addr"))) dw_cfi_addr;
   struct dw_loc_descr_struct * GTY ((tag ("dw_cfi_oprnd_loc"))) dw_cfi_loc;
@@ -671,6 +671,10 @@ lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_loc
     case DW_CFA_def_cfa_offset:
       loc->offset = cfi->dw_cfi_oprnd1.dw_cfi_offset;
       break;
+    case DW_CFA_def_cfa_offset_sf:
+      loc->offset
+	= cfi->dw_cfi_oprnd1.dw_cfi_offset * DWARF_CIE_DATA_ALIGNMENT;
+      break;
     case DW_CFA_def_cfa_register:
       loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
       break;
@@ -678,6 +682,11 @@ lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_loc
       loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
       loc->offset = cfi->dw_cfi_oprnd2.dw_cfi_offset;
       break;
+    case DW_CFA_def_cfa_sf:
+      loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
+      loc->offset
+	= cfi->dw_cfi_oprnd2.dw_cfi_offset * DWARF_CIE_DATA_ALIGNMENT;
+      break;
     case DW_CFA_def_cfa_expression:
       get_cfa_from_loc_descr (loc, cfi->dw_cfi_oprnd1.dw_cfi_loc);
       break;
@@ -775,11 +784,21 @@ def_cfa_1 (const char *label, dw_cfa_loc
 
   if (loc.reg == old_cfa.reg && !loc.indirect)
     {
-      /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction,
-	 indicating the CFA register did not change but the offset
-	 did.  */
-      cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
-      cfi->dw_cfi_oprnd1.dw_cfi_offset = loc.offset;
+      /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction, indicating
+	 the CFA register did not change but the offset did.  */
+      if (loc.offset < 0)
+	{
+	  HOST_WIDE_INT f_offset = loc.offset / DWARF_CIE_DATA_ALIGNMENT;
+	  gcc_assert (f_offset * DWARF_CIE_DATA_ALIGNMENT == loc.offset);
+
+	  cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
+	  cfi->dw_cfi_oprnd1.dw_cfi_offset = f_offset;
+	}
+      else
+	{
+	  cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
+	  cfi->dw_cfi_oprnd1.dw_cfi_offset = loc.offset;
+	}
     }
 
 #ifndef MIPS_DEBUGGING_INFO  /* SGI dbx thinks this means no offset.  */
@@ -800,9 +819,21 @@ def_cfa_1 (const char *label, dw_cfa_loc
       /* Construct a "DW_CFA_def_cfa <register> <offset>" instruction,
 	 indicating the CFA register has changed to <register> with
 	 the specified offset.  */
-      cfi->dw_cfi_opc = DW_CFA_def_cfa;
-      cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg;
-      cfi->dw_cfi_oprnd2.dw_cfi_offset = loc.offset;
+      if (loc.offset < 0)
+	{
+	  HOST_WIDE_INT f_offset = loc.offset / DWARF_CIE_DATA_ALIGNMENT;
+	  gcc_assert (f_offset * DWARF_CIE_DATA_ALIGNMENT == loc.offset);
+
+	  cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
+	  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg;
+	  cfi->dw_cfi_oprnd2.dw_cfi_offset = f_offset;
+	}
+      else
+	{
+	  cfi->dw_cfi_opc = DW_CFA_def_cfa;
+	  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg;
+	  cfi->dw_cfi_oprnd2.dw_cfi_offset = loc.offset;
+	}
     }
   else
     {
@@ -8431,12 +8462,6 @@ dbx_reg_number (rtx rtl)
 {
   unsigned regno = REGNO (rtl);
 
-  /* We do not want to see registers that should have been eliminated.  */
-  gcc_assert (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
-	      || rtl != arg_pointer_rtx);
-  gcc_assert (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM
-	      || rtl != frame_pointer_rtx);
-
   gcc_assert (regno < FIRST_PSEUDO_REGISTER);
 
 #ifdef LEAF_REG_REMAP
@@ -8586,32 +8611,12 @@ int_loc_descriptor (HOST_WIDE_INT i)
   return new_loc_descr (op, i, 0);
 }
 
-/* Return an offset from an eliminable register to the post-prologue
-   frame pointer.  */
-
-static HOST_WIDE_INT
-eliminate_reg_to_offset (rtx reg)
-{
-  HOST_WIDE_INT offset = 0;
-
-  reg = eliminate_regs (reg, VOIDmode, NULL_RTX);
-  if (GET_CODE (reg) == PLUS)
-    {
-      offset = INTVAL (XEXP (reg, 1));
-      reg = XEXP (reg, 0);
-    }
-  gcc_assert (reg == (frame_pointer_needed ? hard_frame_pointer_rtx
-		      : stack_pointer_rtx));
-
-  return offset;
-}
-
 /* Return a location descriptor that designates a base+offset location.  */
 
 static dw_loc_descr_ref
 based_loc_descr (rtx reg, HOST_WIDE_INT offset)
 {
-  dw_loc_descr_ref loc_result;
+  unsigned int regno;
 
   /* We only use "frame base" when we're sure we're talking about the
      post-prologue local stack frame.  We do this by *not* running
@@ -8619,22 +8624,28 @@ based_loc_descr (rtx reg, HOST_WIDE_INT 
      argument pointer and soft frame pointer rtx's.  */
   if (reg == arg_pointer_rtx || reg == frame_pointer_rtx)
     {
-      offset += eliminate_reg_to_offset (reg);
-      offset += frame_pointer_cfa_offset;
+      rtx elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
 
-      loc_result = new_loc_descr (DW_OP_fbreg, offset, 0);
-    }
-  else
-    {
-      unsigned int regno = dbx_reg_number (reg);
+      if (elim != reg)
+	{
+	  if (GET_CODE (elim) == PLUS)
+	    {
+	      offset += INTVAL (XEXP (elim, 1));
+	      elim = XEXP (elim, 0);
+	    }
+	  gcc_assert (elim == (frame_pointer_needed ? hard_frame_pointer_rtx
+		      : stack_pointer_rtx));
+          offset += frame_pointer_cfa_offset;
 
-      if (regno <= 31)
-	loc_result = new_loc_descr (DW_OP_breg0 + regno, offset, 0);
-      else
-	loc_result = new_loc_descr (DW_OP_bregx, regno, offset);
+          return new_loc_descr (DW_OP_fbreg, offset, 0);
+	}
     }
 
-  return loc_result;
+  regno = dbx_reg_number (reg);
+  if (regno <= 31)
+    return new_loc_descr (DW_OP_breg0 + regno, offset, 0);
+  else
+    return new_loc_descr (DW_OP_bregx, regno, offset);
 }
 
 /* Return true if this RTL expression describes a base+offset calculation.  */
@@ -10372,9 +10383,24 @@ static void
 compute_frame_pointer_to_cfa_displacement (void)
 {
   HOST_WIDE_INT offset;
+  rtx reg, elim;
 
-  offset = eliminate_reg_to_offset (arg_pointer_rtx);
-  offset += ARG_POINTER_CFA_OFFSET (current_function_decl);
+#ifdef FRAME_POINTER_CFA_OFFSET
+  reg = frame_pointer_rtx;
+  offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
+#else
+  reg = arg_pointer_rtx;
+  offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
+#endif
+
+  elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
+  if (GET_CODE (elim) == PLUS)
+    {
+      offset += INTVAL (XEXP (elim, 1));
+      elim = XEXP (elim, 0);
+    }
+  gcc_assert (elim == (frame_pointer_needed ? hard_frame_pointer_rtx
+		       : stack_pointer_rtx));
 
   frame_pointer_cfa_offset = -offset;
 }
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.644
diff -u -p -d -r1.644 function.c
--- function.c	7 Sep 2005 07:47:08 -0000	1.644
+++ function.c	9 Sep 2005 05:04:30 -0000
@@ -1231,7 +1231,14 @@ instantiate_new_reg (rtx x, HOST_WIDE_IN
   else if (x == virtual_outgoing_args_rtx)
     new = stack_pointer_rtx, offset = out_arg_offset;
   else if (x == virtual_cfa_rtx)
-    new = arg_pointer_rtx, offset = cfa_offset;
+    {
+#ifdef FRAME_POINTER_CFA_OFFSET
+      new = frame_pointer_rtx;
+#else
+      new = arg_pointer_rtx;
+#endif
+      offset = cfa_offset;
+    }
   else
     return NULL_RTX;
 
@@ -1617,7 +1624,11 @@ instantiate_virtual_regs (void)
   var_offset = STARTING_FRAME_OFFSET;
   dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
   out_arg_offset = STACK_POINTER_OFFSET;
+#ifdef FRAME_POINTER_CFA_OFFSET
+  cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
+#else
   cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
+#endif
 
   /* Initialize recognition, indicating that volatile is OK.  */
   init_recog ();
Index: unwind-dw2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unwind-dw2.c,v
retrieving revision 1.54
diff -u -p -d -r1.54 unwind-dw2.c
--- unwind-dw2.c	25 Jun 2005 02:01:58 -0000	1.54
+++ unwind-dw2.c	9 Sep 2005 05:04:30 -0000
@@ -902,7 +902,7 @@ execute_cfa_program (const unsigned char
 	  insn_ptr += utmp;
 	  break;
 
-	  /* From the 2.1 draft.  */
+	  /* From the dwarf3 draft.  */
 	case DW_CFA_offset_extended_sf:
 	  insn_ptr = read_uleb128 (insn_ptr, &reg);
 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
@@ -916,10 +916,12 @@ execute_cfa_program (const unsigned char
 	  insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
 	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
 	  fs->cfa_how = CFA_REG_OFFSET;
+	  fs->cfa_offset *= fs->data_align;
 	  break;
 
 	case DW_CFA_def_cfa_offset_sf:
 	  insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
+	  fs->cfa_offset *= fs->data_align;
 	  /* cfa_how deliberately not set.  */
 	  break;
 
Index: var-tracking.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/var-tracking.c,v
retrieving revision 2.32
diff -u -p -d -r2.32 var-tracking.c
--- var-tracking.c	7 Sep 2005 07:47:15 -0000	2.32
+++ var-tracking.c	9 Sep 2005 05:04:30 -0000
@@ -557,8 +557,13 @@ adjust_stack_reference (rtx mem, HOST_WI
 {
   rtx addr, cfa, tmp;
 
+#ifdef FRAME_POINTER_CFA_OFFSET
+  adjustment -= FRAME_POINTER_CFA_OFFSET (current_function_decl);
+  cfa = plus_constant (frame_pointer_rtx, adjustment);
+#else
   adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl);
   cfa = plus_constant (arg_pointer_rtx, adjustment);
+#endif
 
   addr = replace_rtx (copy_rtx (XEXP (mem, 0)), stack_pointer_rtx, cfa);
   tmp = simplify_rtx (addr);
Index: config/pa/pa-linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa-linux.h,v
retrieving revision 1.39
diff -u -p -d -r1.39 pa-linux.h
--- config/pa/pa-linux.h	25 Jun 2005 01:21:52 -0000	1.39
+++ config/pa/pa-linux.h	9 Sep 2005 05:04:30 -0000
@@ -19,39 +19,6 @@ the Free Software Foundation, 51 Frankli
 Boston, MA 02110-1301, USA.  */
 
 
-/* A C expression whose value is RTL representing the location of the
-   incoming return address at the beginning of any function, before the
-   prologue.  You only need to define this macro if you want to support
-   call frame debugging information like that provided by DWARF 2.  */
-#define INCOMING_RETURN_ADDR_RTX (gen_rtx_REG (word_mode, 2))
-#define DWARF_FRAME_RETURN_COLUMN (DWARF_FRAME_REGNUM (2))
-
-/* This macro chooses the encoding of pointers embedded in the exception
-   handling sections.  If at all possible, this should be defined such
-   that the exception handling section will not require dynamic relocations,
-   and so may be read-only.
-
-   FIXME: We use DW_EH_PE_aligned to output a PLABEL constructor for
-   global function pointers.  */
-#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)			\
-  (CODE == 2 && GLOBAL ? DW_EH_PE_aligned : DW_EH_PE_absptr)
-
-/* Handle special EH pointer encodings.  Absolute, pc-relative, and
-   indirect are handled automatically.  Since pc-relative encoding is
-   not possible on the PA and we don't have the infrastructure for
-   data relative encoding, we use aligned plabels for global function
-   pointers.  */
-#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
-  do {									\
-    if (((ENCODING) & 0x0F) == DW_EH_PE_aligned)			\
-      {									\
-	fputs (integer_asm_op (SIZE, FALSE), FILE);			\
-	fputs ("P%", FILE);						\
-	assemble_name (FILE, XSTR (ADDR, 0));				\
-	goto DONE;							\
-      }									\
-    } while (0)
-
 #undef TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()		\
   do						\
Index: config/pa/pa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.307
diff -u -p -d -r1.307 pa.c
--- config/pa/pa.c	4 Sep 2005 14:51:58 -0000	1.307
+++ config/pa/pa.c	9 Sep 2005 05:04:32 -0000
@@ -3326,25 +3326,9 @@ store_reg_modify (int base, int reg, HOS
       RTX_FRAME_RELATED_P (insn) = 1;
 
       /* RTX_FRAME_RELATED_P must be set on each frame related set
-	 in a parallel with more than one element.  Don't set
-	 RTX_FRAME_RELATED_P in the first set if reg is temporary
-	 register 1. The effect of this operation is recorded in
-	 the initial copy.  */
-      if (reg != 1)
-	{
-	  RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 0)) = 1;
-	  RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
-	}
-      else
-	{
-	  /* The first element of a PARALLEL is always processed if it is
-	     a SET.  Thus, we need an expression list for this case.  */
-	  REG_NOTES (insn)
-	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
-		gen_rtx_SET (VOIDmode, basereg,
-			     gen_rtx_PLUS (word_mode, basereg, delta)),
-                REG_NOTES (insn));
-	}
+	 in a parallel with more than one element.  */
+      RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 0)) = 1;
+      RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
     }
 }
 
@@ -3578,17 +3562,7 @@ hppa_expand_prologue (void)
 	     frames.  */
 	  insn = emit_move_insn (tmpreg, frame_pointer_rtx);
 	  if (DO_FRAME_NOTES)
-	    {
-	      /* We need to record the frame pointer save here since the
-	         new frame pointer is set in the following insn.  */
-	      RTX_FRAME_RELATED_P (insn) = 1;
-	      REG_NOTES (insn)
-		= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
-		    gen_rtx_SET (VOIDmode,
-				 gen_rtx_MEM (word_mode, stack_pointer_rtx),
-			         frame_pointer_rtx),
-		    REG_NOTES (insn));
-	    }
+	    RTX_FRAME_RELATED_P (insn) = 1;
 
 	  insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
 	  if (DO_FRAME_NOTES)
Index: config/pa/pa.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.252
diff -u -p -d -r1.252 pa.h
--- config/pa/pa.h	6 Aug 2005 13:26:14 -0000	1.252
+++ config/pa/pa.h	9 Sep 2005 05:04:32 -0000
@@ -404,12 +404,42 @@ extern struct rtx_def *hppa_pic_save_rtx
   gen_rtx_MEM (word_mode,						\
 	       gen_rtx_PLUS (word_mode, frame_pointer_rtx,		\
 			     TARGET_64BIT ? GEN_INT (-16) : GEN_INT (-20)))
-			  	
 
-/* Offset from the argument pointer register value to the top of
-   stack.  This is different from FIRST_PARM_OFFSET because of the
-   frame marker.  */
-#define ARG_POINTER_CFA_OFFSET(FNDECL) 0
+/* Offset from the frame pointer register value to the top of stack.  */
+#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
+
+/* A C expression whose value is RTL representing the location of the
+   incoming return address at the beginning of any function, before the
+   prologue.  You only need to define this macro if you want to support
+   call frame debugging information like that provided by DWARF 2.  */
+#define INCOMING_RETURN_ADDR_RTX (gen_rtx_REG (word_mode, 2))
+#define DWARF_FRAME_RETURN_COLUMN (DWARF_FRAME_REGNUM (2))
+
+/* This macro chooses the encoding of pointers embedded in the exception
+   handling sections.  If at all possible, this should be defined such
+   that the exception handling section will not require dynamic relocations,
+   and so may be read-only.
+
+   FIXME: We use DW_EH_PE_aligned to output a PLABEL constructor for
+   global function pointers.  */
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)			\
+  (CODE == 2 && GLOBAL ? DW_EH_PE_aligned : DW_EH_PE_absptr)
+
+/* Handle special EH pointer encodings.  Absolute, pc-relative, and
+   indirect are handled automatically.  Since pc-relative encoding is
+   not possible on the PA and we don't have the infrastructure for
+   data relative encoding, we use aligned plabels for global function
+   pointers.  */
+#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
+  do {									\
+    if (((ENCODING) & 0x0F) == DW_EH_PE_aligned)			\
+      {									\
+	fputs (integer_asm_op (SIZE, FALSE), FILE);			\
+	fputs ("P%", FILE);						\
+	assemble_name (FILE, XSTR (ADDR, 0));				\
+	goto DONE;							\
+      }									\
+    } while (0)
 
 /* The letters I, J, K, L and M in a register constraint string
    can be used to stand for particular ranges of immediate operands.


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