This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] improve handling of ms_struct
- From: Eric Christopher <echristo at apple dot com>
- To: "gcc-patches at gcc dot gnu dot org Patches" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 27 Apr 2006 20:38:23 -0700
- Subject: [patch] improve handling of ms_struct
The ms_struct attribute is, I believe, supposed to be for layout out
structures as close to the MS layout as we can. It turns out that
it's not just the bitfield packing, but the rest of the structure
layout and alignment as well.
Here's a brief description of the layout:
The padding and alignment of members of structures and whether a bit
field can straddle a storage-unit boundary
• Structure members are stored sequentially in the order in which
they are declared: the first member has the lowest memory address and
the last member the highest.
• Every data object has an alignment-requirement. The alignment-
requirement for all data except structures, unions, and arrays is
either the size of the object or the current packing size (specified
with either the aligned attribute or the pack pragma), whichever is
less. For structures, unions, and arrays, the alignment-requirement
is the largest alignment-requirement of its members. Every object is
allocated an offset so that:
offset % alignment-requirement == 0
• Adjacent bit fields are packed into the same 1-, 2-, or 4-byte
allocation unit if the integral types are the same size and if the
next bit field fits into the current allocation unit without crossing
the boundary imposed by the common alignment requirements of the bit
fields.
MSVC interprets zero-length bitfields in the following ways:
1.) If a zero-length bitfield is inserted between two bitfields that
would normally be coalesced, the bitfields will not be coalesced.
For example:
struct
{
unsigned long bf_1 : 12;
unsigned long : 0;
unsigned long bf_2 : 12;
} t1;
The size of t1 would be 8 bytes with the zero-length bitfield. If
the zero-length bitfield were removed, t1's size would be 4 bytes.
2.) If a zero-length bitfield is inserted after a bitfield, foo, and
the alignment of the zero-length bitfield is greater than the member
that follows it, bar, bar will be aligned as the type of the zero-
length bitfield.
For example:
struct
{
char foo : 4;
short : 0;
char bar;
} t2;
struct
{
char foo : 4;
short : 0;
double bar;
} t3;
For t2, bar will be placed at offset 2, rather than offset 1.
Accordingly, the size of t2 will be 4. For t3, the zero-length
bitfield will not affect the alignment of bar or, as a result, the
size of the structure.
Taking this into account, it is important to note the following:
• If a zero-length bitfield follows a non-anonymous bitfield, the
type of the zero-length bitfield may affect the alignment of the
structure as whole. For example, t2 has a size of 4 bytes, since the
anonymous zero-length bitfield follows a non-anonymous bitfield, and
is of type short.
• Even if an anonymous zero-length struct is not followed by a non-
anonymous bitfield, it may still affect the alignment of the structure:
struct
{
char foo : 6;
long : 0;
} t4;
Here, t4 will take up 4 bytes.
3.) Anonymous zero-length bitfields following non-bitfield members
are (as far as I can tell) ignored:
struct
{
char foo;
long : 0;
char bar;
} t5;
Here, t5 will take up 2 bytes.
I've tested the current fix with about 100k randomly generated
structures with various amounts of packing, zero-length bitfields,
and random numbers of fields up to 20 in the structure. This takes
the failures from ~48% to about .1%. I'm still missing a couple of
cases, but this is quite the improvement. I'll likely be continuing
to work on this over time, but wanted to get the largish patch out
first. Plus I have some special handling for big endian targets that
I'd like to get out after this.
Admittedly I'd have liked to rewrite stor-layout.c for this, but I've
not been able to steal time to do that. At some point we might want
to rewrite the structure layout code to allow different code paths
for different layouts that is a little more obvious. That's for
another time though.
OK? Thoughts? Questions?
-eric
2006-04-27 Eric Christopher <echristo@apple.com>
* stor-layout.c (update_alignment_for_field): Unconditionalize
ms_bitfield_layout_p code. Handle non-bitfield fields. Remove
extra alignment code.
(place_field): Don't realign if ms_bitfield_layout_p. Unconditionalize
ms_bitfield_layout_p code. Rewrite handling of structure fields.
Attachment:
stor-layout.c.diff.txt
Description: Text document