aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils2.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-04-15 07:18:21 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-04-15 07:18:21 +0000
commit29f4754ff005a8b53f2f4341093bf1e800aad4ce (patch)
tree0c68173537cdf9a84c8102d91ef9ec47541a5d8b /gcc/ada/utils2.c
parent55d7d0fa979fee55901c9ed8a65fd59461b70840 (diff)
downloadgcc-29f4754ff005a8b53f2f4341093bf1e800aad4ce.zip
gcc-29f4754ff005a8b53f2f4341093bf1e800aad4ce.tar.gz
gcc-29f4754ff005a8b53f2f4341093bf1e800aad4ce.tar.bz2
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) <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
Diffstat (limited to 'gcc/ada/utils2.c')
-rw-r--r--gcc/ada/utils2.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index 3c6cb00..5888bc5 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