From: Eric Botcazou Date: Tue, 15 Apr 2008 07:18:21 +0000 (+0000) Subject: ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=29f4754ff005a8b53f2f4341093bf1e800aad4ce;p=gcc.git ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3. * ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3. * decl.c (gnat_to_gnu_entity) : Call maybe_pad_type only if a size or alignment is specified. Do not take into account alignment promotions for the computation of the object's size. : Call maybe_pad_type only if a size or alignment is specified. (maybe_pad_type): Really reuse the RM_Size of the original type if requested. * trans.c (Attribute_to_gnu): Fix a couple of nits. * utils2.c (build_binary_op) : Merge related conditional statements. Use the padded view of the type when copying between padded objects of the same underlying type. From-SVN: r134310 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index abb4fadfde7..d00479bb926 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,17 @@ +2008-04-15 Eric Botcazou + + * ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3. + * decl.c (gnat_to_gnu_entity) : Call maybe_pad_type only + if a size or alignment is specified. Do not take into account + alignment promotions for the computation of the object's size. + : Call maybe_pad_type only if a size or alignment is specified. + (maybe_pad_type): Really reuse the RM_Size of the original type if + requested. + * trans.c (Attribute_to_gnu): Fix a couple of nits. + * utils2.c (build_binary_op) : Merge related conditional + statements. Use the padded view of the type when copying between + padded objects of the same underlying type. + 2008-04-14 Ralf Wildenhues * vms_data.ads: Fix typo in constant. diff --git a/gcc/ada/ada-tree.h b/gcc/ada/ada-tree.h index b38c34da573..6c60adfbfa4 100644 --- a/gcc/ada/ada-tree.h +++ b/gcc/ada/ada-tree.h @@ -243,13 +243,13 @@ struct lang_type GTY(()) {tree t; }; is needed to access the object. */ #define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE) -/* Nonzero if this decl is a PARM_DECL for an Ada array being passed to a - foreign convention subprogram. */ -#define DECL_BY_COMPONENT_PTR_P(NODE) DECL_LANG_FLAG_2 (PARM_DECL_CHECK (NODE)) - /* Nonzero in a FIELD_DECL that is a dummy built for some internal reason. */ #define DECL_INTERNAL_P(NODE) DECL_LANG_FLAG_3 (FIELD_DECL_CHECK (NODE)) +/* Nonzero if this decl is a PARM_DECL for an Ada array being passed to a + foreign convention subprogram. */ +#define DECL_BY_COMPONENT_PTR_P(NODE) DECL_LANG_FLAG_3 (PARM_DECL_CHECK (NODE)) + /* Nonzero in a FUNCTION_DECL that corresponds to an elaboration procedure. */ #define DECL_ELABORATION_PROC_P(NODE) \ DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (NODE)) diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index eabc9211e19..2b2ec684668 100644 --- a/gcc/ada/decl.c +++ b/gcc/ada/decl.c @@ -516,6 +516,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) bool mutable_p = false; tree gnu_ext_name = NULL_TREE; tree renamed_obj = NULL_TREE; + tree gnu_object_size; if (Present (Renamed_Object (gnat_entity)) && !definition) { @@ -771,9 +772,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) align = MINIMUM_ATOMIC_ALIGNMENT; #endif - /* Make a new type with the desired size and alignment, if needed. */ - gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity, - "PAD", false, definition, true); + /* Make a new type with the desired size and alignment, if needed. + But do not take into account alignment promotions to compute the + size of the object. */ + gnu_object_size = gnu_size ? gnu_size : TYPE_SIZE (gnu_type); + if (gnu_size || align > 0) + gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity, + "PAD", false, definition, + gnu_size ? true : false); /* Make a volatile version of this object's type if we are to make the object volatile. We also interpret 13.3(19) conservatively @@ -1290,16 +1296,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if (!used_by_ref && Unknown_Esize (gnat_entity)) { - tree gnu_back_size; - if (TREE_CODE (gnu_type) == RECORD_TYPE && TYPE_CONTAINS_TEMPLATE_P (gnu_type)) - gnu_back_size + gnu_object_size = TYPE_SIZE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_type)))); - else - gnu_back_size = TYPE_SIZE (gnu_type); - Set_Esize (gnat_entity, annotate_value (gnu_back_size)); + Set_Esize (gnat_entity, annotate_value (gnu_object_size)); } } break; @@ -4237,8 +4239,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* See if we need to pad the type. If we did, and made a record, the name of the new type may be changed. So get it back for us when we make the new TYPE_DECL below. */ - gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity, "PAD", - true, definition, false); + if (gnu_size || align > 0) + gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity, + "PAD", true, definition, false); + if (TREE_CODE (gnu_type) == RECORD_TYPE && TYPE_IS_PADDING_P (gnu_type)) { @@ -5562,19 +5566,18 @@ make_packable_type (tree type, bool in_record) DEFINITION is true if this type is being defined. - SAME_RM_SIZE is true if the RM_Size of the resulting type is to be - set to its TYPE_SIZE; otherwise, it's set to the RM_Size of the original - type. */ + SAME_RM_SIZE is true if the RM_Size of the resulting type is to be set + to SIZE too; otherwise, it's set to the RM_Size of the original type. */ tree maybe_pad_type (tree type, tree size, unsigned int align, Entity_Id gnat_entity, const char *name_trailer, bool is_user_type, bool definition, bool same_rm_size) { + tree orig_rm_size = same_rm_size ? NULL_TREE : rm_size (type); tree orig_size = TYPE_SIZE (type); unsigned int orig_align = align; - tree record; - tree field; + tree record, field; /* If TYPE is a padded type, see if it agrees with any size and alignment we were given. If so, return the original type. Otherwise, strip @@ -5673,9 +5676,9 @@ maybe_pad_type (tree type, tree size, unsigned int align, /* Do not finalize it until after the auxiliary record is built. */ finish_record_type (record, field, 1, true); - /* Keep the RM_Size of the padded record as that of the old record - if requested. */ - SET_TYPE_ADA_SIZE (record, same_rm_size ? size : rm_size (type)); + /* Set the same size for its RM_size if requested; otherwise reuse + the RM_size of the original type. */ + SET_TYPE_ADA_SIZE (record, same_rm_size ? size : orig_rm_size); /* Unless debugging information isn't being written for the input type, write a record that shows what we are a subtype of and also make a diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c index b00f5c3af05..300ac780f20 100644 --- a/gcc/ada/trans.c +++ b/gcc/ada/trans.c @@ -996,8 +996,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) /* Remove NOPS from gnu_expr and conversions from gnu_prefix. We only use GNU_EXPR to see if a COMPONENT_REF was involved. */ while (TREE_CODE (gnu_expr) == NOP_EXPR) - gnu_expr = TREE_OPERAND (gnu_expr, 0) - ; + gnu_expr = TREE_OPERAND (gnu_expr, 0); gnu_prefix = remove_conversions (gnu_prefix, true); prefix_unused = true; @@ -1018,7 +1017,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) /* If we're looking for the size of a field, return the field size. Otherwise, if the prefix is an object, or if 'Object_Size or 'Max_Size_In_Storage_Elements has been specified, the result is the - GCC size of the type. Otherwise, the result is the RM_Size of the + GCC size of the type. Otherwise, the result is the RM_Size of the type. */ if (TREE_CODE (gnu_prefix) == COMPONENT_REF) gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1)); diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c index 3c6cb0074eb..5888bc583c4 100644 --- a/gcc/ada/utils2.c +++ b/gcc/ada/utils2.c @@ -687,23 +687,38 @@ build_binary_op (enum tree_code op_code, tree result_type, left_type = TREE_TYPE (left_operand); } - if (!operation_type) - operation_type = left_type; - - /* Find the best type to use for copying between aggregate types. */ - if (((TREE_CODE (left_type) == ARRAY_TYPE - && TREE_CODE (right_type) == ARRAY_TYPE) - || (TREE_CODE (left_type) == RECORD_TYPE - && TREE_CODE (right_type) == RECORD_TYPE)) - && (best_type = find_common_type (left_type, right_type))) - operation_type = best_type; - /* If a class-wide type may be involved, force use of the RHS type. */ if ((TREE_CODE (right_type) == RECORD_TYPE || TREE_CODE (right_type) == UNION_TYPE) && TYPE_ALIGN_OK (right_type)) operation_type = right_type; + /* If we are copying between padded objects of the same underlying + type with a non-zero size, use the padded view of the type, this + is very likely more efficient. */ + else if (TREE_CODE (left_type) == RECORD_TYPE + && TYPE_IS_PADDING_P (left_type) + && TREE_TYPE (TYPE_FIELDS (left_type)) == right_type + && !integer_zerop (TYPE_SIZE (right_type)) + && TREE_CODE (right_operand) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (right_operand, 0))) + == RECORD_TYPE + && TYPE_IS_PADDING_P + (TREE_TYPE (TREE_OPERAND (right_operand, 0)))) + operation_type = left_type; + + /* Find the best type to use for copying between aggregate types. */ + else if (((TREE_CODE (left_type) == ARRAY_TYPE + && TREE_CODE (right_type) == ARRAY_TYPE) + || (TREE_CODE (left_type) == RECORD_TYPE + && TREE_CODE (right_type) == RECORD_TYPE)) + && (best_type = find_common_type (left_type, right_type))) + operation_type = best_type; + + /* Otherwise use the LHS type. */ + else if (!operation_type) + operation_type = left_type; + /* Ensure everything on the LHS is valid. If we have a field reference, strip anything that get_inner_reference can handle. Then remove any conversions between types having the same code and mode. And mark