lto-symtab.c (lto_symtab_merge): Use gimple_types_compatible_p.
2010-07-20 Richard Guenther <rguenther@suse.de> * lto-symtab.c (lto_symtab_merge): Use gimple_types_compatible_p. (lto_symtab_merge_decls_2): Likewise. * gimple.h (gimple_types_compatible_p): Declare. * gimple.c (gimple_queue_type_fixup): Remove. (gimple_fixup_complete_and_incomplete_subtype_p): Likewise. (gimple_compatible_complete_and_incomplete_type_p): New function. (gimple_types_compatible_p): Adjust. (gimple_register_type): Remove type fixup code. (print_gimple_types_stats): Adjust. (free_gimple_type_tables): Likewise. * lto-streamer-in.c (input_gimple_stmt): Use gimple_types_compatible_p. * tree-ssa.c (useless_type_conversion_p): Likewise. From-SVN: r162330
This commit is contained in:
parent
ad650c924f
commit
f5d6836a24
|
@ -1,3 +1,19 @@
|
|||
2010-07-20 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* lto-symtab.c (lto_symtab_merge): Use gimple_types_compatible_p.
|
||||
(lto_symtab_merge_decls_2): Likewise.
|
||||
* gimple.h (gimple_types_compatible_p): Declare.
|
||||
* gimple.c (gimple_queue_type_fixup): Remove.
|
||||
(gimple_fixup_complete_and_incomplete_subtype_p): Likewise.
|
||||
(gimple_compatible_complete_and_incomplete_type_p): New
|
||||
function.
|
||||
(gimple_types_compatible_p): Adjust.
|
||||
(gimple_register_type): Remove type fixup code.
|
||||
(print_gimple_types_stats): Adjust.
|
||||
(free_gimple_type_tables): Likewise.
|
||||
* lto-streamer-in.c (input_gimple_stmt): Use gimple_types_compatible_p.
|
||||
* tree-ssa.c (useless_type_conversion_p): Likewise.
|
||||
|
||||
2010-07-20 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/44971
|
||||
|
|
128
gcc/gimple.c
128
gcc/gimple.c
|
@ -47,6 +47,8 @@ static struct pointer_map_t *type_hash_cache;
|
|||
/* Global type comparison cache. */
|
||||
static htab_t gtc_visited;
|
||||
static struct obstack gtc_ob;
|
||||
static htab_t gtc_visited2;
|
||||
static struct obstack gtc_ob2;
|
||||
|
||||
/* All the tuples have their operand vector (if present) at the very bottom
|
||||
of the structure. Therefore, the offset required to find the
|
||||
|
@ -3323,37 +3325,12 @@ gimple_compare_field_offset (tree f1, tree f2)
|
|||
return false;
|
||||
}
|
||||
|
||||
typedef struct type_fixup_s {
|
||||
tree context;
|
||||
tree *incomplete;
|
||||
tree complete;
|
||||
} type_fixup;
|
||||
DEF_VEC_O(type_fixup);
|
||||
DEF_VEC_ALLOC_O(type_fixup,heap);
|
||||
|
||||
static VEC(type_fixup, heap) *gimple_register_type_fixups = NULL;
|
||||
|
||||
static void
|
||||
gimple_queue_type_fixup (tree context, tree *incomplete, tree complete)
|
||||
{
|
||||
type_fixup f;
|
||||
f.context = context;
|
||||
f.incomplete = incomplete;
|
||||
f.complete = 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. */
|
||||
/* If the type T1 and the type T2 are a complete and an incomplete
|
||||
variant of the same type return true. */
|
||||
|
||||
static bool
|
||||
gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p,
|
||||
tree context2, tree *t2p)
|
||||
gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
|
||||
{
|
||||
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)
|
||||
|
@ -3363,30 +3340,15 @@ gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p,
|
|||
&& 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 true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return 1 iff T1 and T2 are structurally identical.
|
||||
Otherwise, return 0. */
|
||||
|
||||
static int
|
||||
gimple_types_compatible_p (tree t1, tree t2)
|
||||
bool
|
||||
gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
|
||||
{
|
||||
type_pair_t p = NULL;
|
||||
|
||||
|
@ -3439,7 +3401,8 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
/* Perform cheap tail-recursion for vector and complex types. */
|
||||
if (TREE_CODE (t1) == VECTOR_TYPE
|
||||
|| TREE_CODE (t1) == COMPLEX_TYPE)
|
||||
return gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2));
|
||||
return gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
|
||||
for_merging_p);
|
||||
|
||||
/* For integral types fall thru to more complex checks. */
|
||||
}
|
||||
|
@ -3460,7 +3423,9 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
|
||||
/* If we've visited this type pair before (in the case of aggregates
|
||||
with self-referential types), and we made a decision, return it. */
|
||||
p = lookup_type_pair (t1, t2, >c_visited, >c_ob);
|
||||
p = lookup_type_pair (t1, t2,
|
||||
for_merging_p ? >c_visited : >c_visited2,
|
||||
for_merging_p ? >c_ob : >c_ob2);
|
||||
if (p->same_p == 0 || p->same_p == 1)
|
||||
{
|
||||
/* We have already decided whether T1 and T2 are the
|
||||
|
@ -3489,7 +3454,8 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
case ARRAY_TYPE:
|
||||
/* Array types are the same if the element types are the same and
|
||||
the number of elements are the same. */
|
||||
if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))
|
||||
if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
|
||||
for_merging_p)
|
||||
|| TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
|
||||
|| TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
|
||||
goto different_types;
|
||||
|
@ -3538,7 +3504,7 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
case METHOD_TYPE:
|
||||
/* Method types should belong to the same class. */
|
||||
if (!gimple_types_compatible_p (TYPE_METHOD_BASETYPE (t1),
|
||||
TYPE_METHOD_BASETYPE (t2)))
|
||||
TYPE_METHOD_BASETYPE (t2), for_merging_p))
|
||||
goto different_types;
|
||||
|
||||
/* Fallthru */
|
||||
|
@ -3546,9 +3512,11 @@ 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_fixup_complete_and_incomplete_subtype_p
|
||||
(t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2))
|
||||
&& !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
|
||||
if ((for_merging_p
|
||||
|| !gimple_compatible_complete_and_incomplete_subtype_p
|
||||
(TREE_TYPE (t1), TREE_TYPE (t2)))
|
||||
&& !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
|
||||
for_merging_p))
|
||||
goto different_types;
|
||||
|
||||
if (!targetm.comp_type_attributes (t1, t2))
|
||||
|
@ -3564,10 +3532,12 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
parms1 && parms2;
|
||||
parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
|
||||
{
|
||||
if (!gimple_fixup_complete_and_incomplete_subtype_p
|
||||
(t1, &TREE_VALUE (parms1), t2, &TREE_VALUE (parms2))
|
||||
if ((for_merging_p
|
||||
|| !gimple_compatible_complete_and_incomplete_subtype_p
|
||||
(TREE_VALUE (parms1), TREE_VALUE (parms2)))
|
||||
&& !gimple_types_compatible_p (TREE_VALUE (parms1),
|
||||
TREE_VALUE (parms2)))
|
||||
TREE_VALUE (parms2),
|
||||
for_merging_p))
|
||||
goto different_types;
|
||||
}
|
||||
|
||||
|
@ -3579,9 +3549,11 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
|
||||
case OFFSET_TYPE:
|
||||
{
|
||||
if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))
|
||||
if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
|
||||
for_merging_p)
|
||||
|| !gimple_types_compatible_p (TYPE_OFFSET_BASETYPE (t1),
|
||||
TYPE_OFFSET_BASETYPE (t2)))
|
||||
TYPE_OFFSET_BASETYPE (t2),
|
||||
for_merging_p))
|
||||
goto different_types;
|
||||
|
||||
goto same_types;
|
||||
|
@ -3597,13 +3569,15 @@ 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 (gimple_fixup_complete_and_incomplete_subtype_p
|
||||
(t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2)))
|
||||
if (!for_merging_p
|
||||
&& gimple_compatible_complete_and_incomplete_subtype_p
|
||||
(TREE_TYPE (t1), TREE_TYPE (t2)))
|
||||
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)))
|
||||
if (gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
|
||||
for_merging_p))
|
||||
goto same_types;
|
||||
|
||||
goto different_types;
|
||||
|
@ -3699,7 +3673,7 @@ gimple_types_compatible_p (tree t1, tree t2)
|
|||
|| DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
|
||||
|| !gimple_compare_field_offset (f1, f2)
|
||||
|| !gimple_types_compatible_p (TREE_TYPE (f1),
|
||||
TREE_TYPE (f2)))
|
||||
TREE_TYPE (f2), for_merging_p))
|
||||
goto different_types;
|
||||
}
|
||||
|
||||
|
@ -4040,7 +4014,8 @@ gimple_type_eq (const void *p1, const void *p2)
|
|||
{
|
||||
const_tree t1 = (const_tree) p1;
|
||||
const_tree t2 = (const_tree) p2;
|
||||
return gimple_types_compatible_p (CONST_CAST_TREE (t1), CONST_CAST_TREE (t2));
|
||||
return gimple_types_compatible_p (CONST_CAST_TREE (t1),
|
||||
CONST_CAST_TREE (t2), true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4070,14 +4045,11 @@ gimple_register_type (tree t)
|
|||
if (gimple_types == NULL)
|
||||
gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0);
|
||||
|
||||
gcc_assert (VEC_empty (type_fixup, gimple_register_type_fixups));
|
||||
slot = htab_find_slot (gimple_types, t, INSERT);
|
||||
if (*slot
|
||||
&& *(tree *)slot != t)
|
||||
{
|
||||
tree new_type = (tree) *((tree *) slot);
|
||||
unsigned i;
|
||||
type_fixup *f;
|
||||
|
||||
/* Do not merge types with different addressability. */
|
||||
gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type));
|
||||
|
@ -4129,11 +4101,6 @@ gimple_register_type (tree t)
|
|||
|
||||
TYPE_CANONICAL (t) = new_type;
|
||||
t = new_type;
|
||||
|
||||
for (i = 0;
|
||||
VEC_iterate (type_fixup, gimple_register_type_fixups, i, f); ++i)
|
||||
if (f->context == t)
|
||||
*(f->incomplete) = f->complete;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4141,7 +4108,6 @@ gimple_register_type (tree t)
|
|||
*slot = (void *) t;
|
||||
}
|
||||
|
||||
VEC_truncate (type_fixup, gimple_register_type_fixups, 0);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -4162,13 +4128,23 @@ print_gimple_types_stats (void)
|
|||
else
|
||||
fprintf (stderr, "GIMPLE type table is empty\n");
|
||||
if (gtc_visited)
|
||||
fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
|
||||
fprintf (stderr, "GIMPLE type merging comparison table: size %ld, %ld "
|
||||
"elements, %ld searches, %ld collisions (ratio: %f)\n",
|
||||
(long) htab_size (gtc_visited),
|
||||
(long) htab_elements (gtc_visited),
|
||||
(long) gtc_visited->searches,
|
||||
(long) gtc_visited->collisions,
|
||||
htab_collisions (gtc_visited));
|
||||
else
|
||||
fprintf (stderr, "GIMPLE type merging comparison table is empty\n");
|
||||
if (gtc_visited2)
|
||||
fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
|
||||
"elements, %ld searches, %ld collisions (ratio: %f)\n",
|
||||
(long) htab_size (gtc_visited2),
|
||||
(long) htab_elements (gtc_visited2),
|
||||
(long) gtc_visited2->searches,
|
||||
(long) gtc_visited2->collisions,
|
||||
htab_collisions (gtc_visited2));
|
||||
else
|
||||
fprintf (stderr, "GIMPLE type comparison table is empty\n");
|
||||
}
|
||||
|
@ -4198,6 +4174,12 @@ free_gimple_type_tables (void)
|
|||
obstack_free (>c_ob, NULL);
|
||||
gtc_visited = NULL;
|
||||
}
|
||||
if (gtc_visited2)
|
||||
{
|
||||
htab_delete (gtc_visited2);
|
||||
obstack_free (>c_ob2, NULL);
|
||||
gtc_visited2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -956,6 +956,7 @@ extern tree get_call_expr_in (tree t);
|
|||
extern void recalculate_side_effects (tree);
|
||||
extern bool gimple_compare_field_offset (tree, tree);
|
||||
extern tree gimple_register_type (tree);
|
||||
extern bool gimple_types_compatible_p (tree, tree, bool);
|
||||
extern void print_gimple_types_stats (void);
|
||||
extern void free_gimple_type_tables (void);
|
||||
extern tree gimple_unsigned_type (tree);
|
||||
|
|
|
@ -960,7 +960,9 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
|||
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
|
||||
{
|
||||
if (tem == field
|
||||
|| (TREE_TYPE (tem) == TREE_TYPE (field)
|
||||
|| (gimple_types_compatible_p (TREE_TYPE (tem),
|
||||
TREE_TYPE (field),
|
||||
false)
|
||||
&& DECL_NONADDRESSABLE_P (tem)
|
||||
== DECL_NONADDRESSABLE_P (field)
|
||||
&& gimple_compare_field_offset (tem, field)))
|
||||
|
|
|
@ -348,7 +348,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
|
|||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
if (TREE_TYPE (prevailing_decl) != TREE_TYPE (decl))
|
||||
if (!gimple_types_compatible_p (TREE_TYPE (prevailing_decl),
|
||||
TREE_TYPE (decl), false))
|
||||
/* 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
|
||||
|
@ -381,7 +382,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
|
|||
fixup process didn't yet run. */
|
||||
prevailing_type = gimple_register_type (prevailing_type);
|
||||
type = gimple_register_type (type);
|
||||
if (prevailing_type != type)
|
||||
if (!gimple_types_compatible_p (prevailing_type, type, false))
|
||||
{
|
||||
if (COMPLETE_TYPE_P (type))
|
||||
return false;
|
||||
|
@ -406,7 +407,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
|
|||
if (TREE_CODE (tem1) != TREE_CODE (tem2))
|
||||
return false;
|
||||
|
||||
if (gimple_register_type (tem1) != gimple_register_type (tem2))
|
||||
if (!gimple_types_compatible_p (gimple_register_type (tem1),
|
||||
gimple_register_type (tem2), false))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -600,7 +602,8 @@ lto_symtab_merge_decls_2 (void **slot)
|
|||
/* Diagnose all mismatched re-declarations. */
|
||||
for (i = 0; VEC_iterate (tree, mismatches, i, decl); ++i)
|
||||
{
|
||||
if (TREE_TYPE (prevailing->decl) != TREE_TYPE (decl))
|
||||
if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl),
|
||||
TREE_TYPE (decl), false))
|
||||
diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
|
||||
"type of %qD does not match original "
|
||||
"declaration", decl);
|
||||
|
|
|
@ -1426,7 +1426,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
|
|||
compared types. */
|
||||
else if (AGGREGATE_TYPE_P (inner_type)
|
||||
&& TREE_CODE (inner_type) == TREE_CODE (outer_type))
|
||||
return false;
|
||||
return gimple_types_compatible_p (outer_type, inner_type, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue