aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@google.com>2009-03-10 15:24:46 +0000
committerDiego Novillo <dnovillo@google.com>2009-03-10 15:24:46 +0000
commit50d00be3ce00f27ca6f51c48c684ca8c7490e841 (patch)
tree197efd2fa202804dea7abd3788d8c79890846e93 /gcc
parent59542774f84839cf9bd3c73c03bebd5657aeae28 (diff)
2009-03-10 Diego Novillo <dnovillo@google.com>
Revert: 2009-03-09 Diego Novillo <dnovillo@google.com> * tree.c (free_lang_data_in_type): Remove all variants except the main variant of TYPE. * gimple.c (struct type_pair_d): Define. (type_pair_t): Define. (type_pair_hash): New. (type_pair_eq): New. (lookup_type_pair): New. (gimple_compare_types): Factor out of gimple_types_compatible_p. Compare type sizes, alignment, precision, mode and sign. Compare values for enumeral types. Compare all fields of structures and unions. Fix comparison of TYPE_QUALS. Compare TYPE_IS_SIZETYPE for integer types. (gimple_types_compatible_p): Call gimple_compare_types. (gimple_same_type_p): Remove. Update all callers. * gimple.h (gimple_same_type_p): Remove. 2009-03-10 Diego Novillo <dnovillo@google.com> Revert: 2009-03-09 Simon Baldwin <simonb@google.com> * g++.dg/lto/20090302_0.C: New. * g++.dg/lto/20090302_1.C: New. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lto@144749 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog.lto23
-rw-r--r--gcc/gimple.c368
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/lto-symtab.c4
-rw-r--r--gcc/testsuite/ChangeLog.lto9
-rw-r--r--gcc/testsuite/g++.dg/lto/20090302_0.C9
-rw-r--r--gcc/testsuite/g++.dg/lto/20090302_1.C7
-rw-r--r--gcc/tree.c27
8 files changed, 171 insertions, 277 deletions
diff --git a/gcc/ChangeLog.lto b/gcc/ChangeLog.lto
index 92e29d69fd5..10fc8afdef3 100644
--- a/gcc/ChangeLog.lto
+++ b/gcc/ChangeLog.lto
@@ -1,3 +1,26 @@
+2009-03-10 Diego Novillo <dnovillo@google.com>
+
+ Revert:
+
+ 2009-03-09 Diego Novillo <dnovillo@google.com>
+
+ * tree.c (free_lang_data_in_type): Remove all variants
+ except the main variant of TYPE.
+ * gimple.c (struct type_pair_d): Define.
+ (type_pair_t): Define.
+ (type_pair_hash): New.
+ (type_pair_eq): New.
+ (lookup_type_pair): New.
+ (gimple_compare_types): Factor out of gimple_types_compatible_p.
+ Compare type sizes, alignment, precision, mode and sign.
+ Compare values for enumeral types.
+ Compare all fields of structures and unions.
+ Fix comparison of TYPE_QUALS.
+ Compare TYPE_IS_SIZETYPE for integer types.
+ (gimple_types_compatible_p): Call gimple_compare_types.
+ (gimple_same_type_p): Remove. Update all callers.
+ * gimple.h (gimple_same_type_p): Remove.
+
2009-03-10 Simon Baldwin <simonb@google.com>
* lto-opts.c (lto_read_file_options): Corrected function comment.
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 0a5563537e7..e28a7fdd374 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3193,169 +3193,102 @@ gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip)
}
-/* Structure used to maintain a cache of some type pairs compared by
- gimple_compare_types when comparing aggregate types. There are
- four possible values for SAME_P:
-
- -2: The pair (T1, T2) has just been inserted in the table.
- -1: The pair (T1, T2) is currently being compared.
- 0: T1 and T2 are different types.
- 1: T1 and T2 are the same type.
-
- This table is only used when comparing aggregate types to avoid
- infinite recursion due to self-referential types. */
-struct type_pair_d
-{
- tree t1;
- tree t2;
- int same_p;
-};
-typedef struct type_pair_d *type_pair_t;
-
-/* Return a hash value for the type pair pointed-to by P. */
-
-static hashval_t
-type_pair_hash (const void *p)
-{
- const struct type_pair_d *pair = (const struct type_pair_d *) p;
- hashval_t val = iterative_hash_hashval_t (htab_hash_pointer (pair->t1), 0);
- return iterative_hash_hashval_t (htab_hash_pointer (pair->t2), val);
-}
-
-/* Compare two type pairs pointed-to by P1 and P2. */
+/* Return 1 if TYPE1 and TYPE2 are structurally compatible. */
-static int
-type_pair_eq (const void *p1, const void *p2)
+int
+gimple_types_compatible_p (tree type1, tree type2)
{
- const struct type_pair_d *pair1 = (const struct type_pair_d *) p1;
- const struct type_pair_d *pair2 = (const struct type_pair_d *) p2;
- return (pair1->t1 == pair2->t1 && pair1->t2 == pair2->t2);
-}
-
+ /* Types are trivially compatible with themselves. */
+ if (type1 == type2)
+ return 1;
-/* Lookup the pair of types T1 and T2 in *VISITED_P. Insert a new
- entry if none existed. */
+ /* Only types with the same code can be compatible. */
+ if (TREE_CODE (type1) != TREE_CODE (type2))
+ return 0;
-static type_pair_t
-lookup_type_pair (tree t1, tree t2, htab_t *visited_p)
-{
- struct type_pair_d pair;
- type_pair_t p;
- void **slot;
+ /* If the main variants or their canonical type are the same, then
+ they are compatible. */
+ if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)
+ || TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
+ return 1;
- if (*visited_p == NULL)
- *visited_p = htab_create (13, type_pair_hash, type_pair_eq, free);
+ /* In the case of aggregates, check structural equality. Note that
+ at this point, TYPE1 and TYPE2 are guaranteed to have the same
+ code already. */
+ if (TREE_CODE (type1) == RECORD_TYPE
+ || TREE_CODE (type1) == UNION_TYPE
+ || TREE_CODE (type1) == QUAL_UNION_TYPE)
+ {
+ tree f1, f2;
- pair.t1 = t1;
- pair.t2 = t2;
- pair.same_p = -2;
- slot = htab_find_slot (*visited_p, &pair, INSERT);
+ for (f1 = TYPE_FIELDS (type1), f2 = TYPE_FIELDS (type2);
+ f1 && f2;
+ f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
+ if (!gimple_types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+ return 0;
- if (*slot)
- p = *((type_pair_t *) slot);
- else
- {
- p = XCNEW (struct type_pair_d);
- p->t1 = t1;
- p->t2 = t2;
- p->same_p = -2;
- *slot = (void *) p;
+ /* If one aggregate is bigger than the other, then they are not
+ compatible. */
+ return f1 || f2 ? 0 : 1;
}
- return p;
+ /* In any other case, the two types are not compatible. */
+ return 0;
}
-/* Recursive helper for gimple_types_compatible_p. Return 1 iff T1
- and T2 are structurally identical. Otherwise, return 0.
- VISITED_P points to a hash table of type pairs that have been
- visited while comparing aggregate types. This prevents infinite
- recursion when comparing aggregates with self-referential fields. */
+/* Returns true iff T1 and T2 are the same type. */
-static int
-gimple_compare_types (tree t1, tree t2, htab_t *visited_p)
+bool
+gimple_same_type_p (tree t1, tree t2)
{
/* Check first for the obvious case of pointer identity. */
if (t1 == t2)
- return 1;
+ return true;
/* Check that we have two types to compare. */
if (t1 == NULL_TREE || t2 == NULL_TREE)
- return 0;
+ return false;
/* Can't be the same type if the types don't have the same code. */
if (TREE_CODE (t1) != TREE_CODE (t2))
- return 0;
-
- /* Void types are always the same. */
- if (TREE_CODE (t1) == VOID_TYPE)
- return 1;
-
- /* Can't be the same type if they have different size, alignment,
- sign, precision or mode. Note that from now on, comparisons
- between *_CST nodes must be done using tree_int_cst_equal because
- we cannot assume that constants from T1 and T2 will be shared
- since T1 and T2 are distinct pointers. */
- if (!tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
- || !tree_int_cst_equal (TYPE_SIZE_UNIT (t1), TYPE_SIZE_UNIT (t2))
- || TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
- || TYPE_PRECISION (t1) != TYPE_PRECISION (t2)
- || TYPE_MODE (t1) != TYPE_MODE (t2)
- || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
- return 0;
+ return false;
/* Can't be the same type if they have different CV qualifiers. */
- if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
- return 0;
+ if (TYPE_QUALS (t1) != TYPE_QUALS (t1))
+ return false;
/* If their attributes are not the same they can't be the same type. */
if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2)))
- return 0;
-
- /* For numerical types, the bounds must coincide. */
- if (INTEGRAL_TYPE_P (t1)
- || SCALAR_FLOAT_TYPE_P (t1)
- || FIXED_POINT_TYPE_P (t1))
- {
- /* If either type has a minimum value, the other type must have
- the same. */
- if (TYPE_MIN_VALUE (t1) && TYPE_MIN_VALUE (t2))
- {
- if (!tree_int_cst_equal (TYPE_MIN_VALUE (t1), TYPE_MIN_VALUE (t2)))
- return 0;
- }
- else if (TYPE_MIN_VALUE (t1) || TYPE_MIN_VALUE (t2))
- return 0;
-
- /* Likewise, if either type has a maximum value, the other type
- must have the same. */
- if (TYPE_MAX_VALUE (t1) && TYPE_MAX_VALUE (t2))
- {
- if (!tree_int_cst_equal (TYPE_MAX_VALUE (t1), TYPE_MAX_VALUE (t2)))
- return 0;
- }
- else if (TYPE_MAX_VALUE (t1) || TYPE_MAX_VALUE (t2))
- return 0;
- }
+ return false;
- /* Do type-specific comparisons. */
switch (TREE_CODE (t1))
{
+ case VOID_TYPE:
+ /* Void types are the same in all translation units. */
+ return true;
+
case INTEGER_TYPE:
case BOOLEAN_TYPE:
- return (TYPE_IS_SIZETYPE (t1) == TYPE_IS_SIZETYPE (t2)
+ /* Corresponding integral types are the same. */
+ return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
+ && TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2)
+ && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
+ && TYPE_ALIGN (t1) == TYPE_ALIGN (t2)
&& TYPE_STRING_FLAG (t1) == TYPE_STRING_FLAG (t2));
case REAL_TYPE:
- /* We've checked every other important attribute already. */
- return 1;
+ /* Corresponding float types are the same. */
+ return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
+ && tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
+ && TYPE_ALIGN (t1) == TYPE_ALIGN (t2));
case ARRAY_TYPE:
/* Array types are the same if the element types are the same and
the number of elements are the same. */
- if (!gimple_compare_types (TREE_TYPE (t1), TREE_TYPE (t2), visited_p)
+ if (!gimple_same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
|| TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))
- return 0;
+ return false;
else
{
tree i1 = TYPE_DOMAIN (t1);
@@ -3373,19 +3306,20 @@ gimple_compare_types (tree t1, tree t2, htab_t *visited_p)
tree max2 = TYPE_MAX_VALUE (i2);
/* If the array types both have unspecified bounds, then
- MAX{1,2} will be NULL_TREE. */
+ MAX_{1,2} will be NULL_TREE. */
if (min1 && min2 && !max1 && !max2)
- return (integer_zerop (min1) && integer_zerop (min2));
+ return (integer_zerop (min1)
+ && integer_zerop (min2));
/* Otherwise, we need the bounds to be fully
specified. */
if (!min1 || !min2 || !max1 || !max2)
- return 0;
+ return false;
else if (TREE_CODE (min1) != INTEGER_CST
- || TREE_CODE (min2) != INTEGER_CST
- || TREE_CODE (max1) != INTEGER_CST
- || TREE_CODE (max2) != INTEGER_CST)
- return 0;
+ || TREE_CODE (min2) != INTEGER_CST
+ || TREE_CODE (max1) != INTEGER_CST
+ || TREE_CODE (max2) != INTEGER_CST)
+ return false;
else if (tree_int_cst_equal (min1, min2))
return tree_int_cst_equal (max1, max2);
else
@@ -3394,11 +3328,11 @@ gimple_compare_types (tree t1, tree t2, htab_t *visited_p)
tree nelts2 = array_type_nelts (t2);
if (!nelts1 || !nelts2)
- return 0;
+ return false;
if (TREE_CODE (nelts1) != INTEGER_CST
|| TREE_CODE (nelts2) != INTEGER_CST)
- return 0;
+ return false;
return tree_int_cst_equal (nelts1, nelts2);
}
@@ -3408,22 +3342,21 @@ gimple_compare_types (tree t1, tree t2, htab_t *visited_p)
case FUNCTION_TYPE:
/* Function types are the same if the return type and arguments types
are the same. */
- if (!gimple_compare_types (TREE_TYPE (t1), TREE_TYPE (t2), visited_p))
- return 0;
+ if (!gimple_same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
else
{
tree parms1 = TYPE_ARG_TYPES (t1);
tree parms2 = TYPE_ARG_TYPES (t2);
if (parms1 == parms2)
- return 1;
+ return true;
else
{
while (parms1 && parms2)
{
- if (!gimple_compare_types (TREE_VALUE (parms1),
- TREE_VALUE (parms2),
- visited_p))
- return 0;
+ if (!gimple_same_type_p (TREE_VALUE (parms1),
+ TREE_VALUE (parms2)))
+ return false;
parms1 = TREE_CHAIN (parms1);
parms2 = TREE_CHAIN (parms2);
}
@@ -3433,130 +3366,61 @@ gimple_compare_types (tree t1, tree t2, htab_t *visited_p)
case POINTER_TYPE:
case REFERENCE_TYPE:
- {
- /* If the two pointers have different ref-all attributes,
- they can't be the same type. */
- if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
- return 0;
-
- /* Otherwise, pointer and reference types are the same if the
- pointed-to types are the same. */
- return gimple_compare_types (TREE_TYPE (t1), TREE_TYPE (t2),
- visited_p);
- }
+ /* Pointer and reference types are the same if the pointed-to types are
+ the same. */
+ return gimple_same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
case ENUMERAL_TYPE:
- {
- /* For enumeral types, all the values must be the same. */
- tree v1, v2;
-
- for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2);
- v1 && v2;
- v1 = TREE_CHAIN (v1), v2 = TREE_CHAIN (v2))
- {
- tree c1 = TREE_VALUE (v1);
- tree c2 = TREE_VALUE (v2);
-
- if (TREE_CODE (c1) == CONST_DECL)
- c1 = DECL_INITIAL (c1);
-
- if (TREE_CODE (c2) == CONST_DECL)
- c2 = DECL_INITIAL (c2);
-
- if (tree_int_cst_equal (c1, c2) != 1)
- return 0;
- }
-
- /* If one enumeration has more values than the other, they
- are not the same. */
- return v1 || v2 ? 0 : 1;
- }
-
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- {
- /* For aggregate types, all the fields must be the same.
- Use *VISITED_P to mark pairs of fields visited to
- avoid infinite loops due to self-referential types. */
- tree f1, f2;
- type_pair_t p;
-
- p = lookup_type_pair (t1, t2, visited_p);
- if (p->same_p == 0 || p->same_p == 1)
- {
- /* We have already decided whether T1 and T2 are the
- same, return the cached result. */
- return p->same_p == 1;
- }
- else if (p->same_p == -1)
- {
- /* We are currently comparing this pair of types, assume
- that they are the same and let the caller decide. */
- return 1;
- }
-
- gcc_assert (p->same_p == -2);
+ /* Enumeration and class types are the same if they have the same
+ name. */
+ {
+ tree variant1 = TYPE_MAIN_VARIANT (t1);
+ tree variant2 = TYPE_MAIN_VARIANT (t2);
+ tree name1 = TYPE_NAME (t1);
+ tree name2 = TYPE_NAME (t2);
+ if (!name1 || !name2)
+ /* Presumably, anonymous types are all unique. */
+ return false;
+
+ if (TREE_CODE (name1) == TYPE_DECL)
+ {
+ name1 = DECL_NAME (name1);
+ if (!name1)
+ return false;
+ }
+ gcc_assert (TREE_CODE (name1) == IDENTIFIER_NODE);
- /* Mark the (T1, T2) comparison in progress. */
- p->same_p = -1;
+ if (TREE_CODE (name2) == TYPE_DECL)
+ {
+ name2 = DECL_NAME (name2);
+ if (!name2)
+ return false;
+ }
+ gcc_assert (TREE_CODE (name2) == IDENTIFIER_NODE);
- for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2);
- f1 && f2;
- f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
- {
- /* The fields must have the same name, offset and type. */
- if (DECL_NAME (f1) != DECL_NAME (f2)
- || !tree_int_cst_equal (DECL_FIELD_OFFSET (f1),
- DECL_FIELD_OFFSET (f2))
- || !gimple_compare_types (TREE_TYPE (f1),
- TREE_TYPE (f2),
- visited_p))
- {
- p->same_p = 0;
- return 0;
- }
- }
+ /* Identifiers can be compared with pointer equality rather
+ than a string comparison. */
+ if (name1 == name2)
+ return true;
- if (f1 == NULL && f2 == NULL)
- {
- /* If we reached the end of both aggregates, T1 and T2
- are the same. */
- p->same_p = 1;
- return 1;
- }
- else
- {
- /* Otherwise, they are different. */
- p->same_p = 0;
- return 0;
- }
- }
+ /* If either type has a variant type, compare that. This finds
+ the case where a struct is typedef'ed in one module but referred
+ to as 'struct foo' in the other; here, the main type for one is
+ 'foo', and for the other 'foo_t', but the variants have the same
+ name 'foo'. */
+ if (variant1 != t1 || variant2 != t2)
+ return gimple_same_type_p (variant1, variant2);
+ else
+ return false;
+ }
+ /* FIXME: add pointer to member types. */
default:
- break;
+ return false;
}
-
- /* The types are different. */
- return 0;
}
-
-/* Return 1 iff T1 and T2 are the structurally identical. Otherwise,
- return 0. */
-
-int
-gimple_types_compatible_p (tree t1, tree t2)
-{
- int same_p;
- htab_t visited = NULL;
-
- same_p = gimple_compare_types (t1, t2, &visited);
-
- if (visited)
- htab_delete (visited);
-
- return same_p;
-}
-
#include "gt-gimple.h"
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 441c00960c2..352e453d7ef 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -916,6 +916,7 @@ extern tree get_call_expr_in (tree t);
extern void recalculate_side_effects (tree);
extern int gimple_types_compatible_p (tree, tree);
+extern bool gimple_same_type_p (tree, tree);
/* In gimplify.c */
extern tree create_tmp_var_raw (tree, const char *);
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index 193e1904077..e35d23d2e4d 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -182,7 +182,7 @@ lto_merge_types (tree type_1, tree type_2)
&& TREE_CODE (type_2) == ARRAY_TYPE
&& !TYPE_ATTRIBUTES (type_1)
&& !TYPE_ATTRIBUTES (type_2)
- && gimple_types_compatible_p (TREE_TYPE (type_1), TREE_TYPE (type_2)))
+ && gimple_same_type_p (TREE_TYPE (type_1), TREE_TYPE (type_2)))
{
lto_merge_qualifiers (type_1, type_2);
@@ -255,7 +255,7 @@ lto_symtab_compatible (tree old_decl, tree new_decl)
}
}
- if (!gimple_types_compatible_p (TREE_TYPE (old_decl), TREE_TYPE (new_decl)))
+ if (!gimple_same_type_p (TREE_TYPE (old_decl), TREE_TYPE (new_decl)))
{
/* Allow an array type with unspecified bounds to
be merged with an array type whose bounds are specified, so
diff --git a/gcc/testsuite/ChangeLog.lto b/gcc/testsuite/ChangeLog.lto
index ba5ffaad8c6..bb5e37f8217 100644
--- a/gcc/testsuite/ChangeLog.lto
+++ b/gcc/testsuite/ChangeLog.lto
@@ -1,3 +1,12 @@
+2009-03-10 Diego Novillo <dnovillo@google.com>
+
+ Revert:
+
+ 2009-03-09 Simon Baldwin <simonb@google.com>
+
+ * g++.dg/lto/20090302_0.C: New.
+ * g++.dg/lto/20090302_1.C: New.
+
2009-03-10 Rafael Avila de Espindola <espindola@google.com>
* g++.dg/lto/20090309_0.C: New.
diff --git a/gcc/testsuite/g++.dg/lto/20090302_0.C b/gcc/testsuite/g++.dg/lto/20090302_0.C
deleted file mode 100644
index be754271bf7..00000000000
--- a/gcc/testsuite/g++.dg/lto/20090302_0.C
+++ /dev/null
@@ -1,9 +0,0 @@
-/* { dg-do "link" } */
-/* { dg-options "{-fPIC -fwhopr -shared}" } */
-struct Foo {
- bool Mumble();
- static void Bar() { if (foo_->Mumble()) foo_ = 0; }
- static void Baz() { Bar(); }
- static Foo *foo_;
-};
-void Unused() { Foo::Bar(); Foo::Baz(); }
diff --git a/gcc/testsuite/g++.dg/lto/20090302_1.C b/gcc/testsuite/g++.dg/lto/20090302_1.C
deleted file mode 100644
index 0ccaf3c8205..00000000000
--- a/gcc/testsuite/g++.dg/lto/20090302_1.C
+++ /dev/null
@@ -1,7 +0,0 @@
-struct Foo {
- bool Mumble();
- static void Bar() { if (foo_->Mumble()) foo_ = 0; }
- static void Baz() { Bar(); }
- static Foo *foo_;
-};
-Foo *Foo::foo_;
diff --git a/gcc/tree.c b/gcc/tree.c
index a04af015e6e..8e94d0c0a2b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3895,13 +3895,26 @@ free_lang_data_in_type (tree type)
FIXME lto: This will break debug info generation. */
TYPE_CONTEXT (type) = NULL_TREE;
- /* Remove type variants other than the main variant. This is both
- wasteful and it may introduce infinite loops when the types are
- read from disk and merged (since the variant will be the same
- type as the main variant, traversing type variants will get into
- an infinite loop). */
- if (TYPE_MAIN_VARIANT (type))
- TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (type)) = NULL_TREE;
+ /* Remove type variants that are the same gimple type as the main
+ variant. This is both wasteful and it may introduce infinite
+ loops when the types are read from disk (since the variant will
+ be the same type as the main variant, traversing type variants
+ will get into an infinite loop). */
+ if (TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (type)))
+ {
+ tree main_variant = TYPE_MAIN_VARIANT (type);
+ tree *tp = &TYPE_NEXT_VARIANT (main_variant);
+
+ while (*tp)
+ {
+ /* If *TP is the same GIMPLE type as MAIN_VARIANT, then it's
+ not necessary to have it in the list of variants. */
+ if (gimple_same_type_p (*tp, main_variant))
+ *tp = TYPE_NEXT_VARIANT (*tp);
+ else
+ tp = &TYPE_NEXT_VARIANT (*tp);
+ }
+ }
}