public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Richard Henderson <rth@redhat.com>,
	Jason Merrill <jason@redhat.com>,
	       Cary Coutant <ccoutant@google.com>
Cc: gcc-patches@gcc.gnu.org, Roland McGrath <roland@hack.frob.com>,
	       Jan Kratochvil <jkratoch@redhat.com>,
	Tom Tromey <tromey@redhat.com>,
	       Mark Wielaard <mjw@redhat.com>
Subject: Re: Typed DWARF stack and convert to untyped
Date: Thu, 09 Jun 2011 18:34:00 -0000	[thread overview]
Message-ID: <20110609174137.GQ17079@tyan-ft48-01.lab.bos.redhat.com> (raw)
In-Reply-To: <20110609145319.GO17079@tyan-ft48-01.lab.bos.redhat.com>

On Thu, Jun 09, 2011 at 04:53:19PM +0200, Jakub Jelinek wrote:
> I'd like to propose convert to untyped operation, e.g.
> DW_OP_GNU_convert <0> could do it (and maybe DW_OP_GNU_reinterpret <0>),
> these would convert to an integral value of the same size as DWARF
> address and make it untyped.  As DW_OP_GNU_convert operand is
> uleb128 DIE offset within current CU, offset 0 certainly won't
> contain any DIEs, because it is the first byte of the CU header.

And here is a rough patch that implements it, in case you agree
with that (and also switches from defaulting to signed types to defaulting
to unsigned types, as those have defined overflow for say
addition/subtraction etc.).  Untested so far.
Testcase where the convert to untyped is used is e.g.:
void foo (unsigned long long a, unsigned long long b)
{
  unsigned long long c = a / b;
  long long d = c;
  long long e = d % 17;
}
Although long is <= DWARF2_ADDR_SIZE here, for unsigned division we have
to change the arguments to typed unsigned 64-bit, then DW_OP_div,
and then we just used to convert to typed signed 64-bit and mod
was performed with the other argument DW_OP_lit17 instead of
DW_OP_const_type <signed 64-bit> <17>.  With the patch
the result of DW_OP_div is converted to untyped and the rest is performed
in untyped.

2011-06-09  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (size_of_loc_descr, output_loc_operands,
	mark_base_types, hash_loc_operands, compare_loc_operands): Allow
	DW_OP_GNU_convert and DW_OP_GNU_reinterpret to use constant instead
	of base type reference as argument.
	(resolve_addr_in_expr): Likewise.  Fix keep computation.
	(convert_descriptor_to_signed): Renamed to...
	(convert_descriptor_to_mode): ... this.  For wider types convert
	to unsigned instead of signed, for <= DWARF2_ADDR_SIZE convert to
	untyped.
	(typed_binop): New function.
	(scompare_loc_descriptor, ucompare_loc_descriptor,
	minmax_loc_descriptor, mem_loc_descriptor): For wider integer modes
	default to unsigned type instead of signed.

--- gcc/dwarf2out.c.jj	2011-06-09 16:56:50.000000000 +0200
+++ gcc/dwarf2out.c	2011-06-09 19:15:26.000000000 +0200
@@ -5076,11 +5076,15 @@ size_of_loc_descr (dw_loc_descr_ref loc)
       break;
     case DW_OP_GNU_convert:
     case DW_OP_GNU_reinterpret:
-      {
-	unsigned long o
-	  = get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die);
-	size += size_of_uleb128 (o);
-      }
+      if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
+	size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
+      else
+	{
+	  unsigned long o
+	    = get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die);
+	  size += size_of_uleb128 (o);
+	}
+      break;
     default:
       break;
     }
@@ -5456,11 +5460,14 @@ output_loc_operands (dw_loc_descr_ref lo
       break;
     case DW_OP_GNU_convert:
     case DW_OP_GNU_reinterpret:
-      {
-	unsigned long o = get_base_type_offset (val1->v.val_die_ref.die);
-	gcc_assert (o);
-	dw2_asm_output_data_uleb128 (o, NULL);
-      }
+      if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
+	dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
+      else
+	{
+	  unsigned long o = get_base_type_offset (val1->v.val_die_ref.die);
+	  gcc_assert (o);
+	  dw2_asm_output_data_uleb128 (o, NULL);
+	}
       break;
 
     default:
@@ -13824,27 +13831,24 @@ base_type_for_mode (enum machine_mode mo
   return type_die;
 }
 
-/* For OP descriptor assumed to be in unsigned MODE, convert it to a signed
-   type matching MODE, or, if MODE is narrower than DWARF2_ADDR_SIZE, signed
-   type matching DWARF2_ADDR_SIZE.  Return NULL if the conversion is not
+/* For OP descriptor assumed to be in unsigned MODE, convert it to a unsigned
+   type matching MODE, or, if MODE is narrower than or as wide as
+   DWARF2_ADDR_SIZE, untyped.  Return NULL if the conversion is not
    possible.  */
 
 static dw_loc_descr_ref
-convert_descriptor_to_signed (enum machine_mode mode, dw_loc_descr_ref op)
+convert_descriptor_to_mode (enum machine_mode mode, dw_loc_descr_ref op)
 {
   enum machine_mode outer_mode = mode;
   dw_die_ref type_die;
   dw_loc_descr_ref cvt;
 
-  if (GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE)
+  if (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE)
     {
-      outer_mode = mode_for_size (DWARF2_ADDR_SIZE * BITS_PER_UNIT,
-				  MODE_INT, 0);
-      if (outer_mode == BLKmode
-	  || GET_MODE_SIZE (outer_mode) != DWARF2_ADDR_SIZE)
-	return NULL;
+      add_loc_descr (&op, new_loc_descr (DW_OP_GNU_convert, 0, 0));
+      return op;
     }
-  type_die = base_type_for_mode (outer_mode, 0);
+  type_die = base_type_for_mode (outer_mode, 1);
   if (type_die == NULL)
     return NULL;
   cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
@@ -13901,9 +13905,29 @@ scompare_loc_descriptor (enum dwarf_loca
     return NULL;
 
   if (GET_MODE_CLASS (op_mode) != MODE_INT
-      || GET_MODE_SIZE (op_mode) >= DWARF2_ADDR_SIZE)
+      || GET_MODE_SIZE (op_mode) == DWARF2_ADDR_SIZE)
     return compare_loc_descriptor (op, op0, op1);
 
+  if (GET_MODE_SIZE (op_mode) > DWARF2_ADDR_SIZE)
+    {
+      dw_die_ref type_die = base_type_for_mode (op_mode, 0);
+      dw_loc_descr_ref cvt;
+
+      if (type_die == NULL)
+	return NULL;
+      cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
+      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+      add_loc_descr (&op0, cvt);
+      cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
+      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+      add_loc_descr (&op1, cvt);
+      return compare_loc_descriptor (op, op0, op1);
+    }
+
   shift = (DWARF2_ADDR_SIZE - GET_MODE_SIZE (op_mode)) * BITS_PER_UNIT;
   /* For eq/ne, if the operands are known to be zero-extended,
      there is no need to do the fancy shifting up.  */
@@ -13959,9 +13983,6 @@ ucompare_loc_descriptor (enum dwarf_loca
   if (dwarf_strict && GET_MODE_SIZE (op_mode) > DWARF2_ADDR_SIZE)
     return NULL;
 
-  if (op_mode != VOIDmode && GET_MODE_CLASS (op_mode) != MODE_INT)
-    return NULL;
-
   op0 = mem_loc_descriptor (XEXP (rtl, 0), op_mode, mem_mode,
 			    VAR_INIT_STATUS_INITIALIZED);
   op1 = mem_loc_descriptor (XEXP (rtl, 1), op_mode, mem_mode,
@@ -14009,24 +14030,6 @@ ucompare_loc_descriptor (enum dwarf_loca
 	add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst,
 					    bias, 0));
     }
-  else
-    {
-      dw_die_ref type_die = base_type_for_mode (op_mode, 1);
-      dw_loc_descr_ref cvt;
-
-      if (type_die == NULL)
-	return NULL;
-      cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
-      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
-      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
-      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
-      add_loc_descr (&op0, cvt);
-      cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
-      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
-      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
-      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
-      add_loc_descr (&op1, cvt);
-    }
   return compare_loc_descriptor (op, op0, op1);
 }
 
@@ -14073,23 +14076,6 @@ minmax_loc_descriptor (rtx rtl, enum mac
 	  add_loc_descr (&op0, new_loc_descr (DW_OP_plus_uconst, bias, 0));
 	  add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst, bias, 0));
 	}
-      else
-	{
-	  dw_die_ref type_die = base_type_for_mode (mode, 1);
-	  dw_loc_descr_ref cvt;
-	  if (type_die == NULL)
-	    return NULL;
-	  cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
-	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
-	  add_loc_descr (&op0, cvt);
-	  cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
-	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
-	  add_loc_descr (&op1, cvt);
-	}
     }
   else if (GET_MODE_CLASS (mode) == MODE_INT
 	   && GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE)
@@ -14100,6 +14086,24 @@ minmax_loc_descriptor (rtx rtl, enum mac
       add_loc_descr (&op1, int_loc_descriptor (shift));
       add_loc_descr (&op1, new_loc_descr (DW_OP_shl, 0, 0));
     }
+  else if (GET_MODE_CLASS (mode) == MODE_INT
+	   && GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE)
+    {
+      dw_die_ref type_die = base_type_for_mode (mode, 0);
+      dw_loc_descr_ref cvt;
+      if (type_die == NULL)
+	return NULL;
+      cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
+      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+      add_loc_descr (&op0, cvt);
+      cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
+      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+      add_loc_descr (&op1, cvt);
+    }
 
   if (GET_CODE (rtl) == SMIN || GET_CODE (rtl) == UMIN)
     op = DW_OP_lt;
@@ -14115,9 +14119,46 @@ minmax_loc_descriptor (rtx rtl, enum mac
   add_loc_descr (&ret, drop_node);
   bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
   bra_node->dw_loc_oprnd1.v.val_loc = drop_node;
+  if ((GET_CODE (rtl) == SMIN || GET_CODE (rtl) == SMAX)
+      && GET_MODE_CLASS (mode) == MODE_INT
+      && GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE)
+    ret = convert_descriptor_to_mode (mode, ret);
   return ret;
 }
 
+/* Helper function for mem_loc_descriptor.  Perform OP binary op,
+   but after converting arguments to type_die, afterwards
+   convert back to unsigned.  */
+
+static dw_loc_descr_ref
+typed_binop (enum dwarf_location_atom op, rtx rtl, dw_die_ref type_die,
+	     enum machine_mode mode, enum machine_mode mem_mode)
+{
+  dw_loc_descr_ref cvt, op0, op1;
+
+  if (type_die == NULL)
+    return NULL;
+  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
+			    VAR_INIT_STATUS_INITIALIZED);
+  op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
+			    VAR_INIT_STATUS_INITIALIZED);
+  if (op0 == NULL || op1 == NULL)
+    return NULL;
+  cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
+  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+  add_loc_descr (&op0, cvt);
+  cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
+  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+  add_loc_descr (&op1, cvt);
+  add_loc_descr (&op0, op1);
+  add_loc_descr (&op0, new_loc_descr (op, 0, 0));
+  return convert_descriptor_to_mode (mode, op0);
+}
+
 /* CLZ (where constV is CLZ_DEFINED_VALUE_AT_ZERO computed value,
    const0 is DW_OP_lit0 or corresponding typed constant,
    const1 is DW_OP_lit1 or corresponding typed constant
@@ -14562,7 +14603,8 @@ mem_loc_descriptor (rtx rtl, enum machin
 					       mem_mode, initialized);
 	  if (mem_loc_result == NULL)
 	    break;
-	  type_die = base_type_for_mode (mode, 0);
+	  type_die = base_type_for_mode (mode,
+					 GET_MODE_CLASS (mode) == MODE_INT);
 	  if (type_die == NULL)
 	    {
 	      mem_loc_result = NULL;
@@ -14594,7 +14636,8 @@ mem_loc_descriptor (rtx rtl, enum machin
 	    break;
 	  if (REGNO (rtl) > FIRST_PSEUDO_REGISTER)
 	    break;
-	  type_die = base_type_for_mode (mode, 0);
+	  type_die = base_type_for_mode (mode,
+					 GET_MODE_CLASS (mode) == MODE_INT);
 	  if (type_die == NULL)
 	    break;
 	  mem_loc_result = new_loc_descr (DW_OP_GNU_regval_type,
@@ -14677,7 +14720,7 @@ mem_loc_descriptor (rtx rtl, enum machin
 					  GET_CODE (rtl) == ZERO_EXTEND);
 	  if (type_die1 == NULL)
 	    break;
-	  type_die2 = base_type_for_mode (mode, 0);
+	  type_die2 = base_type_for_mode (mode, 1);
 	  if (type_die2 == NULL)
 	    break;
 	  mem_loc_result = op0;
@@ -14710,7 +14753,8 @@ mem_loc_descriptor (rtx rtl, enum machin
 
 	      if (dwarf_strict)
 		return NULL;
-	      type_die = base_type_for_mode (mode, 0);
+	      type_die
+		= base_type_for_mode (mode, GET_MODE_CLASS (mode) == MODE_INT);
 	      if (type_die == NULL)
 		return NULL;
 	      deref = new_loc_descr (DW_OP_GNU_deref_type,
@@ -14861,12 +14905,11 @@ mem_loc_descriptor (rtx rtl, enum machin
 	    loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1)));
 	  else
 	    {
-	      dw_loc_descr_ref mem_loc_result2
-		= mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
-				      VAR_INIT_STATUS_INITIALIZED);
-	      if (mem_loc_result2 == 0)
+	      op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
+					VAR_INIT_STATUS_INITIALIZED);
+	      if (op1 == 0)
 		break;
-	      add_loc_descr (&mem_loc_result, mem_loc_result2);
+	      add_loc_descr (&mem_loc_result, op1);
 	      add_loc_descr (&mem_loc_result,
 			     new_loc_descr (DW_OP_plus, 0, 0));
 	    }
@@ -14884,6 +14927,15 @@ mem_loc_descriptor (rtx rtl, enum machin
       goto do_binop;
 
     case DIV:
+      if (!dwarf_strict
+	  && GET_MODE_CLASS (mode) == MODE_INT
+	  && GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE)
+	{
+	  mem_loc_result = typed_binop (DW_OP_div, rtl,
+					base_type_for_mode (mode, 0),
+					mode, mem_mode);
+	  break;
+	}
       op = DW_OP_div;
       goto do_binop;
 
@@ -14955,12 +15007,10 @@ mem_loc_descriptor (rtx rtl, enum machin
     case MOD:
       if (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE && !dwarf_strict)
 	{
-	  /* If MODE is wider than DWARF2_ADDR_SIZE, mem_loc_descriptor
-	     should return signed typed values and therefore DW_OP_mod
-	     won't be unsigned as it defaults for untyped stack values,
-	     but signed.  */
-	  op = DW_OP_mod;
-	  goto do_binop;
+	  mem_loc_result = typed_binop (DW_OP_mod, rtl,
+					base_type_for_mode (mode, 0),
+					mode, mem_mode);
+	  break;
 	}
 
       op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
@@ -14983,32 +15033,14 @@ mem_loc_descriptor (rtx rtl, enum machin
     case UDIV:
       if (!dwarf_strict && GET_MODE_CLASS (mode) == MODE_INT)
 	{
-	  dw_die_ref type_die;
-	  dw_loc_descr_ref cvt;
-
-	  type_die = base_type_for_mode (mode, 1);
-	  if (type_die == NULL)
-	    break;
-	  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
-				    VAR_INIT_STATUS_INITIALIZED);
-	  op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
-				    VAR_INIT_STATUS_INITIALIZED);
-	  if (op0 == 0 || op1 == 0)
-	    break;
-	  cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
-	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
-	  add_loc_descr (&op0, cvt);
-	  cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0);
-	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
-	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
-	  add_loc_descr (&op1, cvt);
-	  mem_loc_result = op0;
-	  add_loc_descr (&mem_loc_result, op1);
-	  add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_div, 0, 0));
-	  mem_loc_result = convert_descriptor_to_signed (mode, mem_loc_result);
+	  if (GET_MODE_CLASS (mode) > DWARF2_ADDR_SIZE)
+	    {
+	      op = DW_OP_div;
+	      goto do_binop;
+	    }
+	  mem_loc_result = typed_binop (DW_OP_div, rtl,
+					base_type_for_mode (mode, 1),
+					mode, mem_mode);
 	}
       break;
 
@@ -15051,7 +15083,7 @@ mem_loc_descriptor (rtx rtl, enum machin
 	  && (GET_MODE_BITSIZE (mode) == HOST_BITS_PER_WIDE_INT
 	      || GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT))
 	{
-	  dw_die_ref type_die = base_type_for_mode (mode, 0);
+	  dw_die_ref type_die = base_type_for_mode (mode, 1);
 	  if (type_die == NULL)
 	    return NULL;
 	  mem_loc_result = new_loc_descr (DW_OP_GNU_const_type, 0,
@@ -15084,7 +15116,8 @@ mem_loc_descriptor (rtx rtl, enum machin
 	      || (GET_MODE (rtl) == VOIDmode
 		  && GET_MODE_BITSIZE (mode) != 2 * HOST_BITS_PER_WIDE_INT))
 	    break;
-	  type_die = base_type_for_mode (mode, 0);
+	  type_die = base_type_for_mode (mode,
+					 GET_MODE_CLASS (mode) == MODE_INT);
 	  if (type_die == NULL)
 	    return NULL;
 	  mem_loc_result = new_loc_descr (DW_OP_GNU_const_type, 0, 0);
@@ -15248,7 +15281,7 @@ mem_loc_descriptor (rtx rtl, enum machin
 	  if (op0 == NULL)
 	    break;
 	  if (GET_MODE_CLASS (GET_MODE (XEXP (rtl, 0))) == MODE_INT
-	      && (GET_CODE (rtl) == UNSIGNED_FLOAT
+	      && (GET_CODE (rtl) == FLOAT
 		  || GET_MODE_SIZE (GET_MODE (XEXP (rtl, 0)))
 		     <= DWARF2_ADDR_SIZE))
 	    {
@@ -15271,10 +15304,10 @@ mem_loc_descriptor (rtx rtl, enum machin
 	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
 	  add_loc_descr (&op0, cvt);
 	  if (GET_MODE_CLASS (mode) == MODE_INT
-	      && (GET_CODE (rtl) == UNSIGNED_FIX
+	      && (GET_CODE (rtl) == FIX
 		  || GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE))
 	    {
-	      op0 = convert_descriptor_to_signed (mode, op0);
+	      op0 = convert_descriptor_to_mode (mode, op0);
 	      if (op0 == NULL)
 		break;
 	    }
@@ -23999,9 +24032,12 @@ mark_base_types (dw_loc_descr_ref loc)
 	case DW_OP_GNU_deref_type:
 	  base_type = loc->dw_loc_oprnd2.v.val_die_ref.die;
 	  break;
-	case DW_OP_GNU_const_type:
 	case DW_OP_GNU_convert:
 	case DW_OP_GNU_reinterpret:
+	  if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
+	    continue;
+	  /* FALLTHRU */
+	case DW_OP_GNU_const_type:
 	  base_type = loc->dw_loc_oprnd1.v.val_die_ref.die;
 	  break;
 	case DW_OP_GNU_entry_value:
@@ -24189,8 +24225,14 @@ resolve_addr_in_expr (dw_loc_descr_ref l
 	    if (loc->dw_loc_opc == DW_OP_GNU_regval_type
 		|| loc->dw_loc_opc == DW_OP_GNU_deref_type)
 	      base1 = loc->dw_loc_oprnd2.v.val_die_ref.die;
+	    else if (loc->dw_loc_oprnd1.val_class
+		     == dw_val_class_unsigned_const)
+	      break;
 	    else
 	      base1 = loc->dw_loc_oprnd1.v.val_die_ref.die;
+	    if (loc->dw_loc_next->dw_loc_oprnd1.val_class
+		== dw_val_class_unsigned_const)
+	      break;
 	    base2 = loc->dw_loc_next->dw_loc_oprnd1.v.val_die_ref.die;
 	    gcc_assert (base1->die_tag == DW_TAG_base_type
 			&& base2->die_tag == DW_TAG_base_type);
@@ -24217,7 +24259,7 @@ resolve_addr_in_expr (dw_loc_descr_ref l
 	    /* Don't change integer DW_OP_GNU_convert after e.g. floating
 	       point typed stack entry.  */
 	    else if (enc1 != DW_ATE_unsigned && enc1 != DW_ATE_signed)
-	      keep = loc;
+	      keep = loc->dw_loc_next;
 	    break;
 	  }
 	break;
@@ -24483,6 +24525,12 @@ hash_loc_operands (dw_loc_descr_ref loc,
       break;
     case DW_OP_GNU_convert:
     case DW_OP_GNU_reinterpret:
+      if (val1->val_class == dw_val_class_unsigned_const)
+	{
+	  hash = iterative_hash_object (val1->v.val_unsigned, hash);
+	  break;
+	}
+      /* FALLTHRU */
     case DW_OP_GNU_const_type:
       {
 	unsigned int byte_size
@@ -24704,6 +24752,10 @@ compare_loc_operands (dw_loc_descr_ref x
 	     && valx2->v.val_die_ref.die == valy2->v.val_die_ref.die;
     case DW_OP_GNU_convert:
     case DW_OP_GNU_reinterpret:
+      if (valx1->val_class != valy1->val_class)
+	return false;
+      if (valx1->val_class == dw_val_class_unsigned_const)
+	return valx1->v.val_unsigned == valy1->v.val_unsigned;
       return valx1->v.val_die_ref.die == valy1->v.val_die_ref.die;
     default:
       /* Other codes have no operands.  */


	Jakub

  reply	other threads:[~2011-06-09 17:42 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-25 11:33 [RFC PATCH] Typed DWARF stack Jakub Jelinek
2011-03-25 16:48 ` Roland McGrath
2011-03-28  9:25   ` Jakub Jelinek
2011-03-25 17:51 ` Cary Coutant
2011-04-16  9:28 ` [PATCH] " Jakub Jelinek
2011-04-29 21:01   ` Jason Merrill
2011-05-03 13:34   ` H.J. Lu
2011-05-08 18:57     ` H.J. Lu
2011-05-04 18:22 ` [RFC PATCH] " Tom Tromey
2011-05-04 18:30   ` Cary Coutant
2011-05-04 18:37   ` Jakub Jelinek
2011-05-04 20:27     ` Tom Tromey
2011-05-12 21:16       ` Tom Tromey
2011-05-12 21:37         ` Tom Tromey
2011-06-09 15:47 ` Typed DWARF stack and convert to untyped Jakub Jelinek
2011-06-09 18:34   ` Jakub Jelinek [this message]
2011-06-13 15:34   ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110609174137.GQ17079@tyan-ft48-01.lab.bos.redhat.com \
    --to=jakub@redhat.com \
    --cc=ccoutant@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=jkratoch@redhat.com \
    --cc=mjw@redhat.com \
    --cc=roland@hack.frob.com \
    --cc=rth@redhat.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).