Commit f5d6836a by Richard Guenther Committed by Richard Biener

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
parent ad650c92
2010-07-20 Richard Guenther <rguenther@suse.de> 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 PR middle-end/44971
PR middle-end/44988 PR middle-end/44988
* tree-ssa.c (maybe_optimize_var): New function split out from ... * tree-ssa.c (maybe_optimize_var): New function split out from ...
......
...@@ -47,6 +47,8 @@ static struct pointer_map_t *type_hash_cache; ...@@ -47,6 +47,8 @@ static struct pointer_map_t *type_hash_cache;
/* Global type comparison cache. */ /* Global type comparison cache. */
static htab_t gtc_visited; static htab_t gtc_visited;
static struct obstack gtc_ob; 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 /* All the tuples have their operand vector (if present) at the very bottom
of the structure. Therefore, the offset required to find the of the structure. Therefore, the offset required to find the
...@@ -3323,37 +3325,12 @@ gimple_compare_field_offset (tree f1, tree f2) ...@@ -3323,37 +3325,12 @@ gimple_compare_field_offset (tree f1, tree f2)
return false; return false;
} }
typedef struct type_fixup_s { /* If the type T1 and the type T2 are a complete and an incomplete
tree context; variant of the same type return true. */
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. */
static bool static bool
gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p, gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
tree context2, tree *t2p)
{ {
tree t1 = *t1p;
tree t2 = *t2p;
/* If one pointer points to an incomplete type variant of /* If one pointer points to an incomplete type variant of
the other pointed-to type they are the same. */ the other pointed-to type they are the same. */
if (TREE_CODE (t1) == TREE_CODE (t2) if (TREE_CODE (t1) == TREE_CODE (t2)
...@@ -3363,30 +3340,15 @@ gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p, ...@@ -3363,30 +3340,15 @@ gimple_fixup_complete_and_incomplete_subtype_p (tree context1, tree *t1p,
&& TYPE_QUALS (t1) == TYPE_QUALS (t2) && TYPE_QUALS (t1) == TYPE_QUALS (t2)
&& compare_type_names_p (TYPE_MAIN_VARIANT (t1), && compare_type_names_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2), true)) 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 false;
} }
/* Return 1 iff T1 and T2 are structurally identical. /* Return 1 iff T1 and T2 are structurally identical.
Otherwise, return 0. */ Otherwise, return 0. */
static int bool
gimple_types_compatible_p (tree t1, tree t2) gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
{ {
type_pair_t p = NULL; type_pair_t p = NULL;
...@@ -3439,7 +3401,8 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3439,7 +3401,8 @@ gimple_types_compatible_p (tree t1, tree t2)
/* Perform cheap tail-recursion for vector and complex types. */ /* Perform cheap tail-recursion for vector and complex types. */
if (TREE_CODE (t1) == VECTOR_TYPE if (TREE_CODE (t1) == VECTOR_TYPE
|| TREE_CODE (t1) == COMPLEX_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. */ /* For integral types fall thru to more complex checks. */
} }
...@@ -3460,7 +3423,9 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -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 /* If we've visited this type pair before (in the case of aggregates
with self-referential types), and we made a decision, return it. */ with self-referential types), and we made a decision, return it. */
p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob); p = lookup_type_pair (t1, t2,
for_merging_p ? &gtc_visited : &gtc_visited2,
for_merging_p ? &gtc_ob : &gtc_ob2);
if (p->same_p == 0 || p->same_p == 1) if (p->same_p == 0 || p->same_p == 1)
{ {
/* We have already decided whether T1 and T2 are the /* We have already decided whether T1 and T2 are the
...@@ -3489,7 +3454,8 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3489,7 +3454,8 @@ gimple_types_compatible_p (tree t1, tree t2)
case ARRAY_TYPE: case ARRAY_TYPE:
/* Array types are the same if the element types are the same and /* Array types are the same if the element types are the same and
the number of elements are the same. */ 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_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
|| TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2)) || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
goto different_types; goto different_types;
...@@ -3538,7 +3504,7 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3538,7 +3504,7 @@ gimple_types_compatible_p (tree t1, tree t2)
case METHOD_TYPE: case METHOD_TYPE:
/* Method types should belong to the same class. */ /* Method types should belong to the same class. */
if (!gimple_types_compatible_p (TYPE_METHOD_BASETYPE (t1), if (!gimple_types_compatible_p (TYPE_METHOD_BASETYPE (t1),
TYPE_METHOD_BASETYPE (t2))) TYPE_METHOD_BASETYPE (t2), for_merging_p))
goto different_types; goto different_types;
/* Fallthru */ /* Fallthru */
...@@ -3546,9 +3512,11 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3546,9 +3512,11 @@ gimple_types_compatible_p (tree t1, tree t2)
case FUNCTION_TYPE: case FUNCTION_TYPE:
/* Function types are the same if the return type and arguments types /* Function types are the same if the return type and arguments types
are the same. */ are the same. */
if (!gimple_fixup_complete_and_incomplete_subtype_p if ((for_merging_p
(t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2)) || !gimple_compatible_complete_and_incomplete_subtype_p
&& !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))) (TREE_TYPE (t1), TREE_TYPE (t2)))
&& !gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
for_merging_p))
goto different_types; goto different_types;
if (!targetm.comp_type_attributes (t1, t2)) if (!targetm.comp_type_attributes (t1, t2))
...@@ -3564,10 +3532,12 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3564,10 +3532,12 @@ gimple_types_compatible_p (tree t1, tree t2)
parms1 && parms2; parms1 && parms2;
parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2)) parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
{ {
if (!gimple_fixup_complete_and_incomplete_subtype_p if ((for_merging_p
(t1, &TREE_VALUE (parms1), t2, &TREE_VALUE (parms2)) || !gimple_compatible_complete_and_incomplete_subtype_p
(TREE_VALUE (parms1), TREE_VALUE (parms2)))
&& !gimple_types_compatible_p (TREE_VALUE (parms1), && !gimple_types_compatible_p (TREE_VALUE (parms1),
TREE_VALUE (parms2))) TREE_VALUE (parms2),
for_merging_p))
goto different_types; goto different_types;
} }
...@@ -3579,9 +3549,11 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3579,9 +3549,11 @@ gimple_types_compatible_p (tree t1, tree t2)
case OFFSET_TYPE: 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), || !gimple_types_compatible_p (TYPE_OFFSET_BASETYPE (t1),
TYPE_OFFSET_BASETYPE (t2))) TYPE_OFFSET_BASETYPE (t2),
for_merging_p))
goto different_types; goto different_types;
goto same_types; goto same_types;
...@@ -3597,13 +3569,15 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3597,13 +3569,15 @@ gimple_types_compatible_p (tree t1, tree t2)
/* If one pointer points to an incomplete type variant of /* If one pointer points to an incomplete type variant of
the other pointed-to type they are the same. */ the other pointed-to type they are the same. */
if (gimple_fixup_complete_and_incomplete_subtype_p if (!for_merging_p
(t1, &TREE_TYPE (t1), t2, &TREE_TYPE (t2))) && gimple_compatible_complete_and_incomplete_subtype_p
(TREE_TYPE (t1), TREE_TYPE (t2)))
goto same_types; goto same_types;
/* Otherwise, pointer and reference types are the same if the /* Otherwise, pointer and reference types are the same if the
pointed-to types are the same. */ 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 same_types;
goto different_types; goto different_types;
...@@ -3699,7 +3673,7 @@ gimple_types_compatible_p (tree t1, tree t2) ...@@ -3699,7 +3673,7 @@ gimple_types_compatible_p (tree t1, tree t2)
|| DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2) || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
|| !gimple_compare_field_offset (f1, f2) || !gimple_compare_field_offset (f1, f2)
|| !gimple_types_compatible_p (TREE_TYPE (f1), || !gimple_types_compatible_p (TREE_TYPE (f1),
TREE_TYPE (f2))) TREE_TYPE (f2), for_merging_p))
goto different_types; goto different_types;
} }
...@@ -4040,7 +4014,8 @@ gimple_type_eq (const void *p1, const void *p2) ...@@ -4040,7 +4014,8 @@ gimple_type_eq (const void *p1, const void *p2)
{ {
const_tree t1 = (const_tree) p1; const_tree t1 = (const_tree) p1;
const_tree t2 = (const_tree) p2; 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) ...@@ -4070,14 +4045,11 @@ gimple_register_type (tree t)
if (gimple_types == NULL) if (gimple_types == NULL)
gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0); 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); slot = htab_find_slot (gimple_types, t, INSERT);
if (*slot if (*slot
&& *(tree *)slot != t) && *(tree *)slot != t)
{ {
tree new_type = (tree) *((tree *) slot); tree new_type = (tree) *((tree *) slot);
unsigned i;
type_fixup *f;
/* Do not merge types with different addressability. */ /* Do not merge types with different addressability. */
gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type)); gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type));
...@@ -4129,11 +4101,6 @@ gimple_register_type (tree t) ...@@ -4129,11 +4101,6 @@ gimple_register_type (tree t)
TYPE_CANONICAL (t) = new_type; TYPE_CANONICAL (t) = new_type;
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 else
{ {
...@@ -4141,7 +4108,6 @@ gimple_register_type (tree t) ...@@ -4141,7 +4108,6 @@ gimple_register_type (tree t)
*slot = (void *) t; *slot = (void *) t;
} }
VEC_truncate (type_fixup, gimple_register_type_fixups, 0);
return t; return t;
} }
...@@ -4162,7 +4128,7 @@ print_gimple_types_stats (void) ...@@ -4162,7 +4128,7 @@ print_gimple_types_stats (void)
else else
fprintf (stderr, "GIMPLE type table is empty\n"); fprintf (stderr, "GIMPLE type table is empty\n");
if (gtc_visited) 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", "elements, %ld searches, %ld collisions (ratio: %f)\n",
(long) htab_size (gtc_visited), (long) htab_size (gtc_visited),
(long) htab_elements (gtc_visited), (long) htab_elements (gtc_visited),
...@@ -4170,6 +4136,16 @@ print_gimple_types_stats (void) ...@@ -4170,6 +4136,16 @@ print_gimple_types_stats (void)
(long) gtc_visited->collisions, (long) gtc_visited->collisions,
htab_collisions (gtc_visited)); htab_collisions (gtc_visited));
else 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"); fprintf (stderr, "GIMPLE type comparison table is empty\n");
} }
...@@ -4198,6 +4174,12 @@ free_gimple_type_tables (void) ...@@ -4198,6 +4174,12 @@ free_gimple_type_tables (void)
obstack_free (&gtc_ob, NULL); obstack_free (&gtc_ob, NULL);
gtc_visited = NULL; gtc_visited = NULL;
} }
if (gtc_visited2)
{
htab_delete (gtc_visited2);
obstack_free (&gtc_ob2, NULL);
gtc_visited2 = NULL;
}
} }
......
...@@ -956,6 +956,7 @@ extern tree get_call_expr_in (tree t); ...@@ -956,6 +956,7 @@ extern tree get_call_expr_in (tree t);
extern void recalculate_side_effects (tree); extern void recalculate_side_effects (tree);
extern bool gimple_compare_field_offset (tree, tree); extern bool gimple_compare_field_offset (tree, tree);
extern tree gimple_register_type (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 print_gimple_types_stats (void);
extern void free_gimple_type_tables (void); extern void free_gimple_type_tables (void);
extern tree gimple_unsigned_type (tree); extern tree gimple_unsigned_type (tree);
......
...@@ -960,7 +960,9 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, ...@@ -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)) for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
{ {
if (tem == field 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 (tem)
== DECL_NONADDRESSABLE_P (field) == DECL_NONADDRESSABLE_P (field)
&& gimple_compare_field_offset (tem, field))) && gimple_compare_field_offset (tem, field)))
......
...@@ -348,7 +348,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry) ...@@ -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_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 /* If we don't have a merged type yet...sigh. The linker
wouldn't complain if the types were mismatched, so we wouldn't complain if the types were mismatched, so we
probably shouldn't either. Just use the type from 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) ...@@ -381,7 +382,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
fixup process didn't yet run. */ fixup process didn't yet run. */
prevailing_type = gimple_register_type (prevailing_type); prevailing_type = gimple_register_type (prevailing_type);
type = gimple_register_type (type); type = gimple_register_type (type);
if (prevailing_type != type) if (!gimple_types_compatible_p (prevailing_type, type, false))
{ {
if (COMPLETE_TYPE_P (type)) if (COMPLETE_TYPE_P (type))
return false; return false;
...@@ -406,7 +407,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry) ...@@ -406,7 +407,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
if (TREE_CODE (tem1) != TREE_CODE (tem2)) if (TREE_CODE (tem1) != TREE_CODE (tem2))
return false; 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; return false;
} }
...@@ -600,7 +602,8 @@ lto_symtab_merge_decls_2 (void **slot) ...@@ -600,7 +602,8 @@ lto_symtab_merge_decls_2 (void **slot)
/* Diagnose all mismatched re-declarations. */ /* Diagnose all mismatched re-declarations. */
for (i = 0; VEC_iterate (tree, mismatches, i, decl); ++i) 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, diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
"type of %qD does not match original " "type of %qD does not match original "
"declaration", decl); "declaration", decl);
......
...@@ -1426,7 +1426,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type) ...@@ -1426,7 +1426,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
compared types. */ compared types. */
else if (AGGREGATE_TYPE_P (inner_type) else if (AGGREGATE_TYPE_P (inner_type)
&& TREE_CODE (inner_type) == TREE_CODE (outer_type)) && TREE_CODE (inner_type) == TREE_CODE (outer_type))
return false; return gimple_types_compatible_p (outer_type, inner_type, false);
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment