lto-streamer-in.c (lto_input_ts_type_tree_pointers): Do not stream but initialize TYPE_CANONICAL to NULL.

2010-06-13  Richard Guenther  <rguenther@suse.de>

	* lto-streamer-in.c (lto_input_ts_type_tree_pointers):
	Do not stream but initialize TYPE_CANONICAL to NULL.
	(lto_output_ts_type_tree_pointers): Do not stream TYPE_CANONICAL.
	* gimple.c (gimple_types_compatible_p): Disregard
	TYPE_STRUCTURAL_EQUALITY_P.
	(gimple_register_type): Use TYPE_CANONICAL as cache.
	* lto-streamer.c (lto_record_common_node): Zero TYPE_CANONICAL
	before registering common types.
	* config/i386/i386.c (ix86_function_arg_boundary): Do not
	use TYPE_CANONICAL, instead use TYPE_MAIN_VARIANT.
	* tree.h (TYPE_CANONICAL): Clarify documentation.

	lto/
	* lto.c (lto_fixup_type): Do not register or fixup TYPE_CANONICAL.

From-SVN: r160679
This commit is contained in:
Richard Guenther 2010-06-13 14:14:17 +00:00 committed by Richard Biener
parent ba90d83825
commit 4a2ac96fb7
9 changed files with 63 additions and 24 deletions

View File

@ -1,3 +1,17 @@
2010-06-13 Richard Guenther <rguenther@suse.de>
* lto-streamer-in.c (lto_input_ts_type_tree_pointers):
Do not stream but initialize TYPE_CANONICAL to NULL.
(lto_output_ts_type_tree_pointers): Do not stream TYPE_CANONICAL.
* gimple.c (gimple_types_compatible_p): Disregard
TYPE_STRUCTURAL_EQUALITY_P.
(gimple_register_type): Use TYPE_CANONICAL as cache.
* lto-streamer.c (lto_record_common_node): Zero TYPE_CANONICAL
before registering common types.
* config/i386/i386.c (ix86_function_arg_boundary): Do not
use TYPE_CANONICAL, instead use TYPE_MAIN_VARIANT.
* tree.h (TYPE_CANONICAL): Clarify documentation.
2010-06-13 Anatoly Sokolov <aesok@post.ru>
* config/ia64/ia64.h (FUNCTION_VALUE_REGNO_P, FUNCTION_VALUE,

View File

@ -6398,10 +6398,9 @@ ix86_function_arg_boundary (enum machine_mode mode, tree type)
int align;
if (type)
{
/* Since canonical type is used for call, we convert it to
canonical type if needed. */
if (!TYPE_STRUCTURAL_EQUALITY_P (type))
type = TYPE_CANONICAL (type);
/* Since the main variant type is used for call, we convert it to
the main variant type. */
type = TYPE_MAIN_VARIANT (type);
align = TYPE_ALIGN (type);
}
else

View File

@ -3593,12 +3593,6 @@ gimple_types_compatible_p (tree t1, tree t2)
{
tree f1, f2;
/* If one type requires structural equality checks and the
other doesn't, do not merge the types. */
if (TYPE_STRUCTURAL_EQUALITY_P (t1)
!= TYPE_STRUCTURAL_EQUALITY_P (t2))
goto different_types;
/* The struct tags shall compare equal. */
if (!compare_type_names_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2), false))
@ -3955,6 +3949,11 @@ gimple_register_type (tree t)
gcc_assert (TYPE_P (t));
/* In TYPE_CANONICAL we cache the result of gimple_register_type.
It is initially set to NULL during LTO streaming. */
if (TYPE_CANONICAL (t))
return TYPE_CANONICAL (t);
/* Always register the main variant first. This is important so we
pick up the non-typedef variants as canonical, otherwise we'll end
up taking typedef ids for structure tags during comparison. */
@ -4018,10 +4017,14 @@ gimple_register_type (tree t)
TYPE_NEXT_REF_TO (t) = NULL_TREE;
}
TYPE_CANONICAL (t) = new_type;
t = new_type;
}
else
*slot = (void *) t;
{
TYPE_CANONICAL (t) = t;
*slot = (void *) t;
}
return t;
}

View File

@ -2192,7 +2192,8 @@ lto_input_ts_type_tree_pointers (struct lto_input_block *ib,
if (RECORD_OR_UNION_TYPE_P (expr))
TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
TYPE_CANONICAL (expr) = lto_input_tree (ib, data_in);
/* TYPE_CANONICAL gets re-computed during type merging. */
TYPE_CANONICAL (expr) = NULL_TREE;
TYPE_STUB_DECL (expr) = lto_input_tree (ib, data_in);
}

View File

@ -986,7 +986,8 @@ lto_output_ts_type_tree_pointers (struct output_block *ob, tree expr,
if (RECORD_OR_UNION_TYPE_P (expr))
lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CANONICAL (expr), ref_p);
/* TYPE_CANONICAL is re-computed during type merging, so no need
to stream it here. */
lto_output_tree_or_ref (ob, TYPE_STUB_DECL (expr), ref_p);
}

View File

@ -674,7 +674,12 @@ lto_record_common_node (tree *nodep, VEC(tree, heap) **common_nodes,
return;
if (TYPE_P (node))
*nodep = node = gimple_register_type (node);
{
/* Type merging will get confused by the canonical types as they
are set by the middle-end. */
TYPE_CANONICAL (node) = NULL_TREE;
*nodep = node = gimple_register_type (node);
}
/* Return if node is already seen. */
if (pointer_set_insert (seen_nodes, node))

View File

@ -1,3 +1,7 @@
2010-06-13 Richard Guenther <rguenther@suse.de>
* lto.c (lto_fixup_type): Do not register or fixup TYPE_CANONICAL.
2010-06-09 Kai Tietz <kai.tietz@onevision.com>
* lto.c (lto_resolution_read): Pre-initialize local variable r.

View File

@ -1087,7 +1087,11 @@ lto_fixup_type (tree t, void *data)
else
LTO_FIXUP_SUBTREE (TYPE_CONTEXT (t));
}
LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CANONICAL (t));
/* TYPE_CANONICAL does not need to be fixed up, instead it should
always point to ourselves at this time as we never fixup
non-canonical ones. */
gcc_assert (TYPE_CANONICAL (t) == t);
/* The following re-creates proper variant lists while fixing up
the variant leaders. We do not stream TYPE_NEXT_VARIANT so the

View File

@ -2090,26 +2090,34 @@ extern enum machine_mode vector_type_mode (const_tree);
#define SET_TYPE_MODE(NODE, MODE) \
(TYPE_CHECK (NODE)->type.mode = (MODE))
/* The "canonical" type for this type node, which can be used to
compare the type for equality with another type. If two types are
/* The "canonical" type for this type node, which is used by frontends to
compare the type for equality with another type. If two types are
equal (based on the semantics of the language), then they will have
equivalent TYPE_CANONICAL entries.
As a special case, if TYPE_CANONICAL is NULL_TREE, then it cannot
be used for comparison against other types. Instead, the type is
As a special case, if TYPE_CANONICAL is NULL_TREE, and thus
TYPE_STRUCTURAL_EQUALITY_P is true, then it cannot
be used for comparison against other types. Instead, the type is
said to require structural equality checks, described in
TYPE_STRUCTURAL_EQUALITY_P. */
TYPE_STRUCTURAL_EQUALITY_P.
For unqualified aggregate and function types the middle-end relies on
TYPE_CANONICAL to tell whether two variables can be assigned
to each other without a conversion. The middle-end also makes sure
to assign the same alias-sets to the type partition with equal
TYPE_CANONICAL of their unqualified variants. */
#define TYPE_CANONICAL(NODE) (TYPE_CHECK (NODE)->type.canonical)
/* Indicates that the type node requires structural equality
checks. The compiler will need to look at the composition of the
checks. The compiler will need to look at the composition of the
type to determine whether it is equal to another type, rather than
just comparing canonical type pointers. For instance, we would need
just comparing canonical type pointers. For instance, we would need
to look at the return and parameter types of a FUNCTION_TYPE
node. */
node. */
#define TYPE_STRUCTURAL_EQUALITY_P(NODE) (TYPE_CANONICAL (NODE) == NULL_TREE)
/* Sets the TYPE_CANONICAL field to NULL_TREE, indicating that the
type node requires structural equality. */
type node requires structural equality. */
#define SET_TYPE_STRUCTURAL_EQUALITY(NODE) (TYPE_CANONICAL (NODE) = NULL_TREE)
#define TYPE_LANG_SPECIFIC(NODE) (TYPE_CHECK (NODE)->type.lang_specific)
#define TYPE_IBIT(NODE) (GET_MODE_IBIT (TYPE_MODE (NODE)))
#define TYPE_FBIT(NODE) (GET_MODE_FBIT (TYPE_MODE (NODE)))