From 09eb10edf9eb3f69a4337a4f4793b6f20feea37e Mon Sep 17 00:00:00 2001 From: rguenth Date: Sun, 13 Jun 2010 14:14:17 +0000 Subject: [PATCH] 2010-06-13 Richard Guenther * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160679 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/config/i386/i386.c | 7 +++---- gcc/gimple.c | 17 ++++++++++------- gcc/lto-streamer-in.c | 3 ++- gcc/lto-streamer-out.c | 3 ++- gcc/lto-streamer.c | 7 ++++++- gcc/lto/ChangeLog | 4 ++++ gcc/lto/lto.c | 6 +++++- gcc/tree.h | 26 +++++++++++++++++--------- 9 files changed, 63 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4543351..7229741 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-06-13 Richard Guenther + + * 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 * config/ia64/ia64.h (FUNCTION_VALUE_REGNO_P, FUNCTION_VALUE, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 1bdc689..657e55a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 diff --git a/gcc/gimple.c b/gcc/gimple.c index b949985..1a10f31 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -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; } diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 0c9f90a..d56cf5d 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -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); } diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index d43de21..e647545 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -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); } diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index a086d91..5b0e774 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -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)) diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 0da0eca..c3618b6 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,7 @@ +2010-06-13 Richard Guenther + + * lto.c (lto_fixup_type): Do not register or fixup TYPE_CANONICAL. + 2010-06-09 Kai Tietz * lto.c (lto_resolution_read): Pre-initialize local variable r. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 740a8b8..d969a10 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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 diff --git a/gcc/tree.h b/gcc/tree.h index 683eaea..bd86f44 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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))) -- 2.7.4