Blame SOURCES/gcc34-var-tracking-fix.patch

4e62ec
2005-06-08  Eric Botcazou  <ebotcazou@libertysurf.fr>
4e62ec
4e62ec
	PR debug/21946
4e62ec
	* dwarf2out.c (add_loc_descr_op_piece): Move to the
4e62ec
	DWARF2_DEBUGGING_INFO section.
4e62ec
4e62ec
2005-06-07  Jakub Jelinek  <jakub@redhat.com>
4e62ec
4e62ec
	PR debug/21946
4e62ec
	* dwarf2out.c (add_loc_descr_op_piece): New function.
4e62ec
	(multiple_reg_loc_descriptor, concat_loc_descriptor,
4e62ec
	loc_descriptor): Use it.
4e62ec
4e62ec
	* var-tracking.c: Include regs.h and expr.h.
4e62ec
	(emit_note_insn_var_location): Skip over pieces where offset
4e62ec
	is smaller than previous offset plus previous piece mode size.
4e62ec
	Optimize adjacent hard registers or memory locations.
4e62ec
	* Makefile.in (var-tracking.o): Depend on $(REGS_H) and $(EXPR_H).
4e62ec
4e62ec
--- gcc/dwarf2out.c.jj	2005-06-07 00:39:11.000000000 +0200
4e62ec
+++ gcc/dwarf2out.c	2005-06-07 00:54:10.000000000 +0200
4e62ec
@@ -3747,6 +3748,7 @@ static dw_die_ref subrange_type_die (tre
4e62ec
 static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
4e62ec
 static int type_is_enum (tree);
4e62ec
 static unsigned int dbx_reg_number (rtx);
4e62ec
+static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
4e62ec
 static dw_loc_descr_ref reg_loc_descriptor (rtx);
4e62ec
 static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
4e62ec
 static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
4e62ec
@@ -8176,6 +8178,26 @@ dbx_reg_number (rtx rtl)
4e62ec
   return DBX_REGISTER_NUMBER (regno);
4e62ec
 }
4e62ec
 
4e62ec
+/* Optionally add a DW_OP_piece term to a location description expression.
4e62ec
+   DW_OP_piece is only added if the location description expression already
4e62ec
+   doesn't end with DW_OP_piece.  */
4e62ec
+
4e62ec
+static void
4e62ec
+add_loc_descr_op_piece (dw_loc_descr_ref *list_head, int size)
4e62ec
+{
4e62ec
+  dw_loc_descr_ref loc;
4e62ec
+
4e62ec
+  if (*list_head != NULL)
4e62ec
+    {
4e62ec
+      /* Find the end of the chain.  */
4e62ec
+      for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
4e62ec
+	;
4e62ec
+
4e62ec
+      if (loc->dw_loc_opc != DW_OP_piece)
4e62ec
+	loc->dw_loc_next = new_loc_descr (DW_OP_piece, size, 0);
4e62ec
+    }
4e62ec
+}
4e62ec
+
4e62ec
 /* Return a location descriptor that designates a machine register or
4e62ec
    zero if there is none.  */
4e62ec
 
4e62ec
@@ -8235,7 +8257,7 @@ multiple_reg_loc_descriptor (rtx rtl, rt
4e62ec
 
4e62ec
 	  t = one_reg_loc_descriptor (reg);
4e62ec
 	  add_loc_descr (&loc_result, t);
4e62ec
-	  add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
4e62ec
+	  add_loc_descr_op_piece (&loc_result, size);
4e62ec
 	  ++reg;
4e62ec
 	}
4e62ec
       return loc_result;
4e62ec
@@ -8256,7 +8278,7 @@ multiple_reg_loc_descriptor (rtx rtl, rt
4e62ec
       t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
4e62ec
       add_loc_descr (&loc_result, t);
4e62ec
       size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
4e62ec
-      add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
4e62ec
+      add_loc_descr_op_piece (&loc_result, size);
4e62ec
     }
4e62ec
   return loc_result;
4e62ec
 }
4e62ec
@@ -8551,14 +8573,10 @@ concat_loc_descriptor (rtx x0, rtx x1)
4e62ec
     return 0;
4e62ec
 
4e62ec
   cc_loc_result = x0_ref;
4e62ec
-  add_loc_descr (&cc_loc_result,
4e62ec
-		 new_loc_descr (DW_OP_piece,
4e62ec
-				GET_MODE_SIZE (GET_MODE (x0)), 0));
4e62ec
+  add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x0)));
4e62ec
 
4e62ec
   add_loc_descr (&cc_loc_result, x1_ref);
4e62ec
-  add_loc_descr (&cc_loc_result,
4e62ec
-		 new_loc_descr (DW_OP_piece,
4e62ec
-				GET_MODE_SIZE (GET_MODE (x1)), 0));
4e62ec
+  add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x1)));
4e62ec
 
4e62ec
   return cc_loc_result;
4e62ec
 }
4e62ec
@@ -8619,8 +8637,7 @@ loc_descriptor (rtx rtl, bool can_use_fb
4e62ec
 	  loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
4e62ec
 				       can_use_fbreg);
4e62ec
 	  mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
4e62ec
-	  add_loc_descr (&loc_result,
4e62ec
-			 new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
4e62ec
+	  add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
4e62ec
 	  for (i = 1; i < num_elem; i++)
4e62ec
 	    {
4e62ec
 	      dw_loc_descr_ref temp;
4e62ec
@@ -8629,9 +8646,7 @@ loc_descriptor (rtx rtl, bool can_use_fb
4e62ec
 				     can_use_fbreg);
4e62ec
 	      add_loc_descr (&loc_result, temp);
4e62ec
 	      mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
4e62ec
-	      add_loc_descr (&loc_result,
4e62ec
-			     new_loc_descr (DW_OP_piece,
4e62ec
-					    GET_MODE_SIZE (mode), 0));
4e62ec
+	      add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
4e62ec
 	    }
4e62ec
 	}
4e62ec
       break;
4e62ec
@@ -9930,8 +9945,7 @@ add_location_or_const_value_attribute (d
4e62ec
 	/* Create the first one, so we have something to add to.  */
4e62ec
 	descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0), true);
4e62ec
 	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
4e62ec
-	add_loc_descr (&descr,
4e62ec
-		       new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
4e62ec
+	add_loc_descr_op_piece (&descr, GET_MODE_SIZE (mode));
4e62ec
 	for (i = 1; i < num_elem; i++)
4e62ec
 	  {
4e62ec
 	    dw_loc_descr_ref temp;
4e62ec
@@ -9939,9 +9953,7 @@ add_location_or_const_value_attribute (d
4e62ec
 	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0), true);
4e62ec
 	    add_loc_descr (&descr, temp);
4e62ec
 	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
4e62ec
-	    add_loc_descr (&descr,
4e62ec
-			   new_loc_descr (DW_OP_piece,
4e62ec
-					  GET_MODE_SIZE (mode), 0));
4e62ec
+	    add_loc_descr_op_piece (&descr, GET_MODE_SIZE (mode));
4e62ec
 	  }
4e62ec
       }
4e62ec
       add_AT_location_description (die, DW_AT_location, descr);
4e62ec
--- gcc/var-tracking.c.jj	2005-06-07 00:39:11.000000000 +0200
4e62ec
+++ gcc/var-tracking.c	2005-06-07 00:52:15.000000000 +0200
4e62ec
@@ -102,6 +102,8 @@
4e62ec
 #include "alloc-pool.h"
4e62ec
 #include "fibheap.h"
4e62ec
 #include "hashtab.h"
4e62ec
+#include "regs.h"
4e62ec
+#include "expr.h"
4e62ec
 
4e62ec
 /* Type of micro operation.  */
4e62ec
 enum micro_operation_type
4e62ec
@@ -2185,10 +2187,12 @@ emit_note_insn_var_location (void **varp
4e62ec
   rtx insn = ((emit_note_data *)data)->insn;
4e62ec
   enum emit_note_where where = ((emit_note_data *)data)->where;
4e62ec
   rtx note;
4e62ec
-  int i;
4e62ec
+  int i, j, n_var_parts;
4e62ec
   bool complete;
4e62ec
   HOST_WIDE_INT last_limit;
4e62ec
   tree type_size_unit;
4e62ec
+  HOST_WIDE_INT offsets[MAX_VAR_PARTS];
4e62ec
+  rtx loc[MAX_VAR_PARTS];
4e62ec
 
4e62ec
 #ifdef ENABLE_CHECKING
4e62ec
   if (!var->decl)
4e62ec
@@ -2197,16 +2201,90 @@ emit_note_insn_var_location (void **varp
4e62ec
 
4e62ec
   complete = true;
4e62ec
   last_limit = 0;
4e62ec
+  n_var_parts = 0;
4e62ec
   for (i = 0; i < var->n_var_parts; i++)
4e62ec
     {
4e62ec
+      enum machine_mode mode, wider_mode;
4e62ec
+
4e62ec
       if (last_limit < var->var_part[i].offset)
4e62ec
 	{
4e62ec
 	  complete = false;
4e62ec
 	  break;
4e62ec
 	}
4e62ec
-      last_limit
4e62ec
-	= (var->var_part[i].offset
4e62ec
-	   + GET_MODE_SIZE (GET_MODE (var->var_part[i].loc_chain->loc)));
4e62ec
+      else if (last_limit > var->var_part[i].offset)
4e62ec
+	continue;
4e62ec
+      offsets[n_var_parts] = var->var_part[i].offset;
4e62ec
+      loc[n_var_parts] = var->var_part[i].loc_chain->loc;
4e62ec
+      mode = GET_MODE (loc[n_var_parts]);
4e62ec
+      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
4e62ec
+
4e62ec
+      /* Attempt to merge adjacent registers or memory.  */
4e62ec
+      wider_mode = GET_MODE_WIDER_MODE (mode);
4e62ec
+      for (j = i + 1; j < var->n_var_parts; j++)
4e62ec
+	if (last_limit <= var->var_part[j].offset)
4e62ec
+	  break;
4e62ec
+      if (j < var->n_var_parts
4e62ec
+	  && wider_mode != VOIDmode
4e62ec
+	  && GET_CODE (loc[n_var_parts])
4e62ec
+	     == GET_CODE (var->var_part[j].loc_chain->loc)
4e62ec
+	  && mode == GET_MODE (var->var_part[j].loc_chain->loc)
4e62ec
+	  && last_limit == var->var_part[j].offset)
4e62ec
+	{
4e62ec
+	  rtx new_loc = NULL;
4e62ec
+	  rtx loc2 = var->var_part[j].loc_chain->loc;
4e62ec
+
4e62ec
+	  if (REG_P (loc[n_var_parts])
4e62ec
+	      && HARD_REGNO_NREGS (REGNO (loc[n_var_parts]), mode) * 2
4e62ec
+		 == HARD_REGNO_NREGS (REGNO (loc[n_var_parts]), wider_mode)
4e62ec
+	      && REGNO (loc[n_var_parts])
4e62ec
+		 + HARD_REGNO_NREGS (REGNO (loc[n_var_parts]), mode)
4e62ec
+		 == REGNO (loc2))
4e62ec
+	    {
4e62ec
+	      if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
4e62ec
+		new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
4e62ec
+					   mode, 0);
4e62ec
+	      else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
4e62ec
+		new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
4e62ec
+	      if (new_loc)
4e62ec
+		{
4e62ec
+		  if (!REG_P (new_loc)
4e62ec
+		      || REGNO (new_loc) != REGNO (loc[n_var_parts]))
4e62ec
+		    new_loc = NULL;
4e62ec
+		  else
4e62ec
+		    REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
4e62ec
+		}
4e62ec
+	    }
4e62ec
+	  else if (GET_CODE (loc[n_var_parts]) == MEM
4e62ec
+		   && GET_CODE (XEXP (loc2, 0)) == PLUS
4e62ec
+		   && GET_CODE (XEXP (XEXP (loc2, 0), 0)) == REG
4e62ec
+		   && GET_CODE (XEXP (XEXP (loc2, 0), 1)) == CONST_INT)
4e62ec
+	    {
4e62ec
+	      if ((GET_CODE (XEXP (loc[n_var_parts], 0)) == REG
4e62ec
+		   && rtx_equal_p (XEXP (loc[n_var_parts], 0),
4e62ec
+				   XEXP (XEXP (loc2, 0), 0))
4e62ec
+		   && INTVAL (XEXP (XEXP (loc2, 0), 1))
4e62ec
+		      == GET_MODE_SIZE (mode))
4e62ec
+		  || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
4e62ec
+		      && GET_CODE (XEXP (XEXP (loc[n_var_parts], 0), 1))
4e62ec
+			 == CONST_INT
4e62ec
+		      && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
4e62ec
+				      XEXP (XEXP (loc2, 0), 0))
4e62ec
+		      && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
4e62ec
+			 + GET_MODE_SIZE (mode)
4e62ec
+			 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
4e62ec
+		new_loc = adjust_address_nv (loc[n_var_parts],
4e62ec
+					     wider_mode, 0);
4e62ec
+	    }
4e62ec
+
4e62ec
+	  if (new_loc)
4e62ec
+	    {
4e62ec
+	      loc[n_var_parts] = new_loc;
4e62ec
+	      mode = wider_mode;
4e62ec
+	      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
4e62ec
+	      i = j;
4e62ec
+	    }
4e62ec
+	}
4e62ec
+      ++n_var_parts;
4e62ec
     }
4e62ec
   type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (var->decl));
4e62ec
   if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
4e62ec
@@ -2222,26 +2300,24 @@ emit_note_insn_var_location (void **varp
4e62ec
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
4e62ec
 						       NULL_RTX);
4e62ec
     }
4e62ec
-  else if (var->n_var_parts == 1)
4e62ec
+  else if (n_var_parts == 1)
4e62ec
     {
4e62ec
       rtx expr_list
4e62ec
-	= gen_rtx_EXPR_LIST (VOIDmode,
4e62ec
-			     var->var_part[0].loc_chain->loc,
4e62ec
-			     GEN_INT (var->var_part[0].offset));
4e62ec
+	= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
4e62ec
 
4e62ec
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
4e62ec
 						       expr_list);
4e62ec
     }
4e62ec
-  else if (var->n_var_parts)
4e62ec
+  else if (n_var_parts)
4e62ec
     {
4e62ec
-      rtx argp[MAX_VAR_PARTS];
4e62ec
       rtx parallel;
4e62ec
 
4e62ec
-      for (i = 0; i < var->n_var_parts; i++)
4e62ec
-	argp[i] = gen_rtx_EXPR_LIST (VOIDmode, var->var_part[i].loc_chain->loc,
4e62ec
-				     GEN_INT (var->var_part[i].offset));
4e62ec
+      for (i = 0; i < n_var_parts; i++)
4e62ec
+	loc[i]
4e62ec
+	  = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
4e62ec
+
4e62ec
       parallel = gen_rtx_PARALLEL (VOIDmode,
4e62ec
-				   gen_rtvec_v (var->n_var_parts, argp));
4e62ec
+				   gen_rtvec_v (n_var_parts, loc));
4e62ec
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
4e62ec
 						       parallel);
4e62ec
     }
4e62ec
--- gcc/Makefile.in.jj	2005-06-07 00:39:11.000000000 +0200
4e62ec
+++ gcc/Makefile.in	2005-06-07 00:55:12.000000000 +0200
4e62ec
@@ -1693,7 +1693,8 @@ df.o : df.c $(CONFIG_H) $(SYSTEM_H) core
4e62ec
    $(BASIC_BLOCK_H) df.h $(FIBHEAP_H)
4e62ec
 var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
4e62ec
    $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h flags.h \
4e62ec
-   $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H)
4e62ec
+   $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
4e62ec
+   $(REGS_H) $(EXPR_H)
4e62ec
 conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H) \
4e62ec
    $(HASHTAB_H) $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
4e62ec
 profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \