decl.c (gnat_to_gnu_entity): If the subprogram has copy-in copy-out parameters...
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 24 Jul 2011 13:14:17 +0000 (13:14 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 24 Jul 2011 13:14:17 +0000 (13:14 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>: If the
subprogram has copy-in copy-out parameters, try to promote the mode of
the return type if it is passed in registers.

From-SVN: r176714

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c

index 01ab4e6d8f0c6c405cda436661d84c8c451ba07f..d91f54f98ab5a76b1235d67ce492a5ca5c5dc342 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-24  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>: If the
+       subprogram has copy-in copy-out parameters, try to promote the mode of
+       the return type if it is passed in registers.
+
 2011-07-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/utils2.c (build_binary_op) <ARRAY_REF>: Do not mark the
index 1f9083a454ea4fbe7e731cbba27aba8b0cd41445..99be625ecd15fc57dbc4a0c7d5cb86c262d017fe 100644 (file)
@@ -4245,17 +4245,50 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              }
          }
 
-       /* Do not compute record for out parameters if subprogram is
-          stubbed since structures are incomplete for the back-end.  */
-       if (gnu_field_list && Convention (gnat_entity) != Convention_Stubbed)
-         finish_record_type (gnu_return_type, nreverse (gnu_field_list),
-                             0, debug_info_p);
-
-       /* If we have a CICO list but it has only one entry, we convert
-          this function into a function that simply returns that one
-          object.  */
-       if (list_length (gnu_cico_list) == 1)
-         gnu_return_type = TREE_TYPE (TREE_PURPOSE (gnu_cico_list));
+       if (gnu_cico_list)
+         {
+           /* If we have a CICO list but it has only one entry, we convert
+              this function into a function that returns this object.  */
+           if (list_length (gnu_cico_list) == 1)
+             gnu_return_type = TREE_TYPE (TREE_PURPOSE (gnu_cico_list));
+
+           /* Do not finalize the return type if the subprogram is stubbed
+              since structures are incomplete for the back-end.  */
+           else if (Convention (gnat_entity) != Convention_Stubbed)
+             {
+               finish_record_type (gnu_return_type, nreverse (gnu_field_list),
+                                   0, false);
+
+               /* Try to promote the mode of the return type if it is passed
+                  in registers, again to speed up accesses.  */
+               if (TYPE_MODE (gnu_return_type) == BLKmode
+                   && !targetm.calls.return_in_memory (gnu_return_type,
+                                                       NULL_TREE))
+                 {
+                   unsigned int size
+                     = TREE_INT_CST_LOW (TYPE_SIZE (gnu_return_type));
+                   unsigned int i = BITS_PER_UNIT;
+                   enum machine_mode mode;
+
+                   while (i < size)
+                     i <<= 1;
+                   mode = mode_for_size (i, MODE_INT, 0);
+                   if (mode != BLKmode)
+                     {
+                       SET_TYPE_MODE (gnu_return_type, mode);
+                       TYPE_ALIGN (gnu_return_type)
+                         = GET_MODE_ALIGNMENT (mode);
+                       TYPE_SIZE (gnu_return_type)
+                         = bitsize_int (GET_MODE_BITSIZE (mode));
+                       TYPE_SIZE_UNIT (gnu_return_type)
+                         = size_int (GET_MODE_SIZE (mode));
+                     }
+                 }
+
+               if (debug_info_p)
+                 rest_of_record_type_compilation (gnu_return_type);
+             }
+         }
 
        if (Has_Stdcall_Convention (gnat_entity))
          prepend_one_attribute_to