This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]