diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-10 08:39:46 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-10 08:39:46 +0000 |
commit | 816ede17aec94126d3908a6c5f36a6c439c655b6 (patch) | |
tree | f95de652429f2b6544137000cfc168804f88e923 /gcc/gimple.c | |
parent | 96fbe9dde2cd3dc9e6e5cea6905f8f98fdda1b4d (diff) | |
download | gcc-816ede17aec94126d3908a6c5f36a6c439c655b6.tar.gz |
2010-07-10 Richard Guenther <rguenther@suse.de>
PR lto/44889
* gimple.c (gimple_fixup_complete_and_incomplete_subtype_p): New
helper function.
(gimple_types_compatible_p): Similar to pointed-to
types allow and merge a mix of complete and incomplete aggregate.
Use gimple_fixup_complete_and_incomplete_subtype_p for that.
(iterative_hash_gimple_type): Adjust for that.
* gcc.dg/lto/20100709-1_0.c: New testcase.
* gcc.dg/lto/20100709-1_1.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162032 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimple.c')
-rw-r--r-- | gcc/gimple.c | 132 |
1 files changed, 84 insertions, 48 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c index 318b6d80e3a..5606da8a539 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3343,6 +3343,45 @@ gimple_queue_type_fixup (tree context, tree *incomplete, tree complete) VEC_safe_push (type_fixup, heap, gimple_register_type_fixups, &f); } +/* If the type *T1P and the type *T2P are a complete and an incomplete + variant of the same type return true and queue a fixup for the + incomplete one and its CONTEXT. Return false otherwise. */ + +static bool +gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p, + tree context2, tree *t2p) +{ + tree t1 = *t1p; + tree t2 = *t2p; + + /* If one pointer points to an incomplete type variant of + the other pointed-to type they are the same. */ + if (TREE_CODE (t1) == TREE_CODE (t2) + && RECORD_OR_UNION_TYPE_P (t1) + && (!COMPLETE_TYPE_P (t1) + || !COMPLETE_TYPE_P (t2)) + && TYPE_QUALS (t1) == TYPE_QUALS (t2) + && compare_type_names_p (TYPE_MAIN_VARIANT (t1), + TYPE_MAIN_VARIANT (t2), true)) + { + /* Replace the pointed-to incomplete type with the complete one. + ??? This simple name-based merging causes at least some + of the ICEs in canonicalizing FIELD_DECLs during stmt + read. For example in GCC we have two different struct deps + and we mismatch the use in struct cpp_reader in sched-int.h + vs. mkdeps.c. Of course the whole exercise is for TBAA + with structs which contain pointers to incomplete types + in one unit and to complete ones in another. So we + probably should merge these types only with more context. */ + if (COMPLETE_TYPE_P (t2)) + gimple_queue_type_fixup (context1, t1p, t2); + else + gimple_queue_type_fixup (context2, t2p, t1); + return true; + } + return false; +} + /* Return 1 iff T1 and T2 are structurally identical. Otherwise, return 0. */ @@ -3507,33 +3546,35 @@ gimple_types_compatible_p (tree t1, tree t2) case FUNCTION_TYPE: /* Function types are the same if the return type and arguments types are the same. */ - if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))) + if (!gimple_fixup_complete_and_incomplete_subtype_p + (t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2)) + && !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))) + goto different_types; + + if (!targetm.comp_type_attributes (t1, t2)) goto different_types; + + if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)) + goto same_types; else { - if (!targetm.comp_type_attributes (t1, t2)) - goto different_types; + tree parms1, parms2; - if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)) - goto same_types; - else + for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2); + parms1 && parms2; + parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2)) { - tree parms1, parms2; - - for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2); - parms1 && parms2; - parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2)) - { - if (!gimple_types_compatible_p (TREE_VALUE (parms1), - TREE_VALUE (parms2))) - goto different_types; - } - - if (parms1 || parms2) + if (!gimple_fixup_complete_and_incomplete_subtype_p + (t1, &TREE_VALUE (parms1), t2, &TREE_VALUE (parms2)) + && !gimple_types_compatible_p (TREE_VALUE (parms1), + TREE_VALUE (parms2))) goto different_types; - - goto same_types; } + + if (parms1 || parms2) + goto different_types; + + goto same_types; } case OFFSET_TYPE: @@ -3556,30 +3597,9 @@ gimple_types_compatible_p (tree t1, tree 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))) - && TYPE_QUALS (TREE_TYPE (t1)) == TYPE_QUALS (TREE_TYPE (t2)) - && compare_type_names_p (TYPE_MAIN_VARIANT (TREE_TYPE (t1)), - TYPE_MAIN_VARIANT (TREE_TYPE (t2)), true)) - { - /* Replace the pointed-to incomplete type with the - complete one. - ??? This simple name-based merging causes at least some - of the ICEs in canonicalizing FIELD_DECLs during stmt - read. For example in GCC we have two different struct deps - and we mismatch the use in struct cpp_reader in sched-int.h - vs. mkdeps.c. Of course the whole exercise is for TBAA - with structs which contain pointers to incomplete types - in one unit and to complete ones in another. So we - probably should merge these types only with more context. */ - if (COMPLETE_TYPE_P (TREE_TYPE (t2))) - gimple_queue_type_fixup (t1, &TREE_TYPE (t1), TREE_TYPE (t2)); - else - gimple_queue_type_fixup (t2, &TREE_TYPE (t2), TREE_TYPE (t1)); - goto same_types; - } + if (gimple_fixup_complete_and_incomplete_subtype_p + (t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2))) + goto same_types; /* Otherwise, pointer and reference types are the same if the pointed-to types are the same. */ @@ -3900,13 +3920,29 @@ iterative_hash_gimple_type (tree type, hashval_t val, v = visit (TYPE_METHOD_BASETYPE (type), state, v, sccstack, sccstate, sccstate_obstack); - v = visit (TREE_TYPE (type), state, v, - sccstack, sccstate, sccstate_obstack); + /* For result types allow mismatch in completeness. */ + if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) + { + v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v); + v = iterative_hash_name + (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v); + } + else + v = visit (TREE_TYPE (type), state, v, + sccstack, sccstate, sccstate_obstack); for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p)) { - v = visit (TREE_VALUE (p), state, v, - sccstack, sccstate, sccstate_obstack); + /* For argument types allow mismatch in completeness. */ + if (RECORD_OR_UNION_TYPE_P (TREE_VALUE (p))) + { + v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v); + v = iterative_hash_name + (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v); + } + else + v = visit (TREE_VALUE (p), state, v, + sccstack, sccstate, sccstate_obstack); na++; } |