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: [stack] PATCH: PR debug/36728: gdb doesn't work with stack alignment


On Fri, Jul 04, 2008 at 01:24:43PM -0700, H.J. Lu wrote:
> We need to use cfa+offset to represent the location of rguments passed
> on stack when drap is used to align stack. I am testing this patch.
> I will check it in if all pass.
> 
> 

We need to handle

set vdrap drap

very carefully. vdrap may be register or memory.  We should only use
it to set vdrap_reg if vdrap is register and never confuse it with 

set mem drap

when vdrap is memory.  This is the patch I checked in.

Thanks.


H.J.
---
Index: ChangeLog.stackalign
===================================================================
--- ChangeLog.stackalign	(revision 137477)
+++ ChangeLog.stackalign	(working copy)
@@ -1,3 +1,21 @@
+2008-07-05  H.J. Lu  <hongjiu.lu@intel.com>
+	    Xuepeng Guo  <xuepeng.guo@intel.com>
+
+	PR debug/36728
+	* dwarf2out.c (dw_fde_node): Add drap_reg and vdrap_reg.  Remove
+	cfa_uses_expression.
+	(add_cfi): Check drap_reg instead of cfa_uses_expression.
+	(dwarf2out_frame_debug_expr): Add rule 20 to handle virtual
+	drap.  Update rule 19 to set drap_reg instead of
+	cfa_uses_expression.
+	(dwarf2out_begin_prologue): Initialize drap_reg and vdrap_reg
+	to INVALID_REGNUM.
+	(based_loc_descr): Use cfa+offset to represent the location of
+	arguments passed on stack when drap is used to align stack.
+
+	* config/i386/i386.c (ix86_get_drap_rtx): Set RTX_FRAME_RELATED_P
+	bit on virtual drap insn.
+
 2008-07-04  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* cfgexpand.c (expand_stack_alignment): Fix a typo in comments.
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 137477)
+++ dwarf2out.c	(working copy)
@@ -240,13 +240,15 @@ typedef struct dw_fde_struct GTY(())
   dw_cfi_ref dw_fde_cfi;
   unsigned funcdef_number;
   HOST_WIDE_INT stack_realignment;
+  /* Dynamic realign argument pointer register.  */
+  unsigned int drap_reg;
+  /* Virtual dynamic realign argument pointer register.  */
+  unsigned int vdrap_reg;
   unsigned all_throwers_are_sibcalls : 1;
   unsigned nothrow : 1;
   unsigned uses_eh_lsda : 1;
   /* Whether we did stack realign in this call frame.  */
   unsigned stack_realign : 1;
-  /* Whether cfa is defined by expression.  */
-  unsigned cfa_uses_expression : 1;
 }
 dw_fde_node;
 
@@ -628,10 +630,9 @@ add_cfi (dw_cfi_ref *list_head, dw_cfi_r
   dw_cfi_ref *p;
   dw_fde_ref fde = current_fde ();
 
-  /* When the CFA is defined with an expression, redefine it may lead
-     to a different CFA value.  FIXME: Will the value of CFA expression
-     ever change?   */
-  if (fde && fde->cfa_uses_expression)
+  /* When DRAP is used, CFA is defined with an expression.  Redefine
+     CFA may lead to a different CFA value.   */
+  if (fde && fde->drap_reg != INVALID_REGNUM)
     switch (cfi->dw_cfi_opc)
       {
         case DW_CFA_def_cfa_register:
@@ -1418,7 +1419,7 @@ static dw_cfa_location cfa_temp;
 	       difference of the original location and cfa_store's
 	       location (or cfa_temp's location if cfa_temp is used).
 
-  Rules 16-19: If AND operation happens on sp in prologue, we assume
+  Rules 16-20: If AND operation happens on sp in prologue, we assume
 	       stack is realigned.  We will use a group of DW_OP_XXX
 	       expressions to represent the location of the stored
 	       register instead of CFA+offset.
@@ -1540,7 +1541,22 @@ static dw_cfa_location cfa_temp;
                && cfa.offset == 0
                && cfa.indirect == 0
                && cfa.reg != HARD_FRAME_POINTER_REGNUM
-  effects: Use DW_CFA_def_cfa_expression to define cfa.  */
+  effects: Use DW_CFA_def_cfa_expression to define cfa.
+
+  Rule 20:
+  Special case for set (vdrap drap)
+  (set reg cfa.reg})
+  constraints: fde->stack_realign == 1
+               && cfa.offset == 0
+               && cfa.indirect == 0
+               && cfa.reg != HARD_FRAME_POINTER_REGNUM
+  effects: fde->vdrap_reg = reg
+  (set reg drap_reg)
+  constraints: fde->stack_realign == 1
+  effects: fde->vdrap_reg = reg.
+  (set mem drap_reg)
+  constraints: fde->stack_realign == 1
+  effects: none.  */
 
 static void
 dwarf2out_frame_debug_expr (rtx expr, const char *label)
@@ -1600,6 +1616,29 @@ dwarf2out_frame_debug_expr (rtx expr, co
 
   fde = current_fde ();
 
+  if (GET_CODE (src) == REG
+      && fde
+      && fde->stack_realign
+      && ((fde->drap_reg != INVALID_REGNUM
+	   && fde->drap_reg == REGNO (src))
+	  || (GET_CODE (dest) == REG
+	      && cfa.offset == 0
+	      && cfa.indirect == 0
+	      && cfa.reg != HARD_FRAME_POINTER_REGNUM
+	      && cfa.reg == (unsigned) REGNO (src))))
+    {
+      /* Rule 20 */
+      /* If we are saving dynamic realign argument pointer to a
+	 register, the destination is virtual dynamic realign
+	 argument pointer.  It may be used to access argument.  */
+      if (GET_CODE (dest) == REG)
+	{
+	  gcc_assert (fde->vdrap_reg == INVALID_REGNUM);
+	  fde->vdrap_reg = REGNO (dest);
+	}
+      return;
+    }
+
   switch (GET_CODE (dest))
     {
     case REG:
@@ -1907,18 +1946,18 @@ dwarf2out_frame_debug_expr (rtx expr, co
                   && cfa.indirect == 0
                   && cfa.reg != HARD_FRAME_POINTER_REGNUM)
                 {
-                  dw_cfa_location cfa_uses_expression;
+		  dw_cfa_location cfa_exp;
 
-                  cfa_uses_expression.indirect = 1;
-                  cfa_uses_expression.reg = HARD_FRAME_POINTER_REGNUM;
-                  cfa_uses_expression.base_offset = offset;
-                  cfa_uses_expression.offset = 0;
+		  cfa_exp.indirect = 1;
+		  cfa_exp.reg = HARD_FRAME_POINTER_REGNUM;
+		  cfa_exp.base_offset = offset;
+		  cfa_exp.offset = 0;
 
-                  def_cfa_1 (label, &cfa_uses_expression);
+		  fde->drap_reg = cfa.reg;
 
-                  fde->cfa_uses_expression = 1;
+		  def_cfa_1 (label, &cfa_exp);
 
-                  queue_reg_save (label, stack_pointer_rtx, NULL_RTX, 
+		  queue_reg_save (label, stack_pointer_rtx, NULL_RTX,
 				  offset);
                   break;
                 }
@@ -2729,6 +2768,8 @@ dwarf2out_begin_prologue (unsigned int l
   fde->nothrow = TREE_NOTHROW (current_function_decl);
   fde->uses_eh_lsda = crtl->uses_eh_lsda;
   fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
+  fde->drap_reg = INVALID_REGNUM;
+  fde->vdrap_reg = INVALID_REGNUM;
 
   args_size = old_args_size = 0;
 
@@ -3699,7 +3740,7 @@ reg_save (const char *label, unsigned in
 
       /* When CFA is defined as FP+OFFSET, emulate stack alignment.  */
       if (cfa.reg == HARD_FRAME_POINTER_REGNUM
-          && cfa.indirect == 0)
+	  && cfa.indirect == 0)
 	{
 	  if (dwarf_fp <= 31)
 	    head = tmp = new_loc_descr (DW_OP_breg0 + dwarf_fp, 0, 0);
@@ -9170,8 +9211,6 @@ based_loc_descr (rtx reg, HOST_WIDE_INT 
   unsigned int regno;
   dw_loc_descr_ref result;
   dw_fde_ref fde = current_fde ();
-  unsigned int dwarf_fp = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
-  unsigned int dwarf_sp = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);
 
   /* 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
@@ -9195,8 +9234,8 @@ based_loc_descr (rtx reg, HOST_WIDE_INT 
 				  ? hard_frame_pointer_rtx
 				  : stack_pointer_rtx));
 
-	  /* If stack is aligned while drap register used, use frame
-	     pointer + offset to access stack variables. If stack
+	  /* If drap register is used to align stack, use frame
+	     pointer + offset to access stack variables.  If stack
 	     is aligned without drap, use stack pointer + offset to
 	     access stack variables.  */
 	  if (fde
@@ -9204,7 +9243,10 @@ based_loc_descr (rtx reg, HOST_WIDE_INT 
 	      && cfa.reg == HARD_FRAME_POINTER_REGNUM
 	      && reg == frame_pointer_rtx)
 	    {
-	      int base_reg = cfa.indirect ? dwarf_fp : dwarf_sp;
+	      int base_reg
+		= DWARF_FRAME_REGNUM (cfa.indirect
+				      ? HARD_FRAME_POINTER_REGNUM
+				      : STACK_POINTER_REGNUM);
 	      if (base_reg <= 31)
 		return new_loc_descr (DW_OP_breg0 + base_reg, offset, 0);
 	      else
@@ -9215,6 +9257,15 @@ based_loc_descr (rtx reg, HOST_WIDE_INT 
 	  return new_loc_descr (DW_OP_fbreg, offset, 0);
 	}
     }
+  else if (fde
+	   && fde->drap_reg != INVALID_REGNUM
+	   && (fde->drap_reg == REGNO (reg)
+	       || fde->vdrap_reg == REGNO (reg)))
+    {
+      /* Use cfa+offset to represent the location of arguments passed
+	 on stack when drap is used to align stack.  */
+      return new_loc_descr (DW_OP_fbreg, offset, 0);
+    }
 
   regno = dbx_reg_number (reg);
   if (regno <= 31)
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 137477)
+++ config/i386/i386.c	(working copy)
@@ -6628,7 +6628,7 @@ ix86_get_drap_rtx (void)
       unsigned int regno = find_drap_reg ();
       rtx drap_vreg;
       rtx arg_ptr;
-      rtx seq;
+      rtx seq, insn;
 
       arg_ptr = gen_rtx_REG (Pmode, regno);
       crtl->drap_reg = arg_ptr;
@@ -6638,7 +6638,8 @@ ix86_get_drap_rtx (void)
       seq = get_insns ();
       end_sequence ();
       
-      emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
+      insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
+      RTX_FRAME_RELATED_P (insn) = 1;
       return drap_vreg;
     }
   else


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