aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-06-13 14:14:17 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-06-13 14:14:17 +0000
commit4a2ac96fb7e845adc573a3accfafdd534e179156 (patch)
tree35daaa9972d65e4f2ede54da386f2214ce5ac3cb /gcc
parentba90d838257853023abae85f8c393eda41c50189 (diff)
downloadgcc-4a2ac96fb7e845adc573a3accfafdd534e179156.zip
gcc-4a2ac96fb7e845adc573a3accfafdd534e179156.tar.gz
gcc-4a2ac96fb7e845adc573a3accfafdd534e179156.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/i386/i386.c7
-rw-r--r--gcc/gimple.c17
-rw-r--r--gcc/lto-streamer-in.c3
-rw-r--r--gcc/lto-streamer-out.c3
-rw-r--r--gcc/lto-streamer.c7
-rw-r--r--gcc/lto/ChangeLog4
-rw-r--r--gcc/lto/lto.c6
-rw-r--r--gcc/tree.h26
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 <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,
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 <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.
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)))