diff mbox

[Ada] Avoid unnecessarily overaligned access types

Message ID 201208191615.18675.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou Aug. 19, 2012, 2:15 p.m. UTC
This changes the default alignment of all access types to that of access types
with standard size (Standard'Address_Size) on non-strict-alignment platforms.
This in particular means that access-to-unconstrained-array types, whose size
is twice as large as that of regular access types, are not overaligned by
default anymore and therefore don't cause unnecessary padding in record types.

The following program must run quietly on these platforms:

procedure P is
  type Array_T is array (Positive range <>) of Integer;
  type Access_Array_T is access Array_T;
  type Thin_Access_Array_T is access Array_T;
  for Thin_Access_Array_T'Size use Standard'Address_Size;
begin
  if Access_Array_T'Alignment /= Thin_Access_Array_T'Alignment then
    raise Program_Error;
  end if;
end;

Tested on x86_64-suse-linux, applied on the mainline.


2012-08-19  Eric Botcazou  <ebotcazou@adacore.com>

	* layout.adb (Set_Elem_Alignment): Cap the alignment of access types to
	that of a regular access type for non-strict-alignment platforms.
	* gcc-interface/utils.c (finish_fat_pointer_type): Do not set the
	alignment for non-strict-alignment platforms.
diff mbox

Patch

Index: layout.adb
===================================================================
--- layout.adb	(revision 190510)
+++ layout.adb	(working copy)
@@ -3118,6 +3118,19 @@  package body Layout is
 
          if Esize (E) / SSU > Ttypes.Maximum_Alignment then
             S := Ttypes.Maximum_Alignment;
+
+         --  If this is an access type and the target doesn't have strict
+         --  alignment and we are not doing front end layout, then cap the
+         --  alignment to that of a regular access type. This will avoid
+         --  giving fat pointers twice the usual alignment for no practical
+         --  benefit since the misalignment doesn't really matter.
+
+         elsif Is_Access_Type (E)
+           and then not Target_Strict_Alignment
+           and then not Frontend_Layout_On_Target
+         then
+            S := System_Address_Size / SSU;
+
          else
             S := UI_To_Int (Esize (E)) / SSU;
          end if;
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 190510)
+++ gcc-interface/utils.c	(working copy)
@@ -1369,7 +1369,8 @@  void
 finish_fat_pointer_type (tree record_type, tree field_list)
 {
   /* Make sure we can put it into a register.  */
-  TYPE_ALIGN (record_type) = MIN (BIGGEST_ALIGNMENT, 2 * POINTER_SIZE);
+  if (STRICT_ALIGNMENT)
+    TYPE_ALIGN (record_type) = MIN (BIGGEST_ALIGNMENT, 2 * POINTER_SIZE);
 
   /* Show what it really is.  */
   TYPE_FAT_POINTER_P (record_type) = 1;