Commit cd0a10dd by Nathan Froyd Committed by Nathan Froyd

dwarf2out.c (field_byte_offset): Move the existing logic under the control of…

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