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

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