Commit 29f4754f by Eric Botcazou Committed by Eric Botcazou

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
parent 55d7d0fa
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> 2008-04-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* vms_data.ads: Fix typo in constant. * vms_data.ads: Fix typo in constant.
...@@ -243,13 +243,13 @@ struct lang_type GTY(()) {tree t; }; ...@@ -243,13 +243,13 @@ struct lang_type GTY(()) {tree t; };
is needed to access the object. */ is needed to access the object. */
#define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE) #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. */ /* 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)) #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. */ /* Nonzero in a FUNCTION_DECL that corresponds to an elaboration procedure. */
#define DECL_ELABORATION_PROC_P(NODE) \ #define DECL_ELABORATION_PROC_P(NODE) \
DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (NODE)) DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (NODE))
......
...@@ -516,6 +516,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -516,6 +516,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
bool mutable_p = false; bool mutable_p = false;
tree gnu_ext_name = NULL_TREE; tree gnu_ext_name = NULL_TREE;
tree renamed_obj = NULL_TREE; tree renamed_obj = NULL_TREE;
tree gnu_object_size;
if (Present (Renamed_Object (gnat_entity)) && !definition) if (Present (Renamed_Object (gnat_entity)) && !definition)
{ {
...@@ -771,9 +772,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -771,9 +772,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
align = MINIMUM_ATOMIC_ALIGNMENT; align = MINIMUM_ATOMIC_ALIGNMENT;
#endif #endif
/* Make a new type with the desired size and alignment, if needed. */ /* Make a new type with the desired size and alignment, if needed.
gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity, But do not take into account alignment promotions to compute the
"PAD", false, definition, true); 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 /* Make a volatile version of this object's type if we are to make
the object volatile. We also interpret 13.3(19) conservatively 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) ...@@ -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)) if (!used_by_ref && Unknown_Esize (gnat_entity))
{ {
tree gnu_back_size;
if (TREE_CODE (gnu_type) == RECORD_TYPE if (TREE_CODE (gnu_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_type)) && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
gnu_back_size gnu_object_size
= TYPE_SIZE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_type)))); = 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; break;
...@@ -4237,8 +4239,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -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, /* 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 the name of the new type may be changed. So get it back for
us when we make the new TYPE_DECL below. */ us when we make the new TYPE_DECL below. */
gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity, "PAD", if (gnu_size || align > 0)
true, definition, false); gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity,
"PAD", true, definition, false);
if (TREE_CODE (gnu_type) == RECORD_TYPE if (TREE_CODE (gnu_type) == RECORD_TYPE
&& TYPE_IS_PADDING_P (gnu_type)) && TYPE_IS_PADDING_P (gnu_type))
{ {
...@@ -5562,19 +5566,18 @@ make_packable_type (tree type, bool in_record) ...@@ -5562,19 +5566,18 @@ make_packable_type (tree type, bool in_record)
DEFINITION is true if this type is being defined. 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 SAME_RM_SIZE is true if the RM_Size of the resulting type is to be set
set to its TYPE_SIZE; otherwise, it's set to the RM_Size of the original to SIZE too; otherwise, it's set to the RM_Size of the original type. */
type. */
tree tree
maybe_pad_type (tree type, tree size, unsigned int align, maybe_pad_type (tree type, tree size, unsigned int align,
Entity_Id gnat_entity, const char *name_trailer, Entity_Id gnat_entity, const char *name_trailer,
bool is_user_type, bool definition, bool same_rm_size) 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); tree orig_size = TYPE_SIZE (type);
unsigned int orig_align = align; unsigned int orig_align = align;
tree record; tree record, field;
tree field;
/* If TYPE is a padded type, see if it agrees with any size and alignment /* 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 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, ...@@ -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. */ /* Do not finalize it until after the auxiliary record is built. */
finish_record_type (record, field, 1, true); finish_record_type (record, field, 1, true);
/* Keep the RM_Size of the padded record as that of the old record /* Set the same size for its RM_size if requested; otherwise reuse
if requested. */ the RM_size of the original type. */
SET_TYPE_ADA_SIZE (record, same_rm_size ? size : rm_size (type)); SET_TYPE_ADA_SIZE (record, same_rm_size ? size : orig_rm_size);
/* Unless debugging information isn't being written for the input type, /* 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 write a record that shows what we are a subtype of and also make a
......
...@@ -996,8 +996,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) ...@@ -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. /* Remove NOPS from gnu_expr and conversions from gnu_prefix.
We only use GNU_EXPR to see if a COMPONENT_REF was involved. */ We only use GNU_EXPR to see if a COMPONENT_REF was involved. */
while (TREE_CODE (gnu_expr) == NOP_EXPR) 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); gnu_prefix = remove_conversions (gnu_prefix, true);
prefix_unused = true; prefix_unused = true;
...@@ -1018,7 +1017,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) ...@@ -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. /* 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 Otherwise, if the prefix is an object, or if 'Object_Size or
'Max_Size_In_Storage_Elements has been specified, the result is the '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. */ type. */
if (TREE_CODE (gnu_prefix) == COMPONENT_REF) if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1)); gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1));
......
...@@ -687,23 +687,38 @@ build_binary_op (enum tree_code op_code, tree result_type, ...@@ -687,23 +687,38 @@ build_binary_op (enum tree_code op_code, tree result_type,
left_type = TREE_TYPE (left_operand); 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 a class-wide type may be involved, force use of the RHS type. */
if ((TREE_CODE (right_type) == RECORD_TYPE if ((TREE_CODE (right_type) == RECORD_TYPE
|| TREE_CODE (right_type) == UNION_TYPE) || TREE_CODE (right_type) == UNION_TYPE)
&& TYPE_ALIGN_OK (right_type)) && TYPE_ALIGN_OK (right_type))
operation_type = 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, /* Ensure everything on the LHS is valid. If we have a field reference,
strip anything that get_inner_reference can handle. Then remove any strip anything that get_inner_reference can handle. Then remove any
conversions between types having the same code and mode. And mark conversions between types having the same code and mode. And mark
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment