Commit a844a60b by Richard Guenther Committed by Richard Biener

re PR c++/44871 (Invalid type mismatches while merging C and C++ sources)

2010-12-02  Richard Guenther  <rguenther@suse.de>

	PR lto/44871
	* gimple.c (canonical_type_hash_cache): New hashtable.
	(gimple_type_hash): Make a wrapper around ...
	(gimple_type_hash_1): ... this.  Take gtc_mode argument.
	(gimple_canonical_type_hash): Likewise.
	(gtc_visit): Take a gtc_mode argument.
	(gimple_types_compatible_p_1): Likewise. Do not compare struct
	tag names or field names when computing canonical types.
	(gimple_types_compatible_p): Adjust.
	(visit): Take a gtc_mode argument.
	(iterative_hash_gimple_type): Likewise.  Do not hash struct tag
	names or field names when computing hashes of canonical types.
	(gimple_register_canonical_type): Use gimple_canonical_type_hash
	for the hash.
	(print_gimple_types_stats): Dump stats of canonical_type_hash_cache.
	(free_gimple_type_tables): Free canonical_type_hash_cache.

	* g++.dg/lto/20101126-1_0.C: New testcase.
	* g++.dg/lto/20101126-1_1.c: Likewise.

From-SVN: r167367
parent 52bd463c
2010-12-02 Richard Guenther <rguenther@suse.de> 2010-12-02 Richard Guenther <rguenther@suse.de>
PR lto/44871
* gimple.c (canonical_type_hash_cache): New hashtable.
(gimple_type_hash): Make a wrapper around ...
(gimple_type_hash_1): ... this. Take gtc_mode argument.
(gimple_canonical_type_hash): Likewise.
(gtc_visit): Take a gtc_mode argument.
(gimple_types_compatible_p_1): Likewise. Do not compare struct
tag names or field names when computing canonical types.
(gimple_types_compatible_p): Adjust.
(visit): Take a gtc_mode argument.
(iterative_hash_gimple_type): Likewise. Do not hash struct tag
names or field names when computing hashes of canonical types.
(gimple_register_canonical_type): Use gimple_canonical_type_hash
for the hash.
(print_gimple_types_stats): Dump stats of canonical_type_hash_cache.
(free_gimple_type_tables): Free canonical_type_hash_cache.
2010-12-02 Richard Guenther <rguenther@suse.de>
Ira Rosen <irar@il.ibm.com> Ira Rosen <irar@il.ibm.com>
PR tree-optimization/46663 PR tree-optimization/46663
...@@ -47,6 +47,8 @@ static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node))) ...@@ -47,6 +47,8 @@ static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node)))
htab_t gimple_canonical_types; htab_t gimple_canonical_types;
static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map))) static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
htab_t type_hash_cache; htab_t type_hash_cache;
static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
htab_t canonical_type_hash_cache;
/* Global type comparison cache. This is by TYPE_UID for space efficiency /* Global type comparison cache. This is by TYPE_UID for space efficiency
and thus cannot use and does not need GC. */ and thus cannot use and does not need GC. */
...@@ -3131,7 +3133,7 @@ gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip) ...@@ -3131,7 +3133,7 @@ gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip)
} }
static hashval_t gimple_type_hash (const void *); static hashval_t gimple_type_hash_1 (const void *, enum gtc_mode);
/* Structure used to maintain a cache of some type pairs compared by /* Structure used to maintain a cache of some type pairs compared by
gimple_types_compatible_p when comparing aggregate types. There are gimple_types_compatible_p when comparing aggregate types. There are
...@@ -3474,7 +3476,7 @@ gtc_visit (tree t1, tree t2, enum gtc_mode mode, ...@@ -3474,7 +3476,7 @@ gtc_visit (tree t1, tree t2, enum gtc_mode mode,
/* If the hash values of t1 and t2 are different the types can't /* If the hash values of t1 and t2 are different the types can't
possibly be the same. This helps keeping the type-pair hashtable possibly be the same. This helps keeping the type-pair hashtable
small, only tracking comparisons for hash collisions. */ small, only tracking comparisons for hash collisions. */
if (gimple_type_hash (t1) != gimple_type_hash (t2)) if (gimple_type_hash_1 (t1, mode) != gimple_type_hash_1 (t2, mode))
return false; return false;
/* Allocate a new cache entry for this comparison. */ /* Allocate a new cache entry for this comparison. */
...@@ -3757,8 +3759,9 @@ gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode, ...@@ -3757,8 +3759,9 @@ gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
tree f1, f2; tree f1, f2;
/* The struct tags shall compare equal. */ /* The struct tags shall compare equal. */
if (!compare_type_names_p (TYPE_MAIN_VARIANT (t1), if (mode == GTC_MERGE
TYPE_MAIN_VARIANT (t2), false)) && !compare_type_names_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2), false))
goto different_types; goto different_types;
/* For aggregate types, all the fields must be the same. */ /* For aggregate types, all the fields must be the same. */
...@@ -3767,7 +3770,8 @@ gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode, ...@@ -3767,7 +3770,8 @@ gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
{ {
/* The fields must have the same name, offset and type. */ /* The fields must have the same name, offset and type. */
if (DECL_NAME (f1) != DECL_NAME (f2) if ((mode == GTC_MERGE
&& DECL_NAME (f1) != DECL_NAME (f2))
|| 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)
|| !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), mode, || !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), mode,
...@@ -3910,7 +3914,7 @@ gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode) ...@@ -3910,7 +3914,7 @@ gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode)
/* If the hash values of t1 and t2 are different the types can't /* If the hash values of t1 and t2 are different the types can't
possibly be the same. This helps keeping the type-pair hashtable possibly be the same. This helps keeping the type-pair hashtable
small, only tracking comparisons for hash collisions. */ small, only tracking comparisons for hash collisions. */
if (gimple_type_hash (t1) != gimple_type_hash (t2)) if (gimple_type_hash_1 (t1, mode) != gimple_type_hash_1 (t2, mode))
return false; return false;
/* 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
...@@ -3939,7 +3943,8 @@ gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode) ...@@ -3939,7 +3943,8 @@ gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode)
static hashval_t static hashval_t
iterative_hash_gimple_type (tree, hashval_t, VEC(tree, heap) **, iterative_hash_gimple_type (tree, hashval_t, VEC(tree, heap) **,
struct pointer_map_t *, struct obstack *); struct pointer_map_t *, struct obstack *,
enum gtc_mode);
/* DFS visit the edge from the callers type with state *STATE to T. /* DFS visit the edge from the callers type with state *STATE to T.
Update the callers type hash V with the hash for T if it is not part Update the callers type hash V with the hash for T if it is not part
...@@ -3950,7 +3955,7 @@ static hashval_t ...@@ -3950,7 +3955,7 @@ static hashval_t
visit (tree t, struct sccs *state, hashval_t v, visit (tree t, struct sccs *state, hashval_t v,
VEC (tree, heap) **sccstack, VEC (tree, heap) **sccstack,
struct pointer_map_t *sccstate, struct pointer_map_t *sccstate,
struct obstack *sccstate_obstack) struct obstack *sccstate_obstack, enum gtc_mode mode)
{ {
struct sccs *cstate = NULL; struct sccs *cstate = NULL;
struct tree_int_map m; struct tree_int_map m;
...@@ -3959,7 +3964,9 @@ visit (tree t, struct sccs *state, hashval_t v, ...@@ -3959,7 +3964,9 @@ visit (tree t, struct sccs *state, hashval_t v,
/* If there is a hash value recorded for this type then it can't /* If there is a hash value recorded for this type then it can't
possibly be part of our parent SCC. Simply mix in its hash. */ possibly be part of our parent SCC. Simply mix in its hash. */
m.base.from = t; m.base.from = t;
if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT)) if ((slot = htab_find_slot (mode == GTC_MERGE
? type_hash_cache : canonical_type_hash_cache,
&m, NO_INSERT))
&& *slot) && *slot)
return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, v); return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, v);
...@@ -3970,7 +3977,8 @@ visit (tree t, struct sccs *state, hashval_t v, ...@@ -3970,7 +3977,8 @@ visit (tree t, struct sccs *state, hashval_t v,
hashval_t tem; hashval_t tem;
/* Not yet visited. DFS recurse. */ /* Not yet visited. DFS recurse. */
tem = iterative_hash_gimple_type (t, v, tem = iterative_hash_gimple_type (t, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack,
mode);
if (!cstate) if (!cstate)
cstate = (struct sccs *)* pointer_map_contains (sccstate, t); cstate = (struct sccs *)* pointer_map_contains (sccstate, t);
state->low = MIN (state->low, cstate->low); state->low = MIN (state->low, cstate->low);
...@@ -4021,7 +4029,8 @@ static hashval_t ...@@ -4021,7 +4029,8 @@ static hashval_t
iterative_hash_gimple_type (tree type, hashval_t val, iterative_hash_gimple_type (tree type, hashval_t val,
VEC(tree, heap) **sccstack, VEC(tree, heap) **sccstack,
struct pointer_map_t *sccstate, struct pointer_map_t *sccstate,
struct obstack *sccstate_obstack) struct obstack *sccstate_obstack,
enum gtc_mode mode)
{ {
hashval_t v; hashval_t v;
void **slot; void **slot;
...@@ -4067,11 +4076,11 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4067,11 +4076,11 @@ iterative_hash_gimple_type (tree type, hashval_t val,
{ {
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v); v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
v = iterative_hash_name v = iterative_hash_name
(TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v); (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v);
} }
else else
v = visit (TREE_TYPE (type), state, v, v = visit (TREE_TYPE (type), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
} }
/* For integer types hash the types min/max values and the string flag. */ /* For integer types hash the types min/max values and the string flag. */
...@@ -4092,7 +4101,7 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4092,7 +4101,7 @@ iterative_hash_gimple_type (tree type, hashval_t val,
{ {
v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v); v = iterative_hash_hashval_t (TYPE_STRING_FLAG (type), v);
v = visit (TYPE_DOMAIN (type), state, v, v = visit (TYPE_DOMAIN (type), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
} }
/* Recurse for aggregates with a single element type. */ /* Recurse for aggregates with a single element type. */
...@@ -4100,7 +4109,7 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4100,7 +4109,7 @@ iterative_hash_gimple_type (tree type, hashval_t val,
|| TREE_CODE (type) == COMPLEX_TYPE || TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE) || TREE_CODE (type) == VECTOR_TYPE)
v = visit (TREE_TYPE (type), state, v, v = visit (TREE_TYPE (type), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
/* Incorporate function return and argument types. */ /* Incorporate function return and argument types. */
if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
...@@ -4111,18 +4120,18 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4111,18 +4120,18 @@ iterative_hash_gimple_type (tree type, hashval_t val,
/* For method types also incorporate their parent class. */ /* For method types also incorporate their parent class. */
if (TREE_CODE (type) == METHOD_TYPE) if (TREE_CODE (type) == METHOD_TYPE)
v = visit (TYPE_METHOD_BASETYPE (type), state, v, v = visit (TYPE_METHOD_BASETYPE (type), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
/* For result types allow mismatch in completeness. */ /* For result types allow mismatch in completeness. */
if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
{ {
v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v); v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
v = iterative_hash_name v = iterative_hash_name
(TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v); (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (type))), v);
} }
else else
v = visit (TREE_TYPE (type), state, v, v = visit (TREE_TYPE (type), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p)) for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
{ {
...@@ -4131,11 +4140,11 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4131,11 +4140,11 @@ iterative_hash_gimple_type (tree type, hashval_t val,
{ {
v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v); v = iterative_hash_hashval_t (TREE_CODE (TREE_VALUE (p)), v);
v = iterative_hash_name v = iterative_hash_name
(TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v); (TYPE_NAME (TYPE_MAIN_VARIANT (TREE_VALUE (p))), v);
} }
else else
v = visit (TREE_VALUE (p), state, v, v = visit (TREE_VALUE (p), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
na++; na++;
} }
...@@ -4149,13 +4158,15 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4149,13 +4158,15 @@ iterative_hash_gimple_type (tree type, hashval_t val,
unsigned nf; unsigned nf;
tree f; tree f;
v = iterative_hash_name (TYPE_NAME (TYPE_MAIN_VARIANT (type)), v); if (mode == GTC_MERGE)
v = iterative_hash_name (TYPE_NAME (TYPE_MAIN_VARIANT (type)), v);
for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f)) for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
{ {
v = iterative_hash_name (DECL_NAME (f), v); if (mode == GTC_MERGE)
v = iterative_hash_name (DECL_NAME (f), v);
v = visit (TREE_TYPE (f), state, v, v = visit (TREE_TYPE (f), state, v,
sccstack, sccstate, sccstate_obstack); sccstack, sccstate, sccstate_obstack, mode);
nf++; nf++;
} }
...@@ -4180,7 +4191,9 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4180,7 +4191,9 @@ iterative_hash_gimple_type (tree type, hashval_t val,
cstate->on_sccstack = false; cstate->on_sccstack = false;
m->base.from = x; m->base.from = x;
m->to = cstate->u.hash; m->to = cstate->u.hash;
slot = htab_find_slot (type_hash_cache, m, INSERT); slot = htab_find_slot (mode == GTC_MERGE
? type_hash_cache : canonical_type_hash_cache,
m, INSERT);
gcc_assert (!*slot); gcc_assert (!*slot);
*slot = (void *) m; *slot = (void *) m;
} }
...@@ -4200,7 +4213,7 @@ iterative_hash_gimple_type (tree type, hashval_t val, ...@@ -4200,7 +4213,7 @@ iterative_hash_gimple_type (tree type, hashval_t val,
types according to gimple_types_compatible_p. */ types according to gimple_types_compatible_p. */
static hashval_t static hashval_t
gimple_type_hash (const void *p) gimple_type_hash_1 (const void *p, enum gtc_mode mode)
{ {
const_tree t = (const_tree) p; const_tree t = (const_tree) p;
VEC(tree, heap) *sccstack = NULL; VEC(tree, heap) *sccstack = NULL;
...@@ -4210,12 +4223,19 @@ gimple_type_hash (const void *p) ...@@ -4210,12 +4223,19 @@ gimple_type_hash (const void *p)
void **slot; void **slot;
struct tree_int_map m; struct tree_int_map m;
if (type_hash_cache == NULL) if (mode == GTC_MERGE
&& type_hash_cache == NULL)
type_hash_cache = htab_create_ggc (512, tree_int_map_hash, type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
tree_int_map_eq, NULL); tree_int_map_eq, NULL);
else if (mode == GTC_DIAG
&& canonical_type_hash_cache == NULL)
canonical_type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
tree_int_map_eq, NULL);
m.base.from = CONST_CAST_TREE (t); m.base.from = CONST_CAST_TREE (t);
if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT)) if ((slot = htab_find_slot (mode == GTC_MERGE
? type_hash_cache : canonical_type_hash_cache,
&m, NO_INSERT))
&& *slot) && *slot)
return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, 0); return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, 0);
...@@ -4224,7 +4244,8 @@ gimple_type_hash (const void *p) ...@@ -4224,7 +4244,8 @@ gimple_type_hash (const void *p)
sccstate = pointer_map_create (); sccstate = pointer_map_create ();
gcc_obstack_init (&sccstate_obstack); gcc_obstack_init (&sccstate_obstack);
val = iterative_hash_gimple_type (CONST_CAST_TREE (t), 0, val = iterative_hash_gimple_type (CONST_CAST_TREE (t), 0,
&sccstack, sccstate, &sccstate_obstack); &sccstack, sccstate, &sccstate_obstack,
mode);
VEC_free (tree, heap, sccstack); VEC_free (tree, heap, sccstack);
pointer_map_destroy (sccstate); pointer_map_destroy (sccstate);
obstack_free (&sccstate_obstack, NULL); obstack_free (&sccstate_obstack, NULL);
...@@ -4232,6 +4253,18 @@ gimple_type_hash (const void *p) ...@@ -4232,6 +4253,18 @@ gimple_type_hash (const void *p)
return val; return val;
} }
static hashval_t
gimple_type_hash (const void *p)
{
return gimple_type_hash_1 (p, GTC_MERGE);
}
static hashval_t
gimple_canonical_type_hash (const void *p)
{
return gimple_type_hash_1 (p, GTC_DIAG);
}
/* Returns nonzero if P1 and P2 are equal. */ /* Returns nonzero if P1 and P2 are equal. */
...@@ -4399,7 +4432,7 @@ gimple_register_canonical_type (tree t) ...@@ -4399,7 +4432,7 @@ gimple_register_canonical_type (tree t)
gimple_register_canonical_type (TYPE_MAIN_VARIANT (t)); gimple_register_canonical_type (TYPE_MAIN_VARIANT (t));
if (gimple_canonical_types == NULL) if (gimple_canonical_types == NULL)
gimple_canonical_types = htab_create_ggc (16381, gimple_type_hash, gimple_canonical_types = htab_create_ggc (16381, gimple_canonical_type_hash,
gimple_canonical_type_eq, 0); gimple_canonical_type_eq, 0);
slot = htab_find_slot (gimple_canonical_types, t, INSERT); slot = htab_find_slot (gimple_canonical_types, t, INSERT);
...@@ -4439,6 +4472,16 @@ print_gimple_types_stats (void) ...@@ -4439,6 +4472,16 @@ print_gimple_types_stats (void)
htab_collisions (gimple_types)); htab_collisions (gimple_types));
else else
fprintf (stderr, "GIMPLE type table is empty\n"); fprintf (stderr, "GIMPLE type table is empty\n");
if (type_hash_cache)
fprintf (stderr, "GIMPLE type hash table: size %ld, %ld elements, "
"%ld searches, %ld collisions (ratio: %f)\n",
(long) htab_size (type_hash_cache),
(long) htab_elements (type_hash_cache),
(long) type_hash_cache->searches,
(long) type_hash_cache->collisions,
htab_collisions (type_hash_cache));
else
fprintf (stderr, "GIMPLE type hash table is empty\n");
if (gimple_canonical_types) if (gimple_canonical_types)
fprintf (stderr, "GIMPLE canonical type table: size %ld, %ld elements, " fprintf (stderr, "GIMPLE canonical type table: size %ld, %ld elements, "
"%ld searches, %ld collisions (ratio: %f)\n", "%ld searches, %ld collisions (ratio: %f)\n",
...@@ -4449,16 +4492,16 @@ print_gimple_types_stats (void) ...@@ -4449,16 +4492,16 @@ print_gimple_types_stats (void)
htab_collisions (gimple_canonical_types)); htab_collisions (gimple_canonical_types));
else else
fprintf (stderr, "GIMPLE canonical type table is empty\n"); fprintf (stderr, "GIMPLE canonical type table is empty\n");
if (type_hash_cache) if (canonical_type_hash_cache)
fprintf (stderr, "GIMPLE type hash table: size %ld, %ld elements, " fprintf (stderr, "GIMPLE canonical type hash table: size %ld, %ld elements, "
"%ld searches, %ld collisions (ratio: %f)\n", "%ld searches, %ld collisions (ratio: %f)\n",
(long) htab_size (type_hash_cache), (long) htab_size (canonical_type_hash_cache),
(long) htab_elements (type_hash_cache), (long) htab_elements (canonical_type_hash_cache),
(long) type_hash_cache->searches, (long) canonical_type_hash_cache->searches,
(long) type_hash_cache->collisions, (long) canonical_type_hash_cache->collisions,
htab_collisions (type_hash_cache)); htab_collisions (canonical_type_hash_cache));
else else
fprintf (stderr, "GIMPLE type hash table is empty\n"); fprintf (stderr, "GIMPLE canonical type hash table is empty\n");
if (gtc_visited) if (gtc_visited)
fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld " fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
"elements, %ld searches, %ld collisions (ratio: %f)\n", "elements, %ld searches, %ld collisions (ratio: %f)\n",
...@@ -4495,6 +4538,11 @@ free_gimple_type_tables (void) ...@@ -4495,6 +4538,11 @@ free_gimple_type_tables (void)
htab_delete (type_hash_cache); htab_delete (type_hash_cache);
type_hash_cache = NULL; type_hash_cache = NULL;
} }
if (canonical_type_hash_cache)
{
htab_delete (canonical_type_hash_cache);
canonical_type_hash_cache = NULL;
}
if (gtc_visited) if (gtc_visited)
{ {
htab_delete (gtc_visited); htab_delete (gtc_visited);
......
2010-12-02 Richard Guenther <rguenther@suse.de> 2010-12-02 Richard Guenther <rguenther@suse.de>
PR lto/44871
* g++.dg/lto/20101126-1_0.C: New testcase.
* g++.dg/lto/20101126-1_1.c: Likewise.
2010-12-02 Richard Guenther <rguenther@suse.de>
Ira Rosen <irar@il.ibm.com> Ira Rosen <irar@il.ibm.com>
PR tree-optimization/46663 PR tree-optimization/46663
......
typedef struct { int i; } T1;
typedef T1 T2;
extern T1 a;
extern T2 b;
int main() { return a.i + b.i; }
typedef struct { int i; } T1;
typedef T1 T2;
T1 a;
T2 b;
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