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:
parent
0ae278e724
commit
e575382e2c
4 changed files with 148 additions and 196 deletions
|
@ -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
|
||||
|
|
205
gcc/gimple.c
205
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;
|
||||
}
|
||||
|
||||
/* 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))
|
||||
|
|
|
@ -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);
|
||||
|
|
125
gcc/lto-symtab.c
125
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue