gimple.c (gimple_types, [...]): Move to GC memory.

2010-09-08  Richard Guenther  <rguenther@suse.de>

	* gimple.c (gimple_types, type_hash_cache): Move to GC memory.
	(visit): Adjust.
	(iterative_hash_gimple_type): Likewise.
	(gimple_type_hash): Likewise.
	(gimple_register_type): Likewise.
	(print_gimple_types_stats): Likewise.
	(free_gimple_type_tables): Likewise.

	lto/
	* lto.c (read_cgraph_and_symbols): Collect again after each
	file.

From-SVN: r164001
This commit is contained in:
Richard Guenther 2010-09-08 13:30:39 +00:00 committed by Richard Biener
parent 813f2f136e
commit 0f443ad061
4 changed files with 55 additions and 18 deletions

View File

@ -1,3 +1,13 @@
2010-09-08 Richard Guenther <rguenther@suse.de>
* gimple.c (gimple_types, type_hash_cache): Move to GC memory.
(visit): Adjust.
(iterative_hash_gimple_type): Likewise.
(gimple_type_hash): Likewise.
(gimple_register_type): Likewise.
(print_gimple_types_stats): Likewise.
(free_gimple_type_tables): Likewise.
2010-09-08 Michael Matz <matz@suse.de>
PR tree-optimization/43430

View File

@ -36,15 +36,19 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "alias.h"
#include "demangle.h"
#include "langhooks.h"
/* Global type table. FIXME lto, it should be possible to re-use some
of the type hashing routines in tree.c (type_hash_canon, type_hash_lookup,
etc), but those assume that types were built with the various
build_*_type routines which is not the case with the streamer. */
static htab_t gimple_types;
static struct pointer_map_t *type_hash_cache;
static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node)))
htab_t gimple_types;
static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
htab_t type_hash_cache;
/* Global type comparison cache. */
/* Global type comparison cache. This is by TYPE_UID for space efficiency
and thus cannot use and does not need GC. */
static htab_t gtc_visited;
static struct obstack gtc_ob;
@ -3916,12 +3920,15 @@ visit (tree t, struct sccs *state, hashval_t v,
struct obstack *sccstate_obstack)
{
struct sccs *cstate = NULL;
struct tree_int_map m;
void **slot;
/* 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. */
if ((slot = pointer_map_contains (type_hash_cache, t)))
return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, v);
m.base.from = t;
if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT))
&& *slot)
return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, v);
if ((slot = pointer_map_contains (sccstate, t)) != NULL)
cstate = (struct sccs *)*slot;
@ -3988,9 +3995,8 @@ iterative_hash_gimple_type (tree type, hashval_t val,
struct sccs *state;
#ifdef ENABLE_CHECKING
/* Not visited during this DFS walk nor during previous walks. */
gcc_assert (!pointer_map_contains (type_hash_cache, type)
&& !pointer_map_contains (sccstate, type));
/* Not visited during this DFS walk. */
gcc_assert (!pointer_map_contains (sccstate, type));
#endif
state = XOBNEW (sccstate_obstack, struct sccs);
*pointer_map_insert (sccstate, type) = state;
@ -4137,12 +4143,15 @@ iterative_hash_gimple_type (tree type, hashval_t val,
do
{
struct sccs *cstate;
struct tree_int_map *m = ggc_alloc_cleared_tree_int_map ();
x = VEC_pop (tree, *sccstack);
gcc_assert (!pointer_map_contains (type_hash_cache, x));
cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
cstate->on_sccstack = false;
slot = pointer_map_insert (type_hash_cache, x);
*slot = (void *) (size_t) cstate->u.hash;
m->base.from = x;
m->to = cstate->u.hash;
slot = htab_find_slot (type_hash_cache, m, INSERT);
gcc_assert (!*slot);
*slot = (void *) m;
}
while (x != type);
}
@ -4168,12 +4177,16 @@ gimple_type_hash (const void *p)
struct obstack sccstate_obstack;
hashval_t val;
void **slot;
struct tree_int_map m;
if (type_hash_cache == NULL)
type_hash_cache = pointer_map_create ();
type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
tree_int_map_eq, NULL);
if ((slot = pointer_map_contains (type_hash_cache, p)) != NULL)
return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, 0);
m.base.from = CONST_CAST_TREE (t);
if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT))
&& *slot)
return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, 0);
/* Perform a DFS walk and pre-hash all reachable types. */
next_dfs_num = 1;
@ -4226,7 +4239,7 @@ gimple_register_type (tree t)
gimple_register_type (TYPE_MAIN_VARIANT (t));
if (gimple_types == NULL)
gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0);
gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0);
slot = htab_find_slot (gimple_types, t, INSERT);
if (*slot
@ -4312,6 +4325,16 @@ print_gimple_types_stats (void)
htab_collisions (gimple_types));
else
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 (gtc_visited)
fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
"elements, %ld searches, %ld collisions (ratio: %f)\n",
@ -4340,7 +4363,7 @@ free_gimple_type_tables (void)
}
if (type_hash_cache)
{
pointer_map_destroy (type_hash_cache);
htab_delete (type_hash_cache);
type_hash_cache = NULL;
}
if (gtc_visited)

View File

@ -1,3 +1,8 @@
2010-09-08 Richard Guenther <rguenther@suse.de>
* lto.c (read_cgraph_and_symbols): Collect again after each
file.
2010-09-07 Jan Hubicka <jh@suse.cz>
* lto.c (promote_var, promote_fn): Set DECL_VISIBILITY_SPECIFIED.

View File

@ -1789,8 +1789,7 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
lto_obj_file_close (current_lto_file);
current_lto_file = NULL;
/* ??? We'd want but can't ggc_collect () here as the type merging
code in gimple.c uses hashtables that are not ggc aware. */
ggc_collect ();
}
lto_flatten_files (decl_data, count, last_file_ix);