* [PATCH] Re-enable ggc-collect during LTO streaming
@ 2010-09-08 14:09 Richard Guenther
0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2010-09-08 14:09 UTC (permalink / raw)
To: gcc-patches
This re-enables ggc-collecting during LTO-in streaming by moving the
type hash and table to GC memory.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c.orig 2010-09-08 11:30:18.000000000 +0200
--- gcc/gimple.c 2010-09-08 12:58:49.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 36,50 ****
#include "flags.h"
#include "alias.h"
#include "demangle.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;
! /* Global type comparison cache. */
static htab_t gtc_visited;
static struct obstack gtc_ob;
--- 36,54 ----
#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 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. 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;
*************** visit (tree t, struct sccs *state, hashv
*** 3916,3927 ****
struct obstack *sccstate_obstack)
{
struct sccs *cstate = NULL;
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);
if ((slot = pointer_map_contains (sccstate, t)) != NULL)
cstate = (struct sccs *)*slot;
--- 3920,3934 ----
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. */
! 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;
*************** iterative_hash_gimple_type (tree type, h
*** 3988,3996 ****
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));
#endif
state = XOBNEW (sccstate_obstack, struct sccs);
*pointer_map_insert (sccstate, type) = state;
--- 3995,4002 ----
struct sccs *state;
#ifdef ENABLE_CHECKING
! /* 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;
*************** iterative_hash_gimple_type (tree type, h
*** 4137,4148 ****
do
{
struct sccs *cstate;
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;
}
while (x != type);
}
--- 4143,4157 ----
do
{
struct sccs *cstate;
+ struct tree_int_map *m = ggc_alloc_cleared_tree_int_map ();
x = VEC_pop (tree, *sccstack);
cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
cstate->on_sccstack = false;
! 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);
}
*************** gimple_type_hash (const void *p)
*** 4168,4179 ****
struct obstack sccstate_obstack;
hashval_t val;
void **slot;
if (type_hash_cache == NULL)
! type_hash_cache = pointer_map_create ();
! if ((slot = pointer_map_contains (type_hash_cache, p)) != NULL)
! return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, 0);
/* Perform a DFS walk and pre-hash all reachable types. */
next_dfs_num = 1;
--- 4177,4192 ----
struct obstack sccstate_obstack;
hashval_t val;
void **slot;
+ struct tree_int_map m;
if (type_hash_cache == NULL)
! type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
! tree_int_map_eq, NULL);
! 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;
*************** gimple_register_type (tree t)
*** 4226,4232 ****
gimple_register_type (TYPE_MAIN_VARIANT (t));
if (gimple_types == NULL)
! gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0);
slot = htab_find_slot (gimple_types, t, INSERT);
if (*slot
--- 4239,4245 ----
gimple_register_type (TYPE_MAIN_VARIANT (t));
if (gimple_types == NULL)
! gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0);
slot = htab_find_slot (gimple_types, t, INSERT);
if (*slot
*************** print_gimple_types_stats (void)
*** 4312,4317 ****
--- 4325,4340 ----
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",
*************** free_gimple_type_tables (void)
*** 4340,4346 ****
}
if (type_hash_cache)
{
! pointer_map_destroy (type_hash_cache);
type_hash_cache = NULL;
}
if (gtc_visited)
--- 4363,4369 ----
}
if (type_hash_cache)
{
! htab_delete (type_hash_cache);
type_hash_cache = NULL;
}
if (gtc_visited)
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c.orig 2010-09-07 18:41:54.000000000 +0200
--- gcc/lto/lto.c 2010-09-08 12:52:05.000000000 +0200
*************** read_cgraph_and_symbols (unsigned nfiles
*** 1789,1796 ****
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. */
}
lto_flatten_files (decl_data, count, last_file_ix);
--- 1789,1795 ----
lto_obj_file_close (current_lto_file);
current_lto_file = NULL;
! ggc_collect ();
}
lto_flatten_files (decl_data, count, last_file_ix);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-09-08 13:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-08 14:09 [PATCH] Re-enable ggc-collect during LTO streaming Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).