summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/gimple.c193
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/lto-symtab.c125
4 files changed, 142 insertions, 190 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b85026d3070..ed8d6e3bec6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2009-10-16 Richard Guenther <rguenther@suse.de>
+
+ * lto-symtab.c (merge_incomplete_and_complete_type): Remove.
+ (maybe_merge_incomplete_and_complete_type): Likewise.
+ (lto_symtab_merge): Do not call them. Do not warn for
+ complete vs. incomplete compatible types.
+ (lto_symtab_merge_decls_2): Simplify.
+ * gimple.c (gimple_force_type_merge): Remove.
+ (gimple_types_compatible_p): Make it static.
+ * gimple.h (gimple_force_type_merge): Remove.
+ (gimple_types_compatible_p): Likewise.
+
2009-10-16 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (mem_loc_descriptor) <case ZERO_EXTRACT>: Cast
diff --git a/gcc/gimple.c b/gcc/gimple.c
index fe8f156b463..80c2cf46831 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3090,35 +3090,6 @@ lookup_type_pair (tree t1, tree t2, htab_t *visited_p, struct obstack *ob_p)
}
-/* Force merging the type T2 into the type T1. */
-
-void
-gimple_force_type_merge (tree t1, tree t2)
-{
- void **slot;
- type_pair_t p;
-
- /* There's no other way than copying t2 to t1 in this case.
- Yuck. We'll just call this "completing" t1. */
- memcpy (t1, t2, tree_size (t1));
-
- /* Adjust the hash value of T1 if it was computed already. Otherwise
- we would be forced to not hash fields of structs to match the
- hash value of an incomplete struct. */
- if (type_hash_cache
- && (slot = pointer_map_contains (type_hash_cache, t1)) != NULL)
- {
- gimple_type_hash (t2);
- *slot = *pointer_map_contains (type_hash_cache, t2);
- }
-
- /* Adjust cached comparison results for T1 and T2 to make sure
- they now compare compatible. */
- p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
- p->same_p = 1;
-}
-
-
/* Return true if T1 and T2 have the same name. If FOR_COMPLETION_P is
true then if any type has no name return false, otherwise return
true if both types have no names. */
@@ -3196,7 +3167,7 @@ compare_field_offset (tree f1, tree f2)
/* Return 1 iff T1 and T2 are structurally identical.
Otherwise, return 0. */
-int
+static int
gimple_types_compatible_p (tree t1, tree t2)
{
type_pair_t p = NULL;
@@ -3404,107 +3375,107 @@ gimple_types_compatible_p (tree t1, tree t2)
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))
- goto different_types;
-
- /* If one pointer points to an incomplete type variant of
- the other pointed-to type they are the same. */
- if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))
- && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t1))
- && (!COMPLETE_TYPE_P (TREE_TYPE (t1))
- || !COMPLETE_TYPE_P (TREE_TYPE (t2)))
- && compare_type_names_p (TREE_TYPE (t1), TREE_TYPE (t2), true))
- {
- /* Replace the pointed-to incomplete type with the
- complete one. */
- if (COMPLETE_TYPE_P (TREE_TYPE (t2)))
- TREE_TYPE (t1) = TREE_TYPE (t2);
- else
- TREE_TYPE (t2) = TREE_TYPE (t1);
- goto same_types;
- }
+ {
+ /* 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))
+ goto different_types;
- /* Otherwise, pointer and reference types are the same if the
- pointed-to types are the same. */
- if (gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ /* If one pointer points to an incomplete type variant of
+ the other pointed-to type they are the same. */
+ if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t1))
+ && (!COMPLETE_TYPE_P (TREE_TYPE (t1))
+ || !COMPLETE_TYPE_P (TREE_TYPE (t2)))
+ && compare_type_names_p (TREE_TYPE (t1), TREE_TYPE (t2), true))
+ {
+ /* Replace the pointed-to incomplete type with the
+ complete one. */
+ if (COMPLETE_TYPE_P (TREE_TYPE (t2)))
+ TREE_TYPE (t1) = TREE_TYPE (t2);
+ else
+ TREE_TYPE (t2) = TREE_TYPE (t1);
goto same_types;
-
- goto different_types;
- }
+ }
+
+ /* Otherwise, pointer and reference types are the same if the
+ pointed-to types are the same. */
+ if (gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ goto same_types;
+
+ goto different_types;
+ }
case ENUMERAL_TYPE:
- {
- /* For enumeral types, all the values must be the same. */
- tree v1, v2;
+ {
+ /* For enumeral types, all the values must be the same. */
+ tree v1, v2;
- if (TYPE_VALUES (t1) == TYPE_VALUES (t2))
- goto same_types;
+ if (TYPE_VALUES (t1) == TYPE_VALUES (t2))
+ goto same_types;
- 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);
+ 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 (c1) == CONST_DECL)
+ c1 = DECL_INITIAL (c1);
- if (TREE_CODE (c2) == CONST_DECL)
- c2 = DECL_INITIAL (c2);
+ if (TREE_CODE (c2) == CONST_DECL)
+ c2 = DECL_INITIAL (c2);
- if (tree_int_cst_equal (c1, c2) != 1)
- goto different_types;
- }
+ if (tree_int_cst_equal (c1, c2) != 1)
+ goto different_types;
+ }
- /* If one enumeration has more values than the other, they
- are not the same. */
- if (v1 || v2)
- goto different_types;
+ /* If one enumeration has more values than the other, they
+ are not the same. */
+ if (v1 || v2)
+ goto different_types;
- goto same_types;
- }
+ goto same_types;
+ }
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- {
- tree f1, f2;
+ {
+ 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;
+ /* 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))
- goto different_types;
+ /* The struct tags shall compare equal. */
+ if (!compare_type_names_p (TYPE_MAIN_VARIANT (t1),
+ TYPE_MAIN_VARIANT (t2), false))
+ goto different_types;
- /* For aggregate types, all the fields must be the same. */
- 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)
- || !compare_field_offset (f1, f2)
- || !gimple_types_compatible_p (TREE_TYPE (f1),
- TREE_TYPE (f2)))
- goto different_types;
- }
+ /* For aggregate types, all the fields must be the same. */
+ 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)
+ || !compare_field_offset (f1, f2)
+ || !gimple_types_compatible_p (TREE_TYPE (f1),
+ TREE_TYPE (f2)))
+ goto different_types;
+ }
- /* If one aggregate has more fields than the other, they
- are not the same. */
- if (f1 || f2)
- goto different_types;
+ /* If one aggregate has more fields than the other, they
+ are not the same. */
+ if (f1 || f2)
+ goto different_types;
- goto same_types;
- }
+ goto same_types;
+ }
case VECTOR_TYPE:
if (TYPE_VECTOR_SUBPARTS (t1) != TYPE_VECTOR_SUBPARTS (t2))
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 3998bdfe03e..87309b694d4 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -915,8 +915,6 @@ extern bool is_gimple_call_addr (tree);
extern tree get_call_expr_in (tree t);
extern void recalculate_side_effects (tree);
-extern void gimple_force_type_merge (tree, tree);
-extern int gimple_types_compatible_p (tree, tree);
extern tree gimple_register_type (tree);
extern void print_gimple_types_stats (void);
extern void free_gimple_type_tables (void);
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index b2fb9629943..275875180c6 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -182,57 +182,6 @@ lto_symtab_get_resolution (tree decl)
}
-static bool maybe_merge_incomplete_and_complete_type (tree, tree);
-
-/* Try to merge an incomplete type INCOMPLETE with a complete type
- COMPLETE of same kinds.
- Return true if they were merged, false otherwise. */
-
-static bool
-merge_incomplete_and_complete_type (tree incomplete, tree complete)
-{
- /* For merging array types do some extra sanity checking. */
- if (TREE_CODE (incomplete) == ARRAY_TYPE
- && !maybe_merge_incomplete_and_complete_type (TREE_TYPE (incomplete),
- TREE_TYPE (complete))
- && !gimple_types_compatible_p (TREE_TYPE (incomplete),
- TREE_TYPE (complete)))
- return false;
-
- /* ??? Ideally we would do this by means of a common canonical type, but
- that's difficult as we do not have links from the canonical type
- back to all its children. */
- gimple_force_type_merge (incomplete, complete);
-
- return true;
-}
-
-/* Try to merge a maybe complete / incomplete type pair TYPE1 and TYPE2.
- Return true if they were merged, false otherwise. */
-
-static bool
-maybe_merge_incomplete_and_complete_type (tree type1, tree type2)
-{
- bool res = false;
-
- if (TREE_CODE (type1) != TREE_CODE (type2))
- return false;
-
- if (!COMPLETE_TYPE_P (type1) && COMPLETE_TYPE_P (type2))
- res = merge_incomplete_and_complete_type (type1, type2);
- else if (COMPLETE_TYPE_P (type1) && !COMPLETE_TYPE_P (type2))
- res = merge_incomplete_and_complete_type (type2, type1);
-
- /* Recurse on pointer targets. */
- if (!res
- && POINTER_TYPE_P (type1)
- && POINTER_TYPE_P (type2))
- res = maybe_merge_incomplete_and_complete_type (TREE_TYPE (type1),
- TREE_TYPE (type2));
-
- return res;
-}
-
/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
all edges and removing the old node. */
@@ -300,8 +249,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
- if (!gimple_types_compatible_p (TREE_TYPE (prevailing_decl),
- TREE_TYPE (decl)))
+ if (TREE_TYPE (prevailing_decl) != TREE_TYPE (decl))
/* If we don't have a merged type yet...sigh. The linker
wouldn't complain if the types were mismatched, so we
probably shouldn't either. Just use the type from
@@ -315,32 +263,56 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
/* Now we exclusively deal with VAR_DECLs. */
- /* Handle external declarations with incomplete type or pointed-to
- incomplete types by forcefully merging the types.
- ??? In principle all types involved in the two decls should
- be merged forcefully, for example without considering type or
- field names. */
- prevailing_type = TREE_TYPE (prevailing_decl);
- type = TREE_TYPE (decl);
-
- /* If the types are structurally equivalent we can use the knowledge
- that both bind to the same symbol to complete incomplete types
- of external declarations or of pointer targets.
- ??? We should apply this recursively to aggregate members here
- and get rid of the completion in gimple_types_compatible_p. */
- if (DECL_EXTERNAL (prevailing_decl) || DECL_EXTERNAL (decl))
- maybe_merge_incomplete_and_complete_type (prevailing_type, type);
- else if (POINTER_TYPE_P (prevailing_type)
- && POINTER_TYPE_P (type))
- maybe_merge_incomplete_and_complete_type (TREE_TYPE (prevailing_type),
- TREE_TYPE (type));
+ /* Sharing a global symbol is a strong hint that two types are
+ compatible. We could use this information to complete
+ incomplete pointed-to types more aggressively here, ignoring
+ mismatches in both field and tag names. It's difficult though
+ to guarantee that this does not have side-effects on merging
+ more compatible types from other translation units though. */
/* We can tolerate differences in type qualification, the
- qualification of the prevailing definition will prevail. */
+ qualification of the prevailing definition will prevail.
+ ??? In principle we might want to only warn for structurally
+ incompatible types here, but unless we have protective measures
+ for TBAA in place that would hide useful information. */
prevailing_type = TYPE_MAIN_VARIANT (TREE_TYPE (prevailing_decl));
type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
- if (!gimple_types_compatible_p (prevailing_type, type))
- return false;
+
+ /* We have to register and fetch canonical types here as the global
+ fixup process didn't yet run. */
+ prevailing_type = gimple_register_type (prevailing_type);
+ type = gimple_register_type (type);
+ if (prevailing_type != type)
+ {
+ if (COMPLETE_TYPE_P (type))
+ return false;
+
+ /* If type is incomplete then avoid warnings in the cases
+ that TBAA handles just fine. */
+
+ if (TREE_CODE (prevailing_type) != TREE_CODE (type))
+ return false;
+
+ if (TREE_CODE (prevailing_type) == ARRAY_TYPE)
+ {
+ tree tem1 = TREE_TYPE (prevailing_type);
+ tree tem2 = TREE_TYPE (type);
+ while (TREE_CODE (tem1) == ARRAY_TYPE
+ && TREE_CODE (tem2) == ARRAY_TYPE)
+ {
+ tem1 = TREE_TYPE (tem1);
+ tem2 = TREE_TYPE (tem2);
+ }
+
+ if (TREE_CODE (tem1) != TREE_CODE (tem2))
+ return false;
+
+ if (gimple_register_type (tem1) != gimple_register_type (tem2))
+ return false;
+ }
+
+ /* Fallthru. Compatible enough. */
+ }
/* ??? We might want to emit a warning here if type qualification
differences were spotted. Do not do this unconditionally though. */
@@ -505,8 +477,7 @@ lto_symtab_merge_decls_2 (void **slot)
/* Diagnose all mismatched re-declarations. */
for (i = 0; VEC_iterate (tree, mismatches, i, decl); ++i)
{
- if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl),
- TREE_TYPE (decl)))
+ if (TREE_TYPE (prevailing->decl) != TREE_TYPE (decl))
diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
"type of %qD does not match original "
"declaration", decl);