lto-symtab.c (lto_symtab_merge): Use gtc_mode enum values.

2010-07-23  Richard Guenther  <rguenther@suse.de>

	* lto-symtab.c (lto_symtab_merge): Use gtc_mode enum
	values.
	(lto_symtab_merge_decls_2): Likewise.
	* tree-ssa.c (useless_type_conversion_p): Likewise.
	* lto-streamer-in.c (input_gimple_stmt): Likewise.
	* gimple.c (gtc_visited2, gtc_ob2): Remove.
	(struct type_pair_d): Make same_p an array indexed by mode.
	Update comment.
	(lookup_type_pair): Update initialization.
	(struct sccs): Adjust same_p type.
	(gimple_types_compatible_p_1, gtc_visit, gimple_types_compatible_p):
	Adjust.
	(print_gimple_types_stats): Likewise.
	* gimple.h (enum gtc_mode): New.
	(gimple_types_compatible_p): Adjust prototype.

From-SVN: r162461
This commit is contained in:
Richard Guenther 2010-07-23 14:01:49 +00:00 committed by Richard Biener
parent 6afb52d3e2
commit c4fcd06a10
6 changed files with 67 additions and 76 deletions

View file

@ -1,3 +1,21 @@
2010-07-23 Richard Guenther <rguenther@suse.de>
* lto-symtab.c (lto_symtab_merge): Use gtc_mode enum
values.
(lto_symtab_merge_decls_2): Likewise.
* tree-ssa.c (useless_type_conversion_p): Likewise.
* lto-streamer-in.c (input_gimple_stmt): Likewise.
* gimple.c (gtc_visited2, gtc_ob2): Remove.
(struct type_pair_d): Make same_p an array indexed by mode.
Update comment.
(lookup_type_pair): Update initialization.
(struct sccs): Adjust same_p type.
(gimple_types_compatible_p_1, gtc_visit, gimple_types_compatible_p):
Adjust.
(print_gimple_types_stats): Likewise.
* gimple.h (enum gtc_mode): New.
(gimple_types_compatible_p): Adjust prototype.
2010-07-23 Daniel Jacobowitz <dan@codesourcery.com>
* dwarf2out.c (dwarf2out_frame_debug): Check for queued saves

View file

@ -47,8 +47,6 @@ 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
@ -3157,20 +3155,20 @@ static hashval_t gimple_type_hash (const void *);
/* Structure used to maintain a cache of some type pairs compared by
gimple_types_compatible_p when comparing aggregate types. There are
four possible values for SAME_P:
three possible values for SAME_P:
-2: The pair (T1, T2) has just been inserted in the table.
-1: The pair (T1, T2) is currently being compared.
0: T1 and T2 are different types.
1: T1 and T2 are the same type.
This table is only used when comparing aggregate types to avoid
infinite recursion due to self-referential types. */
The two elements in the SAME_P array are indexed by the comparison
mode gtc_mode. */
struct type_pair_d
{
unsigned int uid1;
unsigned int uid2;
int same_p;
signed char same_p[2];
};
typedef struct type_pair_d *type_pair_t;
@ -3227,7 +3225,8 @@ lookup_type_pair (tree t1, tree t2, htab_t *visited_p, struct obstack *ob_p)
p = XOBNEW (ob_p, struct type_pair_d);
p->uid1 = TYPE_UID (t1);
p->uid2 = TYPE_UID (t2);
p->same_p = -2;
p->same_p[0] = -2;
p->same_p[1] = -2;
*slot = (void *) p;
}
@ -3246,7 +3245,7 @@ struct sccs
bool on_sccstack;
union {
hashval_t hash;
int same_p;
signed char same_p;
} u;
};
@ -3366,7 +3365,8 @@ gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
}
static bool
gimple_types_compatible_p_1 (tree, tree, bool, VEC(type_pair_t, heap) **,
gimple_types_compatible_p_1 (tree, tree, enum gtc_mode, type_pair_t,
VEC(type_pair_t, heap) **,
struct pointer_map_t *, struct obstack *);
/* DFS visit the edge from the callers type pair with state *STATE to
@ -3376,7 +3376,7 @@ gimple_types_compatible_p_1 (tree, tree, bool, VEC(type_pair_t, heap) **,
SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */
static bool
gtc_visit (tree t1, tree t2, bool for_merging_p,
gtc_visit (tree t1, tree t2, enum gtc_mode mode,
struct sccs *state,
VEC(type_pair_t, heap) **sccstack,
struct pointer_map_t *sccstate,
@ -3456,33 +3456,28 @@ gtc_visit (tree t1, tree t2, bool for_merging_p,
return false;
/* Allocate a new cache entry for this comparison. */
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)
p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
if (p->same_p[mode] == 0 || p->same_p[mode] == 1)
{
/* We have already decided whether T1 and T2 are the
same, return the cached result. */
return p->same_p == 1;
return p->same_p[mode] == 1;
}
gcc_assert (p->same_p == -2);
if ((slot = pointer_map_contains (sccstate, p)) != NULL)
cstate = (struct sccs *)*slot;
if (!cstate)
{
bool res;
/* Not yet visited. DFS recurse. */
res = gimple_types_compatible_p_1 (t1, t2, for_merging_p,
res = gimple_types_compatible_p_1 (t1, t2, mode, p,
sccstack, sccstate, sccstate_obstack);
if (!cstate)
cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
state->low = MIN (state->low, cstate->low);
/* If the type is no longer on the SCC stack and thus is not part
of the parents SCC mix in its hash value. Otherwise we will
ignore the type for hashing purposes and return the unaltered
hash value. */
of the parents SCC, return its state. Otherwise we will
ignore this pair and assume equality. */
if (!cstate->on_sccstack)
return res;
}
@ -3498,19 +3493,15 @@ gtc_visit (tree t1, tree t2, bool for_merging_p,
SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done. */
static bool
gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
type_pair_t p,
VEC(type_pair_t, heap) **sccstack,
struct pointer_map_t *sccstate,
struct obstack *sccstate_obstack)
{
type_pair_t p;
struct sccs *state;
/* Allocate a new cache entry for this comparison. */
p = lookup_type_pair (t1, t2,
for_merging_p ? &gtc_visited : &gtc_visited2,
for_merging_p ? &gtc_ob : &gtc_ob2);
gcc_assert (p->same_p == -2);
gcc_assert (p->same_p[mode] == -2);
state = XOBNEW (sccstate_obstack, struct sccs);
*pointer_map_insert (sccstate, p) = state;
@ -3529,7 +3520,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
{
case VECTOR_TYPE:
case COMPLEX_TYPE:
if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
state, sccstack, sccstate, sccstate_obstack))
goto different_types;
goto same_types;
@ -3537,7 +3528,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
case ARRAY_TYPE:
/* Array types are the same if the element types are the same and
the number of elements are the same. */
if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
state, sccstack, sccstate, sccstate_obstack)
|| TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
|| TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
@ -3587,8 +3578,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
case METHOD_TYPE:
/* Method types should belong to the same class. */
if (!gtc_visit (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2),
for_merging_p,
state, sccstack, sccstate, sccstate_obstack))
mode, state, sccstack, sccstate, sccstate_obstack))
goto different_types;
/* Fallthru */
@ -3596,10 +3586,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
case FUNCTION_TYPE:
/* Function types are the same if the return type and arguments types
are the same. */
if ((for_merging_p
if ((mode != GTC_DIAG
|| !gimple_compatible_complete_and_incomplete_subtype_p
(TREE_TYPE (t1), TREE_TYPE (t2)))
&& !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
&& !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
state, sccstack, sccstate, sccstate_obstack))
goto different_types;
@ -3616,11 +3606,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
parms1 && parms2;
parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
{
if ((for_merging_p
if ((mode == GTC_MERGE
|| !gimple_compatible_complete_and_incomplete_subtype_p
(TREE_VALUE (parms1), TREE_VALUE (parms2)))
&& !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2),
for_merging_p,
&& !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2), mode,
state, sccstack, sccstate, sccstate_obstack))
goto different_types;
}
@ -3633,10 +3622,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
case OFFSET_TYPE:
{
if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
state, sccstack, sccstate, sccstate_obstack)
|| !gtc_visit (TYPE_OFFSET_BASETYPE (t1),
TYPE_OFFSET_BASETYPE (t2), for_merging_p,
TYPE_OFFSET_BASETYPE (t2), mode,
state, sccstack, sccstate, sccstate_obstack))
goto different_types;
@ -3653,14 +3642,14 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
/* If one pointer points to an incomplete type variant of
the other pointed-to type they are the same. */
if (!for_merging_p
if (mode == GTC_DIAG
&& 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 (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
if (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
state, sccstack, sccstate, sccstate_obstack))
goto same_types;
@ -3756,7 +3745,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
if (DECL_NAME (f1) != DECL_NAME (f2)
|| DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
|| !gimple_compare_field_offset (f1, f2)
|| !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), for_merging_p,
|| !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), mode,
state, sccstack, sccstate, sccstate_obstack))
goto different_types;
}
@ -3795,7 +3784,7 @@ pop:
x = VEC_pop (type_pair_t, *sccstack);
cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
cstate->on_sccstack = false;
x->same_p = cstate->u.same_p;
x->same_p[mode] = cstate->u.same_p;
}
while (x != p);
}
@ -3808,7 +3797,7 @@ pop:
are considered different, otherwise they are considered compatible. */
bool
gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode)
{
VEC(type_pair_t, heap) *sccstack = NULL;
struct pointer_map_t *sccstate;
@ -3889,21 +3878,19 @@ gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
/* 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,
for_merging_p ? &gtc_visited : &gtc_visited2,
for_merging_p ? &gtc_ob : &gtc_ob2);
if (p->same_p == 0 || p->same_p == 1)
p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
if (p->same_p[mode] == 0 || p->same_p[mode] == 1)
{
/* We have already decided whether T1 and T2 are the
same, return the cached result. */
return p->same_p == 1;
return p->same_p[mode] == 1;
}
/* Now set up the SCC machinery for the comparison. */
gtc_next_dfs_num = 1;
sccstate = pointer_map_create ();
gcc_obstack_init (&sccstate_obstack);
res = gimple_types_compatible_p_1 (t1, t2, for_merging_p,
res = gimple_types_compatible_p_1 (t1, t2, mode, p,
&sccstack, sccstate, &sccstate_obstack);
VEC_free (type_pair_t, heap, sccstack);
pointer_map_destroy (sccstate);
@ -4210,7 +4197,7 @@ 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), true);
CONST_CAST_TREE (t2), GTC_MERGE);
}
@ -4323,23 +4310,13 @@ print_gimple_types_stats (void)
else
fprintf (stderr, "GIMPLE type table is empty\n");
if (gtc_visited)
fprintf (stderr, "GIMPLE type merging comparison table: size %ld, %ld "
fprintf (stderr, "GIMPLE type 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");
}
@ -4369,12 +4346,6 @@ free_gimple_type_tables (void)
obstack_free (&gtc_ob, NULL);
gtc_visited = NULL;
}
if (gtc_visited2)
{
htab_delete (gtc_visited2);
obstack_free (&gtc_ob2, NULL);
gtc_visited2 = NULL;
}
}

View file

@ -956,7 +956,8 @@ 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);
enum gtc_mode { GTC_MERGE = 0, GTC_DIAG = 1 };
extern bool gimple_types_compatible_p (tree, tree, enum gtc_mode);
extern void print_gimple_types_stats (void);
extern void free_gimple_type_tables (void);
extern tree gimple_unsigned_type (tree);

View file

@ -962,7 +962,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
if (tem == field
|| (gimple_types_compatible_p (TREE_TYPE (tem),
TREE_TYPE (field),
false)
GTC_DIAG)
&& DECL_NONADDRESSABLE_P (tem)
== DECL_NONADDRESSABLE_P (field)
&& gimple_compare_field_offset (tem, field)))

View file

@ -349,7 +349,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), false))
TREE_TYPE (decl), GTC_DIAG))
/* 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
@ -382,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 (!gimple_types_compatible_p (prevailing_type, type, false))
if (!gimple_types_compatible_p (prevailing_type, type, GTC_DIAG))
{
if (COMPLETE_TYPE_P (type))
return false;
@ -408,7 +408,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
return false;
if (!gimple_types_compatible_p (gimple_register_type (tem1),
gimple_register_type (tem2), false))
gimple_register_type (tem2),
GTC_DIAG))
return false;
}
@ -603,7 +604,7 @@ lto_symtab_merge_decls_2 (void **slot)
for (i = 0; VEC_iterate (tree, mismatches, i, decl); ++i)
{
if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl),
TREE_TYPE (decl), false))
TREE_TYPE (decl), GTC_DIAG))
diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
"type of %qD does not match original "
"declaration", decl);

View file

@ -1427,7 +1427,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
else if (AGGREGATE_TYPE_P (inner_type)
&& TREE_CODE (inner_type) == TREE_CODE (outer_type))
return (in_lto_p
&& gimple_types_compatible_p (outer_type, inner_type, false));
&& gimple_types_compatible_p (outer_type, inner_type, GTC_DIAG));
return false;
}