Hello, This enhances location description generation so that the generated opcodes for integer literals are as space-efficient when HOST_WIDE_INT is 64-bits large than when it's 32-bits large. In particular, this reduces the size of the opcodes generated to produce big unsigned literals using small literal integers instead.
Bootstrapped and regtested on x86-linux (no regression). I also checked that the new testcase fails with mainline. Ok to commit? Thank you in advance! gcc/ * dwarf2out.c (int_loc_descriptor): Generate opcodes for another equivalent 32-bit constant (modulo 2**32) when that yields smaller instructions. (size_of_int_loc_descriptor): Update accordingly. --- gcc/dwarf2out.c | 31 ++++++++++++++++++++++++++----- gcc/testsuite/gnat.dg/debug8.adb | 29 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/debug8.adb diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 0fdab9a..f175ea1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -11954,20 +11954,36 @@ int_loc_descriptor (HOST_WIDE_INT i) /* 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 + && DWARF2_ADDR_SIZE == 4 && i > 0x7fffffff + && size_of_int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i) + <= 4) + { + /* As i >= 2**31, the double cast above will yield a negative number. + Since wrapping is defined in DWARF expressions we can output big + positive integers as small negative ones, regardless of the size + of host wide ints. + + Here, since the evaluator will handle 32-bit values and since i >= + 2**31, we know it's going to be interpreted as a negative literal: + store it this way if we can do better than 5 bytes this way. */ + return int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i); + } else if (HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff) op = DW_OP_const4u; + + /* Past this point, i >= 0x100000000 and thus DW_OP_constu will take at + least 6 bytes: see if we can do better before falling back to it. */ 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. */ + /* DW_OP_const1u X DW_OP_const1u Y DW_OP_shl takes just 5 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. */ + DW_OP_const2u X DW_OP_const1u Y DW_OP_shl takes 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 @@ -12192,6 +12208,11 @@ size_of_int_loc_descriptor (HOST_WIDE_INT i) && 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 + && DWARF2_ADDR_SIZE == 4 && i > 0x7fffffff + && size_of_int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i) + <= 4) + return size_of_int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i); else if (HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff) return 5; s = size_of_uleb128 ((unsigned HOST_WIDE_INT) i); diff --git a/gcc/testsuite/gnat.dg/debug8.adb b/gcc/testsuite/gnat.dg/debug8.adb new file mode 100644 index 0000000..fabcc22 --- /dev/null +++ b/gcc/testsuite/gnat.dg/debug8.adb @@ -0,0 +1,29 @@ +-- { dg-do compile } +-- { dg-options "-cargs -g -fgnat-encodings=minimal -dA" } +-- { dg-final { scan-assembler-not "DW_OP_const4u" } } +-- { dg-final { scan-assembler-not "DW_OP_const8u" } } + +-- The DW_AT_byte_size attribute DWARF expression for the +-- DW_TAG_structure_type DIE that describes Rec_Type contains the -4u literal. +-- Check that it is not created using an inefficient encoding (DW_OP_const1s +-- is expected). + +procedure Debug8 is + + type Rec_Type (I : Integer) is record + B : Boolean; + case I is + when 0 => + null; + when 1 .. 10 => + C : Character; + when others => + N : Natural; + end case; + end record; + + R : access Rec_Type := null; + +begin + null; +end Debug8; -- 2.9.3