[PATCH 4/5] Altera Nios II: dwarf generation fix
Julian Brown
julian@codesourcery.com
Mon Apr 22 17:34:00 GMT 2013
On Mon, 22 Apr 2013 21:36:38 +0800
Chung-Lin Tang <cltang@codesourcery.com> wrote:
> On 2013/4/19 12:56 AM, Cary Coutant wrote:
> > On Thu, Apr 18, 2013 at 6:49 AM, Chung-Lin Tang
> > <cltang@codesourcery.com> wrote:
> >> This patch was a fix by Julian which corrected a
> >> HOST_BITS_PER_WIDE_INT host dependency in dwarf generation. Nios
> >> II does not have need_64bit_hwint switched on during configuring,
> >> and ran into GDB test FAILs originating from this problem.
> >>
> >> 2013-04-18 Julian Brown <julian@codesourcery.com>
> >>
> >> * dwarf2out.c (gen_enumeration_type_die): Fix
> >> HOST_BITS_PER_WIDE_INT dependency behavior in enumeration
> >> type DIE generation.
> >
> > + if (host_integerp (value, TYPE_UNSIGNED (TREE_TYPE (value)))
> > + && (simple_type_size_in_bits (TREE_TYPE (value))
> > + <= HOST_BITS_PER_WIDE_INT || host_integerp (value, 0)))
> > /* DWARF2 does not provide a way of indicating whether or
> > not enumeration constants are signed or unsigned. GDB
> > always assumes the values are signed, so we output all
> > values as if they were signed. That means that
> > enumeration constants with very large unsigned values
> > will appear to have negative values in the debugger. */
> > + add_AT_int (enum_die, DW_AT_const_value, TREE_INT_CST_LOW
> > (value));
> > + else
> > + /* Enumeration constants may be wider than HOST_WIDE_INT.
> > Handle
> > + that here. */
> > + add_AT_double (enum_die, DW_AT_const_value,
> > + TREE_INT_CST_HIGH (value), TREE_INT_CST_LOW
> > (value));
> >
> > I'm not sure I understand the logic here. I'd think either the value
> > fits in a signed HOST_WIDE_INT, and we use add_AT_int, or it
> > doesn't, and we use add_AT_double:
> >
> > if (host_integerp (value, 0))
> > add_AT_int (enum_die, DW_AT_const_value, TREE_INT_CST_LOW
> > (value)); else
> > add_AT_double (enum_die, DW_AT_const_value,
> > TREE_INT_CST_HIGH (value), TREE_INT_CST_LOW
> > (value));
> >
> > Why wouldn't that work? I'd think this would even eliminate the need
> > for the comment about signed vs. unsigned.
> >
> > -cary
>
> I think Julian might be able to fill clearer, but IIUC, if you use
> host_integer(value,0) as the test, while functionally also correct,
> for values like:
>
> TREE_INT_CST_HIGH (value) == 00000000...
> TREE_INT_CST_LOW (value) == 1xxxxxxx...
>
> you will end up placing it as a double, even if TREE_TYPE (value) is
> something within 32-bits, which you can actually place as an 'int'. In
> other words, the more complex condition saves a bit of dwarf size.
>
> Julian, can you comment further?
I think that's basically right -- I'd swapped this patch out of my head
by now, so I had a go at reconstructing the logic behind it. Here's an
ASCII-art table depicting the current behaviour of this clause in the
gen_enumeration_type_die function:
A : host_integerp (value, TYPE_UNSIGNED (TREE_TYPE (value)))
B : host_integerp (value, 0)
AB AB AB AB
type_size,hwi | 00 01 10 11
--------------+-------------------------------
32,32 | X X int int
64,32 | X X int int
32,64 | X X - int
64,64 | X X int int
entries marked 'X' emit no value at all for the DIE at present. Entries
marked '-' will not occur in practice, i.e. if the type size is
32 bits, and H_W_I is 64 bits, then all values of the former can be
represented in the latter, so the predicate will never be true.
Here's a table representing the behaviour with my patch:
A : host_integerp (value, TYPE_UNSIGNED (TREE_TYPE (value)))
B : host_integerp (value, 0)
AB AB AB AB
type_size,hwi | 00 01 10 11
--------------+-------------------------------
32,32 | - - int int
64,32 | double double double int
32,64 | - - - int
64,64 | - - int int
(Entries marked 'int' emit an int const_value, those marked 'double'
emit a double one.)
So: the only row affected is the one where HOST_WIDE_INT is 32 bits,
but we're trying to represent a 64-bit enum type. In the particular
case where both host_integerp predicates are true (e.g. the type is
signed or unsigned, but fits within the value range of a signed type)
we can still emit it as a single int.
With Cary's proposed simplification of the patch, the table would look
like:
A : host_integerp (value, TYPE_UNSIGNED (TREE_TYPE (value)))
B : host_integerp (value, 0)
AB AB AB AB
type_size,hwi | 00 01 10 11
--------------+-------------------------------
32,32 | - - double int
64,32 | double int double int
32,64 | - - - int
64,64 | - - double int
Unfortunately I think this breaks for e.g. type_size and hwi size being
64 bits, predicate A being true and B being false (the bottom entry on
the second-to-rightmost column). Such a value might be the unsigned
quantity:
0x8000000000000000
Emitting this as a double DW_AT_const_value (i.e. 128 bits) would not
only be wasteful, but would probably actually be wrong: I wouldn't be
surprised if GDB couldn't handle that. In the case where type_size & hwi
are both 32 bits it might or might not be wrong to emit a double
const_value, but it might also confuse GDB (it's a change of semantics
for big unsigned values at least, I think).
(The second row, AB=01 entry I'm not sure about -- that might be
another '-' case in practice...)
HTH,
Julian
More information about the Gcc-patches
mailing list