From 14ecca2eea820447afe3214ed635883fbc4244a4 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 30 Nov 2015 11:25:24 +0000 Subject: [PATCH] ada-tree.h (TYPE_MAX_ALIGN): New macro. * gcc-interface/ada-tree.h (TYPE_MAX_ALIGN): New macro. * gcc-interface/decl.c (gnat_to_gnu_entity): Do not set PACKED to -2. Remove obsolete code setting the alignment on some atomic types. When the type has no alignment but needs strict alignment and has a size clause, compute a maximum alignment and set it on the type. (adjust_packed): Remove handling of -2 argument. Deal with TYPE_ALIGN and TYPE_MAX_ALIGN directly. (gnat_to_gnu_field): Do not document -2 as argument. (components_to_record): Likewise. * gcc-interface/utils.c (finish_record_type): Do not bump alignment of the record type beyond TYPE_MAX_ALIGN. Reset the latter on exit. * gcc-interface/Makefile.in (PICFLAG_FOR_TARGET): Move around. (GNATLIBCFLAGS_FOR_C): Reformat. (GCC_CFLAGS): Delete. From-SVN: r231062 --- gcc/ada/ChangeLog | 18 +++++ gcc/ada/gcc-interface/Makefile.in | 23 +----- gcc/ada/gcc-interface/ada-tree.h | 4 + gcc/ada/gcc-interface/decl.c | 82 ++++++++++----------- gcc/ada/gcc-interface/utils.c | 10 ++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gnat.dg/specs/rep_clause5.ads | 75 +++++++++++++++++++ 7 files changed, 150 insertions(+), 66 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/specs/rep_clause5.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d8196f483e4..a90fa647b5f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,21 @@ +2015-11-30 Eric Botcazou + + * gcc-interface/ada-tree.h (TYPE_MAX_ALIGN): New macro. + * gcc-interface/decl.c (gnat_to_gnu_entity): Do not set PACKED to -2. + Remove obsolete code setting the alignment on some atomic types. + When the type has no alignment but needs strict alignment and has a + size clause, compute a maximum alignment and set it on the type. + (adjust_packed): Remove handling of -2 argument. Deal with TYPE_ALIGN + and TYPE_MAX_ALIGN directly. + (gnat_to_gnu_field): Do not document -2 as argument. + (components_to_record): Likewise. + * gcc-interface/utils.c (finish_record_type): Do not bump alignment of + the record type beyond TYPE_MAX_ALIGN. Reset the latter on exit. + + * gcc-interface/Makefile.in (PICFLAG_FOR_TARGET): Move around. + (GNATLIBCFLAGS_FOR_C): Reformat. + (GCC_CFLAGS): Delete. + 2015-11-29 Matthias Klose PR ada/68564 diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index bed93b98860..3b27ae3659b 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -111,13 +111,12 @@ NO_SIBLING_ADAFLAGS = -fno-optimize-sibling-calls NO_REORDER_ADAFLAGS = -fno-toplevel-reorder GNATLIBFLAGS = -W -Wall -gnatpg -nostdinc GNATLIBCFLAGS = -g -O2 -PICFLAG_FOR_TARGET = @PICFLAG_FOR_TARGET@ - # Pretend that _Unwind_GetIPInfo is available for the target by default. This # should be autodetected during the configuration of libada and passed down to # here, but we need something for --disable-libada and hope for the best. -GNATLIBCFLAGS_FOR_C = -W -Wall $(GNATLIBCFLAGS) \ - -fexceptions -DIN_RTS -DHAVE_GETIPINFO +GNATLIBCFLAGS_FOR_C = \ + -W -Wall $(GNATLIBCFLAGS) -fexceptions -DIN_RTS -DHAVE_GETIPINFO +PICFLAG_FOR_TARGET = @PICFLAG_FOR_TARGET@ ALL_ADAFLAGS = $(CFLAGS) $(ADA_CFLAGS) $(ADAFLAGS) THREAD_KIND = native THREADSLIB = @@ -132,22 +131,6 @@ soext = .so shext = hyphen = - -# Define this as & to perform parallel make on a Sequent. -# Note that this has some bugs, and it seems currently necessary -# to compile all the gen* files first by hand to avoid erroneous results. -P = - -# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET. -# It specifies -B./. -# It also specifies -B$(tooldir)/ to find as and ld for a cross compiler. -GCC_CFLAGS = $(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS) - -# Tools to use when building a cross-compiler. -# These are used because `configure' appends `cross-make' -# to the makefile when making a cross-compiler. - -# We don't use cross-make. Instead we use the tools from the build tree, -# if they are available. # program_transform_name and objdir are set by configure.ac. program_transform_name = objdir = . diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index 4e368f00dad..5d93ea4bc5c 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -176,6 +176,10 @@ do { \ /* True if TYPE can alias any other types. */ #define TYPE_UNIVERSAL_ALIASING_P(NODE) TYPE_LANG_FLAG_6 (NODE) +/* For RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE, this holds the maximum + alignment value the type ought to have. */ +#define TYPE_MAX_ALIGN(NODE) (TYPE_PRECISION (RECORD_OR_UNION_CHECK (NODE))) + /* For an UNCONSTRAINED_ARRAY_TYPE, this is the record containing both the template and the object. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 3ae079ff904..2450b5066b0 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -2829,11 +2829,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ? 1 : Component_Alignment (gnat_entity) == Calign_Storage_Unit ? -1 - : (Known_Alignment (gnat_entity) - || (Strict_Alignment (gnat_entity) - && Known_RM_Size (gnat_entity))) - ? -2 - : 0; + : 0; + const bool has_align = Known_Alignment (gnat_entity); const bool has_discr = Has_Discriminants (gnat_entity); const bool has_rep = Has_Specified_Layout (gnat_entity); const bool is_extension @@ -2872,7 +2869,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) suppress expanding incomplete types. */ gnu_type = make_node (tree_code_for_record_type (gnat_entity)); TYPE_NAME (gnu_type) = gnu_entity_name; - TYPE_PACKED (gnu_type) = (packed != 0) || has_rep; + TYPE_PACKED (gnu_type) = (packed != 0) || has_align || has_rep; TYPE_REVERSE_STORAGE_ORDER (gnu_type) = Reverse_Storage_Order (gnat_entity); process_attributes (&gnu_type, &attr_list, true, gnat_entity); @@ -2883,38 +2880,32 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) this_deferred = true; } - /* If both a size and rep clause was specified, put the size in - the record type now so that it can get the proper mode. */ + /* If both a size and rep clause were specified, put the size on + the record type now so that it can get the proper layout. */ if (has_rep && Known_RM_Size (gnat_entity)) TYPE_SIZE (gnu_type) = UI_To_gnu (RM_Size (gnat_entity), bitsizetype); - /* Always set the alignment here so that it can be used to - set the mode, if it is making the alignment stricter. If - it is invalid, it will be checked again below. If this is to - be Atomic, choose a default alignment of a word unless we know - the size and it's smaller. */ - if (Known_Alignment (gnat_entity)) + /* Always set the alignment on the record type here so that it can + get the proper layout. */ + if (has_align) TYPE_ALIGN (gnu_type) = validate_alignment (Alignment (gnat_entity), gnat_entity, 0); - else if (Is_Atomic_Or_VFA (gnat_entity) && Known_Esize (gnat_entity)) - { - unsigned int size = UI_To_Int (Esize (gnat_entity)); - TYPE_ALIGN (gnu_type) - = size >= BITS_PER_WORD ? BITS_PER_WORD : ceil_pow2 (size); - } - /* If a type needs strict alignment, the minimum size will be the - type size instead of the RM size (see validate_size). Cap the - alignment, lest it causes this type size to become too large. */ - else if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity)) + else { - unsigned int raw_size = UI_To_Int (RM_Size (gnat_entity)); - unsigned int raw_align = raw_size & -raw_size; - if (raw_align < BIGGEST_ALIGNMENT) - TYPE_ALIGN (gnu_type) = raw_align; + TYPE_ALIGN (gnu_type) = 0; + + /* If a type needs strict alignment, the minimum size will be the + type size instead of the RM size (see validate_size). Cap the + alignment lest it causes this type size to become too large. */ + if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity)) + { + unsigned int max_size = UI_To_Int (RM_Size (gnat_entity)); + unsigned int max_align = max_size & -max_size; + if (max_align < BIGGEST_ALIGNMENT) + TYPE_MAX_ALIGN (gnu_type) = max_align; + } } - else - TYPE_ALIGN (gnu_type) = 0; /* If we have a Parent_Subtype, make a field for the parent. If this record has rep clauses, force the position to zero. */ @@ -6502,25 +6493,29 @@ adjust_packed (tree field_type, tree record_type, int packed) if (type_has_variable_size (field_type)) return 0; + /* In the other cases, we can honor the packing. */ + if (packed) + return packed; + /* If the alignment of the record is specified and the field type is over-aligned, request Storage_Unit alignment for the field. */ - if (packed == -2) - { - if (TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type)) - return -1; - else - return 0; - } + if (TYPE_ALIGN (record_type) + && TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type)) + return -1; + + /* Likewise if the maximum alignment of the record is specified. */ + if (TYPE_MAX_ALIGN (record_type) + && TYPE_ALIGN (field_type) > TYPE_MAX_ALIGN (record_type)) + return -1; - return packed; + return 0; } /* Return a GCC tree for a field corresponding to GNAT_FIELD to be placed in GNU_RECORD_TYPE. - PACKED is 1 if the enclosing record is packed, -1 if the enclosing - record has Component_Alignment of Storage_Unit, -2 if the enclosing - record has a specified alignment. + PACKED is 1 if the enclosing record is packed or -1 if the enclosing + record has Component_Alignment of Storage_Unit. DEFINITION is true if this field is for a record being defined. @@ -6989,9 +6984,8 @@ typedef struct vinfo GNU_FIELD_LIST. The other calls to this function are recursive calls for the component list of a variant and, in this case, GNU_FIELD_LIST is empty. - PACKED is 1 if this is for a packed record, -1 if this is for a record - with Component_Alignment of Storage_Unit, -2 if this is for a record - with a specified alignment. + PACKED is 1 if this is for a packed record or -1 if this is for a record + with Component_Alignment of Storage_Unit. DEFINITION is true if we are defining this record type. diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 0016a3fa288..f236907fc2b 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -1694,7 +1694,8 @@ finish_record_type (tree record_type, tree field_list, int rep_level, /* The enclosing record type must be sufficiently aligned. Otherwise, if no alignment was specified for it and it has been laid out already, bump its alignment to the - desired one if this is compatible with its size. */ + desired one if this is compatible with its size and + maximum alignment, if any. */ if (TYPE_ALIGN (record_type) >= align) { DECL_ALIGN (field) = MAX (DECL_ALIGN (field), align); @@ -1702,7 +1703,9 @@ finish_record_type (tree record_type, tree field_list, int rep_level, } else if (!had_align && rep_level == 0 - && value_factor_p (TYPE_SIZE (record_type), align)) + && value_factor_p (TYPE_SIZE (record_type), align) + && (!TYPE_MAX_ALIGN (record_type) + || TYPE_MAX_ALIGN (record_type) >= align)) { TYPE_ALIGN (record_type) = align; DECL_ALIGN (field) = MAX (DECL_ALIGN (field), align); @@ -1800,6 +1803,9 @@ finish_record_type (tree record_type, tree field_list, int rep_level, } } + /* Reset the TYPE_MAX_ALIGN field since it's private to gigi. */ + TYPE_MAX_ALIGN (record_type) = 0; + if (debug_info_p) rest_of_record_type_compilation (record_type); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 23da95f08e8..e7a3058c4b4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-11-30 Eric Botcazou + + * gnat.dg/specs/rep_clause5.ads: New test. + 2015-11-29 Jan Hubicka PR c/67106 diff --git a/gcc/testsuite/gnat.dg/specs/rep_clause5.ads b/gcc/testsuite/gnat.dg/specs/rep_clause5.ads new file mode 100644 index 00000000000..ffac17b3c29 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/rep_clause5.ads @@ -0,0 +1,75 @@ +-- { dg-do compile } + +pragma Implicit_Packing; + +package Rep_Clause5 is + + type Modes_Type is (Mode_0, Mode_1); + for Modes_Type'size use 8; + + type Mode_Record_Type is + record + Mode_1 : aliased Modes_Type; + Mode_2 : aliased Modes_Type; + Mode_3 : aliased Modes_Type; + Mode_4 : aliased Modes_Type; + Time : aliased Float; + end record; + + for Mode_Record_Type use + record + Mode_1 at 00 range 00 .. 07; + Mode_2 at 01 range 00 .. 07; + Mode_3 at 02 range 00 .. 07; + Mode_4 at 03 range 00 .. 07; + Time at 04 range 00 .. 31; + end record; + + for Mode_Record_Type'Size use 64; + for Mode_Record_Type'Alignment use 4; + + type Array_1_Type is array (0 .. 31) of Boolean; + for Array_1_Type'size use 32; + + type Array_2_Type is array (0 .. 127) of Boolean; + for Array_2_Type'size use 128; + + type Array_3_Type is array (0 .. 31) of Boolean; + for Array_3_Type'size use 32; + + type Unsigned_Long is mod 2 ** 32; + type Array_4_Type is array (1 .. 6) of unsigned_Long; + + type Primary_Data_Type is + record + Array_1 : aliased Array_1_Type; + Mode_Record : aliased Mode_Record_Type; + Array_2 : aliased Array_2_Type; + Array_3 : Array_3_Type; + Array_4 : Array_4_Type; + end record; + + for Primary_Data_Type use + record + Array_1 at 0 range 0 .. 31; -- WORD 1 + Mode_Record at 4 range 0 .. 63; -- WORD 2 .. 3 + Array_2 at 12 range 0 .. 127; -- WORD 4 .. 7 + Array_3 at 28 range 0 .. 31; -- WORD 8 + Array_4 at 32 range 0 .. 191; -- WORD 9 .. 14 + end record; + + for Primary_Data_Type'Size use 448; + + type Results_Record_Type is + record + Thirty_Two_Bit_Pad : Float; + Result : Primary_Data_Type; + end record; + + for Results_Record_Type use + record + Thirty_Two_Bit_Pad at 0 range 0 .. 31; + Result at 4 range 0 .. 447; + end record; + +end Rep_Clause5; -- 2.30.2