summaryrefslogtreecommitdiff
path: root/gcc/gimple.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-10 08:39:46 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-10 08:39:46 +0000
commit816ede17aec94126d3908a6c5f36a6c439c655b6 (patch)
treef95de652429f2b6544137000cfc168804f88e923 /gcc/gimple.c
parent96fbe9dde2cd3dc9e6e5cea6905f8f98fdda1b4d (diff)
downloadgcc-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.c132
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++;
}