re PR debug/49676 (inefficiency: DW_AT_GNU_call_site_value calculates everything << 32)
PR debug/49676 * dwarf2out.c (int_shift_loc_descriptor): New function. (int_loc_descriptor): If shorter, emit i as (i >> shift), shift, DW_OP_shl for suitable shift value. Similarly, try to optimize large negative values using DW_OP_neg of a positive value if shorter. (size_of_int_shift_loc_descriptor): New function. (size_of_int_loc_descriptor): Adjust to match int_loc_descriptor changes. (mem_loc_descriptor) <case CONST_INT>: Emit zero-extended constants that fit into DWARF2_ADDR_SIZE bytes as int_loc_descriptor + DW_OP_GNU_convert instead of DW_OP_GNU_const_type if the former is shorter. (resolve_addr_in_expr): Optimize DW_OP_plus_uconst with a large addend as added DW_OP_plus if it is shorter. * gcc.dg/guality/csttest.c: New test. From-SVN: r176167
This commit is contained in:
parent
932ebb945f
commit
96ae7458c0
|
@ -1,3 +1,21 @@
|
|||
2011-07-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/49676
|
||||
* dwarf2out.c (int_shift_loc_descriptor): New function.
|
||||
(int_loc_descriptor): If shorter, emit i as
|
||||
(i >> shift), shift, DW_OP_shl for suitable shift value.
|
||||
Similarly, try to optimize large negative values using
|
||||
DW_OP_neg of a positive value if shorter.
|
||||
(size_of_int_shift_loc_descriptor): New function.
|
||||
(size_of_int_loc_descriptor): Adjust to match int_loc_descriptor
|
||||
changes.
|
||||
(mem_loc_descriptor) <case CONST_INT>: Emit zero-extended constants
|
||||
that fit into DWARF2_ADDR_SIZE bytes as int_loc_descriptor +
|
||||
DW_OP_GNU_convert instead of DW_OP_GNU_const_type if the former
|
||||
is shorter.
|
||||
(resolve_addr_in_expr): Optimize DW_OP_plus_uconst with a large
|
||||
addend as added DW_OP_plus if it is shorter.
|
||||
|
||||
2011-07-11 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* config/i386/sol2.h [!USE_GLD] (CTORS_SECTION_ASM_OP): Define.
|
||||
|
|
172
gcc/dwarf2out.c
172
gcc/dwarf2out.c
|
@ -10135,6 +10135,21 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
|
|||
return loc_result;
|
||||
}
|
||||
|
||||
static unsigned long size_of_int_loc_descriptor (HOST_WIDE_INT);
|
||||
|
||||
/* Return a location descriptor that designates a constant i,
|
||||
as a compound operation from constant (i >> shift), constant shift
|
||||
and DW_OP_shl. */
|
||||
|
||||
static dw_loc_descr_ref
|
||||
int_shift_loc_descriptor (HOST_WIDE_INT i, int shift)
|
||||
{
|
||||
dw_loc_descr_ref ret = int_loc_descriptor (i >> shift);
|
||||
add_loc_descr (&ret, int_loc_descriptor (shift));
|
||||
add_loc_descr (&ret, new_loc_descr (DW_OP_shl, 0, 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return a location descriptor that designates a constant. */
|
||||
|
||||
static dw_loc_descr_ref
|
||||
|
@ -10146,15 +10161,45 @@ int_loc_descriptor (HOST_WIDE_INT i)
|
|||
defaulting to the LEB encoding. */
|
||||
if (i >= 0)
|
||||
{
|
||||
int clz = clz_hwi (i);
|
||||
int ctz = ctz_hwi (i);
|
||||
if (i <= 31)
|
||||
op = (enum dwarf_location_atom) (DW_OP_lit0 + i);
|
||||
else if (i <= 0xff)
|
||||
op = DW_OP_const1u;
|
||||
else if (i <= 0xffff)
|
||||
op = DW_OP_const2u;
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32
|
||||
|| i <= 0xffffffff)
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 5
|
||||
&& clz + 5 + 255 >= HOST_BITS_PER_WIDE_INT)
|
||||
/* DW_OP_litX DW_OP_litY DW_OP_shl takes just 3 bytes and
|
||||
DW_OP_litX DW_OP_const1u Y DW_OP_shl takes just 4 bytes,
|
||||
while DW_OP_const4u is 5 bytes. */
|
||||
return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 5);
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
|
||||
&& clz + 8 + 31 >= HOST_BITS_PER_WIDE_INT)
|
||||
/* DW_OP_const1u X DW_OP_litY DW_OP_shl takes just 4 bytes,
|
||||
while DW_OP_const4u is 5 bytes. */
|
||||
return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 8);
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff)
|
||||
op = DW_OP_const4u;
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
|
||||
&& clz + 8 + 255 >= HOST_BITS_PER_WIDE_INT)
|
||||
/* DW_OP_const1u X DW_OP_const1u Y DW_OP_shl takes just 5 bytes,
|
||||
while DW_OP_constu of constant >= 0x100000000 takes at least
|
||||
6 bytes. */
|
||||
return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 8);
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 16
|
||||
&& clz + 16 + (size_of_uleb128 (i) > 5 ? 255 : 31)
|
||||
>= HOST_BITS_PER_WIDE_INT)
|
||||
/* DW_OP_const2u X DW_OP_litY DW_OP_shl takes just 5 bytes,
|
||||
DW_OP_const2u X DW_OP_const1u Y DW_OP_shl takes 6 bytes,
|
||||
while DW_OP_constu takes in this case at least 6 bytes. */
|
||||
return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 16);
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 32
|
||||
&& clz + 32 + 31 >= HOST_BITS_PER_WIDE_INT
|
||||
&& size_of_uleb128 (i) > 6)
|
||||
/* DW_OP_const4u X DW_OP_litY DW_OP_shl takes just 7 bytes. */
|
||||
return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 32);
|
||||
else
|
||||
op = DW_OP_constu;
|
||||
}
|
||||
|
@ -10164,35 +10209,88 @@ int_loc_descriptor (HOST_WIDE_INT i)
|
|||
op = DW_OP_const1s;
|
||||
else if (i >= -0x8000)
|
||||
op = DW_OP_const2s;
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32
|
||||
|| i >= -0x80000000)
|
||||
op = DW_OP_const4s;
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32 || i >= -0x80000000)
|
||||
{
|
||||
if (size_of_int_loc_descriptor (i) < 5)
|
||||
{
|
||||
dw_loc_descr_ref ret = int_loc_descriptor (-i);
|
||||
add_loc_descr (&ret, new_loc_descr (DW_OP_neg, 0, 0));
|
||||
return ret;
|
||||
}
|
||||
op = DW_OP_const4s;
|
||||
}
|
||||
else
|
||||
op = DW_OP_consts;
|
||||
{
|
||||
if (size_of_int_loc_descriptor (i)
|
||||
< (unsigned long) 1 + size_of_sleb128 (i))
|
||||
{
|
||||
dw_loc_descr_ref ret = int_loc_descriptor (-i);
|
||||
add_loc_descr (&ret, new_loc_descr (DW_OP_neg, 0, 0));
|
||||
return ret;
|
||||
}
|
||||
op = DW_OP_consts;
|
||||
}
|
||||
}
|
||||
|
||||
return new_loc_descr (op, i, 0);
|
||||
}
|
||||
|
||||
/* Return size_of_locs (int_shift_loc_descriptor (i, shift))
|
||||
without actually allocating it. */
|
||||
|
||||
static unsigned long
|
||||
size_of_int_shift_loc_descriptor (HOST_WIDE_INT i, int shift)
|
||||
{
|
||||
return size_of_int_loc_descriptor (i >> shift)
|
||||
+ size_of_int_loc_descriptor (shift)
|
||||
+ 1;
|
||||
}
|
||||
|
||||
/* Return size_of_locs (int_loc_descriptor (i)) without
|
||||
actually allocating it. */
|
||||
|
||||
static unsigned long
|
||||
size_of_int_loc_descriptor (HOST_WIDE_INT i)
|
||||
{
|
||||
unsigned long s;
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
int clz, ctz;
|
||||
if (i <= 31)
|
||||
return 1;
|
||||
else if (i <= 0xff)
|
||||
return 2;
|
||||
else if (i <= 0xffff)
|
||||
return 3;
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32
|
||||
|| i <= 0xffffffff)
|
||||
clz = clz_hwi (i);
|
||||
ctz = ctz_hwi (i);
|
||||
if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 5
|
||||
&& clz + 5 + 255 >= HOST_BITS_PER_WIDE_INT)
|
||||
return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
|
||||
- clz - 5);
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
|
||||
&& clz + 8 + 31 >= HOST_BITS_PER_WIDE_INT)
|
||||
return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
|
||||
- clz - 8);
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff)
|
||||
return 5;
|
||||
s = size_of_uleb128 ((unsigned HOST_WIDE_INT) i);
|
||||
if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
|
||||
&& clz + 8 + 255 >= HOST_BITS_PER_WIDE_INT)
|
||||
return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
|
||||
- clz - 8);
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 16
|
||||
&& clz + 16 + (s > 5 ? 255 : 31) >= HOST_BITS_PER_WIDE_INT)
|
||||
return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
|
||||
- clz - 16);
|
||||
else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 32
|
||||
&& clz + 32 + 31 >= HOST_BITS_PER_WIDE_INT
|
||||
&& s > 6)
|
||||
return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
|
||||
- clz - 32);
|
||||
else
|
||||
return 1 + size_of_uleb128 ((unsigned HOST_WIDE_INT) i);
|
||||
return 1 + s;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10200,11 +10298,27 @@ size_of_int_loc_descriptor (HOST_WIDE_INT i)
|
|||
return 2;
|
||||
else if (i >= -0x8000)
|
||||
return 3;
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32
|
||||
|| i >= -0x80000000)
|
||||
return 5;
|
||||
else if (HOST_BITS_PER_WIDE_INT == 32 || i >= -0x80000000)
|
||||
{
|
||||
if (-(unsigned HOST_WIDE_INT) i != (unsigned HOST_WIDE_INT) i)
|
||||
{
|
||||
s = size_of_int_loc_descriptor (-i) + 1;
|
||||
if (s < 5)
|
||||
return s;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
else
|
||||
return 1 + size_of_sleb128 (i);
|
||||
{
|
||||
unsigned long r = 1 + size_of_sleb128 (i);
|
||||
if (-(unsigned HOST_WIDE_INT) i != (unsigned HOST_WIDE_INT) i)
|
||||
{
|
||||
s = size_of_int_loc_descriptor (-i) + 1;
|
||||
if (s < r)
|
||||
return s;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11818,8 +11932,27 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
|||
|| GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT))
|
||||
{
|
||||
dw_die_ref type_die = base_type_for_mode (mode, 1);
|
||||
enum machine_mode amode;
|
||||
if (type_die == NULL)
|
||||
return NULL;
|
||||
amode = mode_for_size (DWARF2_ADDR_SIZE * BITS_PER_UNIT,
|
||||
MODE_INT, 0);
|
||||
if (INTVAL (rtl) >= 0
|
||||
&& amode != BLKmode
|
||||
&& trunc_int_for_mode (INTVAL (rtl), amode) == INTVAL (rtl)
|
||||
/* const DW_OP_GNU_convert <XXX> vs.
|
||||
DW_OP_GNU_const_type <XXX, 1, const>. */
|
||||
&& size_of_int_loc_descriptor (INTVAL (rtl)) + 1 + 1
|
||||
< (unsigned long) 1 + 1 + 1 + GET_MODE_SIZE (mode))
|
||||
{
|
||||
mem_loc_result = int_loc_descriptor (INTVAL (rtl));
|
||||
op0 = new_loc_descr (DW_OP_GNU_convert, 0, 0);
|
||||
op0->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
|
||||
op0->dw_loc_oprnd1.v.val_die_ref.die = type_die;
|
||||
op0->dw_loc_oprnd1.v.val_die_ref.external = 0;
|
||||
add_loc_descr (&mem_loc_result, op0);
|
||||
return mem_loc_result;
|
||||
}
|
||||
mem_loc_result = new_loc_descr (DW_OP_GNU_const_type, 0,
|
||||
INTVAL (rtl));
|
||||
mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
|
||||
|
@ -20962,6 +21095,19 @@ resolve_addr_in_expr (dw_loc_descr_ref loc)
|
|||
&& resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL))
|
||||
return false;
|
||||
break;
|
||||
case DW_OP_plus_uconst:
|
||||
if (size_of_loc_descr (loc)
|
||||
> size_of_int_loc_descriptor (loc->dw_loc_oprnd1.v.val_unsigned)
|
||||
+ 1
|
||||
&& loc->dw_loc_oprnd1.v.val_unsigned > 0)
|
||||
{
|
||||
dw_loc_descr_ref repl
|
||||
= int_loc_descriptor (loc->dw_loc_oprnd1.v.val_unsigned);
|
||||
add_loc_descr (&repl, new_loc_descr (DW_OP_plus, 0, 0));
|
||||
add_loc_descr (&repl, loc->dw_loc_next);
|
||||
*loc = *repl;
|
||||
}
|
||||
break;
|
||||
case DW_OP_implicit_value:
|
||||
if (loc->dw_loc_oprnd2.val_class == dw_val_class_addr
|
||||
&& resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL))
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
2011-07-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/49676
|
||||
* gcc.dg/guality/csttest.c: New test.
|
||||
|
||||
PR fortran/49698
|
||||
* gfortran.dg/pr49698.f90: New test.
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* PR debug/49676 */
|
||||
/* { dg-do run { target lp64 } } */
|
||||
/* { dg-options "-g" } */
|
||||
|
||||
volatile int v;
|
||||
|
||||
__attribute__((noinline, noclone))
|
||||
unsigned long long
|
||||
foo (unsigned long long x)
|
||||
{
|
||||
unsigned long long a = x * (0x17ULL << 31); /* { dg-final { gdb-test 29 "a" "(0x17ULL << 31)" } } */
|
||||
unsigned long long b = x * (0x7ULL << 33); /* { dg-final { gdb-test 29 "b" "(0x7ULL << 33)" } } */
|
||||
unsigned long long c = x * (0x1ULL << 35); /* { dg-final { gdb-test 29 "c" "(0x1ULL << 35)" } } */
|
||||
unsigned long long d = x * (0x17ULL << 15); /* { dg-final { gdb-test 29 "d" "(0x17ULL << 15)" } } */
|
||||
unsigned long long e = x * (0x17ULL << 50); /* { dg-final { gdb-test 29 "e" "(0x17ULL << 50)" } } */
|
||||
unsigned long long f = x * (0x37ULL << 31); /* { dg-final { gdb-test 29 "f" "(0x37ULL << 31)" } } */
|
||||
unsigned long long g = x * (0x37ULL << 50); /* { dg-final { gdb-test 29 "g" "(0x37ULL << 50)" } } */
|
||||
unsigned long long h = x * (0x1efULL << 33); /* { dg-final { gdb-test 29 "h" "(0x1efULL << 33)" } } */
|
||||
unsigned long long i = x * (0x1efULL << 50); /* { dg-final { gdb-test 29 "i" "(0x1efULL << 50)" } } */
|
||||
unsigned long long j = x * -(0x17ULL << 31); /* { dg-final { gdb-test 29 "j" "-(0x17ULL << 31)" } } */
|
||||
unsigned long long k = x * -(0x7ULL << 33); /* { dg-final { gdb-test 29 "k" "-(0x7ULL << 33)" } } */
|
||||
unsigned long long l = x * -(0x1ULL << 35); /* { dg-final { gdb-test 29 "l" "-(0x1ULL << 35)" } } */
|
||||
unsigned long long m = x * -(0x17ULL << 15); /* { dg-final { gdb-test 29 "m" "-(0x17ULL << 15)" } } */
|
||||
unsigned long long n = x * -(0x17ULL << 50); /* { dg-final { gdb-test 29 "n" "-(0x17ULL << 50)" } } */
|
||||
unsigned long long o = x * -(0x37ULL << 31); /* { dg-final { gdb-test 29 "o" "-(0x37ULL << 31)" } } */
|
||||
unsigned long long p = x * -(0x37ULL << 50); /* { dg-final { gdb-test 29 "p" "-(0x37ULL << 50)" } } */
|
||||
unsigned long long q = x * -(0x1efULL << 33); /* { dg-final { gdb-test 29 "q" "-(0x1efULL << 33)" } } */
|
||||
unsigned long long r = x * -(0x1efULL << 50); /* { dg-final { gdb-test 29 "r" "-(0x1efULL << 50)" } } */
|
||||
v++;
|
||||
return x;
|
||||
}
|
||||
|
||||
__attribute__((noinline, noclone))
|
||||
unsigned long long
|
||||
bar (unsigned long long x)
|
||||
{
|
||||
unsigned long long a = (x & 255) + (0x17ULL << 31); /* { dg-final { gdb-test 55 "a" "(0x17ULL << 31)" } } */
|
||||
unsigned long long b = (x & 255) + (0x7ULL << 33); /* { dg-final { gdb-test 55 "b" "(0x7ULL << 33)" } } */
|
||||
unsigned long long c = (x & 255) + (0x1ULL << 35); /* { dg-final { gdb-test 55 "c" "(0x1ULL << 35)" } } */
|
||||
unsigned long long d = (x & 255) + (0x17ULL << 15); /* { dg-final { gdb-test 55 "d" "(0x17ULL << 15)" } } */
|
||||
unsigned long long e = (x & 255) + (0x17ULL << 50); /* { dg-final { gdb-test 55 "e" "(0x17ULL << 50)" } } */
|
||||
unsigned long long f = (x & 255) + (0x37ULL << 31); /* { dg-final { gdb-test 55 "f" "(0x37ULL << 31)" } } */
|
||||
unsigned long long g = (x & 255) + (0x37ULL << 50); /* { dg-final { gdb-test 55 "g" "(0x37ULL << 50)" } } */
|
||||
unsigned long long h = (x & 255) + (0x1efULL << 33); /* { dg-final { gdb-test 55 "h" "(0x1efULL << 33)" } } */
|
||||
unsigned long long i = (x & 255) + (0x1efULL << 50); /* { dg-final { gdb-test 55 "i" "(0x1efULL << 50)" } } */
|
||||
unsigned long long j = (x & 255) + -(0x17ULL << 31); /* { dg-final { gdb-test 55 "j" "-(0x17ULL << 31)" } } */
|
||||
unsigned long long k = (x & 255) + -(0x7ULL << 33); /* { dg-final { gdb-test 55 "k" "-(0x7ULL << 33)" } } */
|
||||
unsigned long long l = (x & 255) + -(0x1ULL << 35); /* { dg-final { gdb-test 55 "l" "-(0x1ULL << 35)" } } */
|
||||
unsigned long long m = (x & 255) + -(0x17ULL << 15); /* { dg-final { gdb-test 55 "m" "-(0x17ULL << 15)" } } */
|
||||
unsigned long long n = (x & 255) + -(0x17ULL << 50); /* { dg-final { gdb-test 55 "n" "-(0x17ULL << 50)" } } */
|
||||
unsigned long long o = (x & 255) + -(0x37ULL << 31); /* { dg-final { gdb-test 55 "o" "-(0x37ULL << 31)" } } */
|
||||
unsigned long long p = (x & 255) + -(0x37ULL << 50); /* { dg-final { gdb-test 55 "p" "-(0x37ULL << 50)" } } */
|
||||
unsigned long long q = (x & 255) + -(0x1efULL << 33); /* { dg-final { gdb-test 55 "q" "-(0x1efULL << 33)" } } */
|
||||
unsigned long long r = (x & 255) + -(0x1efULL << 50); /* { dg-final { gdb-test 55 "r" "-(0x1efULL << 50)" } } */
|
||||
v++;
|
||||
return x;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return foo (1) + bar (256) - 257;
|
||||
}
|
Loading…
Reference in New Issue