ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3.
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 15 Apr 2008 07:18:21 +0000 (07:18 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 15 Apr 2008 07:18:21 +0000 (07:18 +0000)
* ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3.
* decl.c (gnat_to_gnu_entity) <object>: 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.
<type>: 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) <MODIFY_EXPR>: Merge related conditional
statements.  Use the padded view of the type when copying between
padded objects of the same underlying type.

From-SVN: r134310

gcc/ada/ChangeLog
gcc/ada/ada-tree.h
gcc/ada/decl.c
gcc/ada/trans.c
gcc/ada/utils2.c

index abb4fadfde722b9018086480c4c08ecf8cd40202..d00479bb92619c5cd8d1a4c6babe8bb94723f896 100644 (file)
@@ -1,3 +1,17 @@
+2008-04-15  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * ada-tree.h (DECL_BY_COMPONENT_PTR_P): Use DECL_LANG_FLAG_3.
+       * decl.c (gnat_to_gnu_entity) <object>: 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.
+       <type>: 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) <MODIFY_EXPR>: 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  <Ralf.Wildenhues@gmx.de>
 
        * vms_data.ads: Fix typo in constant.
index b38c34da5730bfebc997ae71b63c7fd484f07586..6c60adfbfa4acee3f32571e320829894d8ef9d2d 100644 (file)
@@ -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))
index eabc9211e19611a6f12848cffc66f76d826060c8..2b2ec684668363bface036c6342e31e11208a48c 100644 (file)
@@ -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
index b00f5c3af05260115eb5df4de01e3df006c5972d..300ac780f200ab211af54208764a41d0f172fb13 100644 (file)
@@ -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));
index 3c6cb0074ebeb7ff8cdc8f51a5f46ce306ed39b3..5888bc583c47ad3b4f26edb0b0c21ad075fedb59 100644 (file)
@@ -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