aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-07-09 17:48:42 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-07-09 17:48:42 +0200
commit5b696ba2dc1b84bf91782c4c89c19eef224d58cf (patch)
tree6525562c36d52a3cb7739fa718e5ec79da115e96
parent8662b2ba92816ad1e1a461ef9fe3b2c3e9d21905 (diff)
downloadgcc-5b696ba2dc1b84bf91782c4c89c19eef224d58cf.zip
gcc-5b696ba2dc1b84bf91782c4c89c19eef224d58cf.tar.gz
gcc-5b696ba2dc1b84bf91782c4c89c19eef224d58cf.tar.bz2
re PR debug/49676 (inefficiency: DW_AT_GNU_call_site_value calculates everything << 32)
PR debug/49676 * dwarf2out.c (size_of_int_loc_descriptor): New function. (address_of_int_loc_descriptor): Use it. (scompare_loc_descriptor): Optimize EQ/NE comparison with constant. From-SVN: r176083
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/dwarf2out.c69
2 files changed, 58 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cbc027f..addfcd7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2011-07-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/49676
+ * dwarf2out.c (size_of_int_loc_descriptor): New function.
+ (address_of_int_loc_descriptor): Use it.
+ (scompare_loc_descriptor): Optimize EQ/NE comparison with
+ constant.
+
2011-07-09 Richard Henderson <rth@redhat.com>
* config/pdp11/pdp11.md (define_c_enum "unspecv"): New.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 44035d3..bad0b2d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10848,44 +10848,53 @@ int_loc_descriptor (HOST_WIDE_INT i)
return new_loc_descr (op, i, 0);
}
-/* Return loc description representing "address" of integer value.
- This can appear only as toplevel expression. */
+/* Return size_of_locs (int_loc_descriptor (i)) without
+ actually allocating it. */
-static dw_loc_descr_ref
-address_of_int_loc_descriptor (int size, HOST_WIDE_INT i)
+static unsigned long
+size_of_int_loc_descriptor (HOST_WIDE_INT i)
{
- int litsize;
- dw_loc_descr_ref loc_result = NULL;
-
- if (!(dwarf_version >= 4 || !dwarf_strict))
- return NULL;
-
if (i >= 0)
{
if (i <= 31)
- litsize = 1;
+ return 1;
else if (i <= 0xff)
- litsize = 2;
+ return 2;
else if (i <= 0xffff)
- litsize = 3;
+ return 3;
else if (HOST_BITS_PER_WIDE_INT == 32
|| i <= 0xffffffff)
- litsize = 5;
+ return 5;
else
- litsize = 1 + size_of_uleb128 ((unsigned HOST_WIDE_INT) i);
+ return 1 + size_of_uleb128 ((unsigned HOST_WIDE_INT) i);
}
else
{
if (i >= -0x80)
- litsize = 2;
+ return 2;
else if (i >= -0x8000)
- litsize = 3;
+ return 3;
else if (HOST_BITS_PER_WIDE_INT == 32
|| i >= -0x80000000)
- litsize = 5;
+ return 5;
else
- litsize = 1 + size_of_sleb128 (i);
+ return 1 + size_of_sleb128 (i);
}
+}
+
+/* Return loc description representing "address" of integer value.
+ This can appear only as toplevel expression. */
+
+static dw_loc_descr_ref
+address_of_int_loc_descriptor (int size, HOST_WIDE_INT i)
+{
+ int litsize;
+ dw_loc_descr_ref loc_result = NULL;
+
+ if (!(dwarf_version >= 4 || !dwarf_strict))
+ return NULL;
+
+ litsize = size_of_int_loc_descriptor (i);
/* Determine if DW_OP_stack_value or DW_OP_implicit_value
is more compact. For DW_OP_stack_value we need:
litsize + 1 (DW_OP_stack_value)
@@ -11284,6 +11293,28 @@ scompare_loc_descriptor (enum dwarf_location_atom op, rtx rtl,
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (rtl, 1))
== (INTVAL (XEXP (rtl, 1)) & GET_MODE_MASK (op_mode)))))
return compare_loc_descriptor (op, op0, op1);
+
+ /* EQ/NE comparison against constant in narrower type than
+ DWARF2_ADDR_SIZE can be performed either as
+ DW_OP_const1u <shift> DW_OP_shl DW_OP_const* <cst << shift>
+ DW_OP_{eq,ne}
+ or
+ DW_OP_const*u <mode_mask> DW_OP_and DW_OP_const* <cst & mode_mask>
+ DW_OP_{eq,ne}. Pick whatever is shorter. */
+ if (CONST_INT_P (XEXP (rtl, 1))
+ && GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
+ && (size_of_int_loc_descriptor (shift) + 1
+ + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1)) << shift)
+ >= size_of_int_loc_descriptor (GET_MODE_MASK (op_mode)) + 1
+ + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1))
+ & GET_MODE_MASK (op_mode))))
+ {
+ add_loc_descr (&op0, int_loc_descriptor (GET_MODE_MASK (op_mode)));
+ add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
+ op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1))
+ & GET_MODE_MASK (op_mode));
+ return compare_loc_descriptor (op, op0, op1);
+ }
}
add_loc_descr (&op0, int_loc_descriptor (shift));
add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));