lto-symtab.c (merge_incomplete_and_complete_type): Remove.

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.

From-SVN: r152920
This commit is contained in:
Richard Guenther 2009-10-16 21:17:31 +00:00 committed by Richard Biener
parent 0ae278e724
commit e575382e2c
4 changed files with 148 additions and 196 deletions

View File

@ -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

View File

@ -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;
}
/* 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;
{
/* 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;
}
/* 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;
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);
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)
goto different_types;
}
/* If one enumeration has more values than the other, they
are not the same. */
if (v1 || v2)
goto different_types;
{
/* For enumeral types, all the values must be the same. */
tree v1, v2;
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);
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)
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;
}
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))

View File

@ -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);

View File

@ -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);