aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2011-07-24 13:14:17 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-07-24 13:14:17 +0000
commit7d5997c66ce2a2463f8a911f6217c30759f765ce (patch)
tree2f35d4c94eceb2298ff716cc0effe45080b9e450
parent4b4cfdd5e1104810953caefe50729f87e79239ec (diff)
downloadgcc-7d5997c66ce2a2463f8a911f6217c30759f765ce.zip
gcc-7d5997c66ce2a2463f8a911f6217c30759f765ce.tar.gz
gcc-7d5997c66ce2a2463f8a911f6217c30759f765ce.tar.bz2
decl.c (gnat_to_gnu_entity): If the subprogram has copy-in copy-out parameters...
* 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
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/gcc-interface/decl.c55
2 files changed, 50 insertions, 11 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 01ab4e6..d91f54f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,11 @@
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
left operand as addressable.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 1f9083a..99be625 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -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