diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/gimple.c | 193 | ||||
-rw-r--r-- | gcc/gimple.h | 2 | ||||
-rw-r--r-- | gcc/lto-symtab.c | 125 |
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, >c_visited, >c_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); |