aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorPierre-Marie de Rodat <derodat@adacore.com>2016-10-12 08:38:49 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2016-10-12 08:38:49 +0000
commitb4a9ef2f4d68a5a10f4c87c9f416562bf5f59d35 (patch)
tree04fa1e4d55ed57b4c0742c9e0423a0598b7dda3b /gcc/dwarf2out.c
parentc0dbd22d2eebf14210473be5c37da77083dbbf5f (diff)
downloadgcc-b4a9ef2f4d68a5a10f4c87c9f416562bf5f59d35.zip
gcc-b4a9ef2f4d68a5a10f4c87c9f416562bf5f59d35.tar.gz
gcc-b4a9ef2f4d68a5a10f4c87c9f416562bf5f59d35.tar.bz2
DWARF: space-optimize loc. descr. for integer literals on 32-bit targets
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. 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/testsuite/ * gnat.dg/debug8.adb: New testcase. From-SVN: r241024
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index f03e9aa..b5787ef 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -11985,20 +11985,35 @@ 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 (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
@@ -12223,6 +12238,10 @@ 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 (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);