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] |
Tested on x86-linux, committed on mainline. A recent patch that changes the way that sizes are computed in records computes TYPE_SIZE_UNIT by dividing TYPE_SIZE by the BITS_PER_UNIT. That's fine for constants (where it was intended), but is very costly for variable sizes since it means that we compute the byte size by doing 2-word computations. We only do this for repped records, which normally mean everything is constant, but that's not true in the padded type case. We also noticed that while Ada does not feature Fortran-like COMMON variables, on platforms that do not support global BSS sections, uninitialized global variables would go in DATA if DECL_COMMON was not set, thus increasing the size of the executable. In addition, some BLKmode fields may both be claimed potentially addressable and still have to be made a bitfield. The testcase at hand shows exactly one of those cases, in which a bitfield is required to ensure that a representation clause is properly honored. Not making a bitfield yields to an alignment increase, and so a size increase, having the field actually occupy more space than stated by the rep clause, in turn overlapping the following component. The current conditions controlling bitfield creation reject every so-claimed potentially addressable fields, which is too strong for the reasons stated above. This was initially introduced to prevent the creation of a bitfield in the make_aligning_type case, because it screws up the field's alignment and completely defeats the scheme later on. This case happens to be special enough to call for a special handling, which is what this change is doing. The ADDRESSABLE argument of create_field_decl is special cased to have negative values mean "no bitfield creation", and make_aligning_type uses that. Testcase: -- Compile and run this, expected to output nothing: -- $ gnatmake -f p.adb && ./p -- $ -- Without the bug fix, it raises Program_Error because the assignment to -- Block.Vkey clobbers part of Block.Data: -- $ gnatmake -f p.adb && ./p -- [...] -- raised PROGRAM_ERROR : p.adb:62 explicit raise with Ada.Text_Io; use Ada.Text_Io; procedure P is type Uint16_T is range 0 .. 2 ** 16 - 1; for Uint16_T'Size use 16; type Uint32_T is range 0 .. 2 ** 32 - 1; for Uint32_T'Size use 32; type Key_T is record A, B, C : Uint32_T; end record; Key_Bits : constant := 3 * 32; for Key_T'Size use Key_Bits; Null_Key : constant Key_T := (A => 0, B => 0, C => 0); type Vkey_T is record Key : Key_T; Value : Uint16_T; end record; for Vkey_T use record Key at 0 range 0 .. Key_Bits - 1; Value at Key_Bits / 8 range 0 .. 16 - 1; end record; Vkey_Bits : constant := Key_Bits + 16; for Vkey_T'Size use Vkey_Bits; Null_Vkey : constant Vkey_T := (Key => Null_Key, Value => 0); type Data_Block_T (Valid : Boolean) is record Vkey : Vkey_T; Data : Uint32_T; end record; for Data_Block_T use record Valid at 0 range 0 .. 7; Vkey at 4 range 0 .. Vkey_Bits - 1; Data at 4 + Vkey_Bits / 8 range 0 .. 32 - 1; end record; Block : Data_Block_T (Valid => True); begin Block.Data := 333; Block.Vkey := Null_Vkey; if Block.Data /= 333 then raise Program_Error; end if; end P; 2004-12-07 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> Olivier Hainque <hainque@adacore.com> Eric Botcazou <ebotcazou@adacore.com> * decl.c (maybe_pad_type): Use TYPE_SIZE_UNIT of the input type for TYPE_SIZE_UNIT of result type if SIZE is not specified. (make_aligning_type): Pass -1 as ADDRESSABLE to prevent the creation of a bitfield, which we know is useless and causes trouble because of alignment implications. * utils.c (create_var_decl): Set DECL_COMMON again on targets without BSS sections. (process_attributes): Clear DECL_COMMON again when a section attribute is present. (finish_record_type): Independently track if RECORD_TYPE has SIZE and/or SIZE_UNIT already set and use to compute final SIZE and SIZE_UNIT. (create_field_decl): Special case ADDRESSABLE negative to mean "no bitfield creation", to be used by make_aligning_type. Don't restrict bitfield creation to !ADDRESSABLE any more, as some BLKmode fields claimed addressable still have to be bitfields. Use value_factor_p instead of a raw binop construction to check for the position's alignment.
Attachment:
difs.7
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |