dwarf2out.c (field_byte_offset): Move the existing logic under the control of PCC_BITFIELD_TYPE_MATTERS and just...

* dwarf2out.c (field_byte_offset): Move the existing logic
	under the control of PCC_BITFIELD_TYPE_MATTERS and just use
	the bit offset of the field if !PCC_BITFIELD_TYPE_MATTERS.

From-SVN: r124104
This commit is contained in:
Nathan Froyd 2007-04-24 14:45:08 +00:00 committed by Nathan Froyd
parent 6b8846f834
commit cd0a10dd99
2 changed files with 92 additions and 72 deletions

View File

@ -1,3 +1,9 @@
2007-04-24 Nathan Froyd <froydnj@codesourcery.com>
* dwarf2out.c (field_byte_offset): Move the existing logic
under the control of PCC_BITFIELD_TYPE_MATTERS and just use
the bit offset of the field if !PCC_BITFIELD_TYPE_MATTERS.
2007-04-24 Andreas Krebbel <krebbel1@de.ibm.com>
PR target/31641

View File

@ -9694,29 +9694,14 @@ round_up_to_align (HOST_WIDE_INT t, unsigned int align)
static HOST_WIDE_INT
field_byte_offset (tree decl)
{
unsigned int type_align_in_bits;
unsigned int decl_align_in_bits;
unsigned HOST_WIDE_INT type_size_in_bits;
HOST_WIDE_INT object_offset_in_bits;
tree type;
tree field_size_tree;
HOST_WIDE_INT bitpos_int;
HOST_WIDE_INT deepest_bitpos;
unsigned HOST_WIDE_INT field_size_in_bits;
if (TREE_CODE (decl) == ERROR_MARK)
return 0;
gcc_assert (TREE_CODE (decl) == FIELD_DECL);
type = field_type (decl);
field_size_tree = DECL_SIZE (decl);
/* The size could be unspecified if there was an error, or for
a flexible array member. */
if (! field_size_tree)
field_size_tree = bitsize_zero_node;
/* We cannot yet cope with fields whose positions are variable, so
for now, when we see such things, we simply return 0. Someday, we may
be able to handle such cases, but it will be damn difficult. */
@ -9725,76 +9710,105 @@ field_byte_offset (tree decl)
bitpos_int = int_bit_position (decl);
/* If we don't know the size of the field, pretend it's a full word. */
if (host_integerp (field_size_tree, 1))
field_size_in_bits = tree_low_cst (field_size_tree, 1);
else
field_size_in_bits = BITS_PER_WORD;
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
{
tree type;
tree field_size_tree;
HOST_WIDE_INT deepest_bitpos;
unsigned HOST_WIDE_INT field_size_in_bits;
unsigned int type_align_in_bits;
unsigned int decl_align_in_bits;
unsigned HOST_WIDE_INT type_size_in_bits;
type_size_in_bits = simple_type_size_in_bits (type);
type_align_in_bits = simple_type_align_in_bits (type);
decl_align_in_bits = simple_decl_align_in_bits (decl);
type = field_type (decl);
field_size_tree = DECL_SIZE (decl);
/* The GCC front-end doesn't make any attempt to keep track of the starting
bit offset (relative to the start of the containing structure type) of the
hypothetical "containing object" for a bit-field. Thus, when computing
the byte offset value for the start of the "containing object" of a
bit-field, we must deduce this information on our own. This can be rather
tricky to do in some cases. For example, handling the following structure
type definition when compiling for an i386/i486 target (which only aligns
long long's to 32-bit boundaries) can be very tricky:
/* The size could be unspecified if there was an error, or for
a flexible array member. */
if (! field_size_tree)
field_size_tree = bitsize_zero_node;
/* If we don't know the size of the field, pretend it's a full word. */
if (host_integerp (field_size_tree, 1))
field_size_in_bits = tree_low_cst (field_size_tree, 1);
else
field_size_in_bits = BITS_PER_WORD;
type_size_in_bits = simple_type_size_in_bits (type);
type_align_in_bits = simple_type_align_in_bits (type);
decl_align_in_bits = simple_decl_align_in_bits (decl);
/* The GCC front-end doesn't make any attempt to keep track of the
starting bit offset (relative to the start of the containing
structure type) of the hypothetical "containing object" for a
bit-field. Thus, when computing the byte offset value for the
start of the "containing object" of a bit-field, we must deduce
this information on our own. This can be rather tricky to do in
some cases. For example, handling the following structure type
definition when compiling for an i386/i486 target (which only
aligns long long's to 32-bit boundaries) can be very tricky:
struct S { int field1; long long field2:31; };
Fortunately, there is a simple rule-of-thumb which can be used in such
cases. When compiling for an i386/i486, GCC will allocate 8 bytes for the
structure shown above. It decides to do this based upon one simple rule
for bit-field allocation. GCC allocates each "containing object" for each
bit-field at the first (i.e. lowest addressed) legitimate alignment
boundary (based upon the required minimum alignment for the declared type
of the field) which it can possibly use, subject to the condition that
there is still enough available space remaining in the containing object
(when allocated at the selected point) to fully accommodate all of the
bits of the bit-field itself.
Fortunately, there is a simple rule-of-thumb which can be used
in such cases. When compiling for an i386/i486, GCC will
allocate 8 bytes for the structure shown above. It decides to
do this based upon one simple rule for bit-field allocation.
GCC allocates each "containing object" for each bit-field at
the first (i.e. lowest addressed) legitimate alignment boundary
(based upon the required minimum alignment for the declared
type of the field) which it can possibly use, subject to the
condition that there is still enough available space remaining
in the containing object (when allocated at the selected point)
to fully accommodate all of the bits of the bit-field itself.
This simple rule makes it obvious why GCC allocates 8 bytes for each
object of the structure type shown above. When looking for a place to
allocate the "containing object" for `field2', the compiler simply tries
to allocate a 64-bit "containing object" at each successive 32-bit
boundary (starting at zero) until it finds a place to allocate that 64-
bit field such that at least 31 contiguous (and previously unallocated)
bits remain within that selected 64 bit field. (As it turns out, for the
example above, the compiler finds it is OK to allocate the "containing
object" 64-bit field at bit-offset zero within the structure type.)
This simple rule makes it obvious why GCC allocates 8 bytes for
each object of the structure type shown above. When looking
for a place to allocate the "containing object" for `field2',
the compiler simply tries to allocate a 64-bit "containing
object" at each successive 32-bit boundary (starting at zero)
until it finds a place to allocate that 64- bit field such that
at least 31 contiguous (and previously unallocated) bits remain
within that selected 64 bit field. (As it turns out, for the
example above, the compiler finds it is OK to allocate the
"containing object" 64-bit field at bit-offset zero within the
structure type.)
Here we attempt to work backwards from the limited set of facts we're
given, and we try to deduce from those facts, where GCC must have believed
that the containing object started (within the structure type). The value
we deduce is then used (by the callers of this routine) to generate
DW_AT_location and DW_AT_bit_offset attributes for fields (both bit-fields
and, in the case of DW_AT_location, regular fields as well). */
Here we attempt to work backwards from the limited set of facts
we're given, and we try to deduce from those facts, where GCC
must have believed that the containing object started (within
the structure type). The value we deduce is then used (by the
callers of this routine) to generate DW_AT_location and
DW_AT_bit_offset attributes for fields (both bit-fields and, in
the case of DW_AT_location, regular fields as well). */
/* Figure out the bit-distance from the start of the structure to the
"deepest" bit of the bit-field. */
deepest_bitpos = bitpos_int + field_size_in_bits;
/* Figure out the bit-distance from the start of the structure to
the "deepest" bit of the bit-field. */
deepest_bitpos = bitpos_int + field_size_in_bits;
/* This is the tricky part. Use some fancy footwork to deduce where the
lowest addressed bit of the containing object must be. */
object_offset_in_bits = deepest_bitpos - type_size_in_bits;
/* Round up to type_align by default. This works best for bitfields. */
object_offset_in_bits
= round_up_to_align (object_offset_in_bits, type_align_in_bits);
if (object_offset_in_bits > bitpos_int)
{
/* Sigh, the decl must be packed. */
/* This is the tricky part. Use some fancy footwork to deduce
where the lowest addressed bit of the containing object must
be. */
object_offset_in_bits = deepest_bitpos - type_size_in_bits;
/* Round up to decl_align instead. */
/* Round up to type_align by default. This works best for
bitfields. */
object_offset_in_bits
= round_up_to_align (object_offset_in_bits, decl_align_in_bits);
= round_up_to_align (object_offset_in_bits, type_align_in_bits);
if (object_offset_in_bits > bitpos_int)
{
object_offset_in_bits = deepest_bitpos - type_size_in_bits;
/* Round up to decl_align instead. */
object_offset_in_bits
= round_up_to_align (object_offset_in_bits, decl_align_in_bits);
}
}
else
#endif
object_offset_in_bits = bitpos_int;
return object_offset_in_bits / BITS_PER_UNIT;
}