This is the mail archive of the 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]

[Ada] GIGI adjustments/fixes

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.

--  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);

   Block.Data := 333; Block.Vkey := Null_Vkey;
   if Block.Data /= 333 then raise Program_Error; end if;
end P;

2004-12-07  Richard Kenner  <>
	    Olivier Hainque  <>
	    Eric Botcazou  <>

	* 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]