[PCH] Automatically generate roots for htab caches
Geoffrey Keating
geoffk@romulus.sfbay.redhat.com
Tue May 14 16:08:00 GMT 2002
This is done mostly so that gengtype knows which routines it must
generate.
Bootstrapped & tested on i686-pc-linux-gnu with gcac checking.
--
Geoff Keating <geoffk@redhat.com>
===File ~/patches/pchbranch-autocache.patch=================
Index: ChangeLog
2002-05-13 Geoffrey Keating <geoffk@redhat.com>
* emit-rtl.c (const_int_htab): Use gengtype to clear unused entries.
(mem_attrs_htab): Likewise.
(init_emit_once): Don't call ggc_add_deletable_htab.
* fold-const.c (size_htab): Use gengtype to clear unused entries.
(size_int_type_wide): Don't call ggc_add_deletable_htab.
* gengtype.c (finish_root_table): Add LASTNAME and TNAME
parameters, use them, change callers.
(write_gc_root): Add IF_MARKED parameter, use it, change callers.
(write_gc_roots): Handle 'if_marked' option.
(main): Don't need to call set_gc_used_type any more.
* ggc.h (ggc_htab_marked_p): Delete.
(ggc_htab_mark): Delete.
(struct ggc_cache_tab): New.
(gt_ggc_cache_rtab): New declaration.
* ggc-common.c (struct d_htab_root): Delete.
(d_htab_roots): Delete.
(ggc_add_deletable_htab): Delete.
(ggc_htab_delete): Handle new htab-deleting mechanism.
(ggc_mark_roots): Use new htab-deleting mechanism.
* tree.c (type_hash_table): Use gengtype to clear unused entries.
Make static.
(init_obstacks): Don't call ggc_add_deletable_htab.
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.242.4.8
diff -p -u -p -r1.242.4.8 emit-rtl.c
--- emit-rtl.c 6 May 2002 18:43:56 -0000 1.242.4.8
+++ emit-rtl.c 14 May 2002 00:06:57 -0000
@@ -143,10 +143,12 @@ rtx const_int_rtx[MAX_SAVED_CONST_INT *
/* A hash table storing CONST_INTs whose absolute value is greater
than MAX_SAVED_CONST_INT. */
-static htab_t const_int_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+ htab_t const_int_htab;
/* A hash table storing memory attribute structures. */
-static htab_t mem_attrs_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
+ htab_t mem_attrs_htab;
/* start_sequence and gen_sequence can make a lot of rtx expressions which are
shortly thrown away. We use two mechanisms to prevent this waste:
@@ -4767,11 +4769,9 @@ init_emit_once (line_numbers)
/* Initialize the CONST_INT and memory attribute hash tables. */
const_int_htab = htab_create (37, const_int_htab_hash,
const_int_htab_eq, NULL);
- ggc_add_deletable_htab (const_int_htab, 0, 0);
mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
mem_attrs_htab_eq, NULL);
- ggc_add_deletable_htab (mem_attrs_htab, 0, gt_ggc_m_mem_attrs);
no_line_numbers = ! line_numbers;
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.181.4.4
diff -p -u -p -r1.181.4.4 fold-const.c
--- fold-const.c 6 May 2002 18:44:09 -0000 1.181.4.4
+++ fold-const.c 14 May 2002 00:06:58 -0000
@@ -1373,8 +1373,10 @@ size_int_wide (number, kind)
/* Likewise, but the desired type is specified explicitly. */
-static GTY(()) tree new_const;
-static htab_t size_htab;
+static GTY (()) tree new_const;
+static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
+ htab_t size_htab;
+
tree
size_int_type_wide (number, type)
HOST_WIDE_INT number;
@@ -1385,7 +1387,6 @@ size_int_type_wide (number, type)
if (size_htab == 0)
{
size_htab = htab_create (1024, size_htab_hash, size_htab_eq, NULL);
- ggc_add_deletable_htab (size_htab, NULL, NULL);
new_const = make_node (INTEGER_CST);
}
Index: gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gengtype.c,v
retrieving revision 1.1.2.17
diff -p -u -p -r1.1.2.17 gengtype.c
--- gengtype.c 12 May 2002 06:11:46 -0000 1.1.2.17
+++ gengtype.c 14 May 2002 00:06:59 -0000
@@ -773,14 +773,24 @@ close_output_files PARAMS ((void))
}
}
+struct flist {
+ struct flist *next;
+ int started_p;
+ const char *name;
+ FILE *f;
+};
+
static void write_gc_structure_fields
PARAMS ((FILE *, type_p, const char *, const char *, options_p,
int, struct fileloc *, lang_bitmap, type_p));
static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p));
static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
static void put_mangled_filename PARAMS ((FILE *, const char *));
+static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
+ const char *tname, const char *lastname,
+ const char *name));
static void write_gc_root PARAMS ((FILE *, pair_p, type_p, const char *, int,
- struct fileloc *));
+ struct fileloc *, const char *));
static void write_gc_roots PARAMS ((pair_p));
static int gc_counter;
@@ -1352,15 +1362,13 @@ put_mangled_filename (f, fn)
fputc ('_', f);
}
-struct flist {
- struct flist *next;
- int started_p;
- const char *name;
- FILE *f;
-};
-
static void
-finish_root_table (struct flist *flp, const char *pfx, const char *name)
+finish_root_table (flp, pfx, lastname, tname, name)
+ struct flist *flp;
+ const char *pfx;
+ const char *tname;
+ const char *lastname;
+ const char *name;
{
struct flist *fli2;
unsigned started_bitmap = 0;
@@ -1368,7 +1376,7 @@ finish_root_table (struct flist *flp, co
for (fli2 = flp; fli2; fli2 = fli2->next)
if (fli2->started_p)
{
- fputs (" LAST_GGC_ROOT_TAB\n", fli2->f);
+ fprintf (fli2->f, " %s\n", lastname);
fputs ("};\n\n", fli2->f);
}
@@ -1382,8 +1390,8 @@ finish_root_table (struct flist *flp, co
if (bitmap & 1)
{
fprintf (base_files[fnum],
- "extern const struct ggc_root_tab gt_ggc_%s_",
- pfx);
+ "extern const struct %s gt_ggc_%s_",
+ tname, pfx);
put_mangled_filename (base_files[fnum], fli2->name);
fputs ("[];\n", base_files[fnum]);
}
@@ -1403,8 +1411,8 @@ finish_root_table (struct flist *flp, co
if (! (started_bitmap & (1 << fnum)))
{
fprintf (base_files [fnum],
- "const struct ggc_root_tab * const %s[] = {\n",
- name);
+ "const struct %s * const %s[] = {\n",
+ tname, name);
started_bitmap |= 1 << fnum;
}
fprintf (base_files[fnum], " gt_ggc_%s_", pfx);
@@ -1427,13 +1435,14 @@ finish_root_table (struct flist *flp, co
}
static void
-write_gc_root (f, v, type, name, has_length, line)
+write_gc_root (f, v, type, name, has_length, line, if_marked)
FILE *f;
pair_p v;
type_p type;
const char *name;
int has_length;
struct fileloc *line;
+ const char *if_marked;
{
switch (type->kind)
{
@@ -1488,7 +1497,8 @@ write_gc_root (f, v, type, name, has_len
+ strlen (validf->name));
sprintf (newname, "%s.%s.%s",
name, fld->name, validf->name);
- write_gc_root (f, v, validf->type, newname, 0, line);
+ write_gc_root (f, v, validf->type, newname, 0, line,
+ if_marked);
free (newname);
}
}
@@ -1501,7 +1511,7 @@ write_gc_root (f, v, type, name, has_len
char *newname;
newname = xmalloc (strlen (name) + 2 + strlen (fld->name));
sprintf (newname, "%s.%s", name, fld->name);
- write_gc_root (f, v, fld->type, newname, 0, line);
+ write_gc_root (f, v, fld->type, newname, 0, line, if_marked);
free (newname);
}
}
@@ -1513,7 +1523,7 @@ write_gc_root (f, v, type, name, has_len
char *newname;
newname = xmalloc (strlen (name) + 4);
sprintf (newname, "%s[0]", name);
- write_gc_root (f, v, type->u.a.p, newname, has_length, line);
+ write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
free (newname);
}
break;
@@ -1543,11 +1553,11 @@ write_gc_root (f, v, type, name, has_len
if (! has_length
&& (tp->kind == TYPE_UNION || tp->kind == TYPE_STRUCT))
{
- fprintf (f, " >_ggc_m_%s\n", tp->u.s.tag);
+ fprintf (f, " >_ggc_m_%s", tp->u.s.tag);
}
else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
{
- fprintf (f, " >_ggc_mm_%d%s_%s\n",
+ fprintf (f, " >_ggc_mm_%d%s_%s",
strlen (tp->u.param_struct.param->u.s.tag),
tp->u.param_struct.param->u.s.tag,
tp->u.param_struct.stru->u.s.tag);
@@ -1555,7 +1565,7 @@ write_gc_root (f, v, type, name, has_len
else if (has_length
&& tp->kind == TYPE_POINTER)
{
- fprintf (f, " >_ggc_ma_%s\n", name);
+ fprintf (f, " >_ggc_ma_%s", name);
}
else
{
@@ -1563,7 +1573,9 @@ write_gc_root (f, v, type, name, has_len
"global `%s' is pointer to unimplemented type",
name);
}
- fputs (" },\n", f);
+ if (if_marked)
+ fprintf (f, ",\n &%s", if_marked);
+ fputs ("\n },\n", f);
}
break;
@@ -1600,6 +1612,8 @@ write_gc_roots (variables)
deletable_p = 1;
else if (strcmp (o->name, "param_is") == 0)
;
+ else if (strcmp (o->name, "if_marked") == 0)
+ ;
else
error_at_line (&v->line,
"global `%s' has unknown option `%s'",
@@ -1677,16 +1691,17 @@ write_gc_roots (variables)
FILE *f = get_output_file_with_visibility (v->line.file);
struct flist *fli;
const char *length = NULL;
- int deletable_p = 0;
+ int skip_p = 0;
options_p o;
for (o = v->opt; o; o = o->next)
if (strcmp (o->name, "length") == 0)
length = (const char *)o->info;
- else if (strcmp (o->name, "deletable") == 0)
- deletable_p = 1;
+ else if (strcmp (o->name, "deletable") == 0
+ || strcmp (o->name, "if_marked") == 0)
+ skip_p = 1;
- if (deletable_p)
+ if (skip_p)
continue;
for (fli = flp; fli; fli = fli->next)
@@ -1701,23 +1716,26 @@ write_gc_roots (variables)
fputs ("[] = {\n", f);
}
- write_gc_root (f, v, v->type, v->name, length != NULL, &v->line);
+ write_gc_root (f, v, v->type, v->name, length != NULL, &v->line, NULL);
}
- finish_root_table (flp, "r", "gt_ggc_rtab");
+ finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+ "gt_ggc_rtab");
for (v = variables; v; v = v->next)
{
FILE *f = get_output_file_with_visibility (v->line.file);
struct flist *fli;
- int deletable_p = 0;
+ int skip_p = 1;
options_p o;
for (o = v->opt; o; o = o->next)
if (strcmp (o->name, "deletable") == 0)
- deletable_p = 1;
+ skip_p = 0;
+ else if (strcmp (o->name, "if_marked") == 0)
+ skip_p = 1;
- if (! deletable_p)
+ if (skip_p)
continue;
for (fli = flp; fli; fli = fli->next)
@@ -1736,7 +1754,52 @@ write_gc_roots (variables)
v->name, v->name);
}
- finish_root_table (flp, "rd", "gt_ggc_deletable_rtab");
+ finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+ "gt_ggc_deletable_rtab");
+
+ for (v = variables; v; v = v->next)
+ {
+ FILE *f = get_output_file_with_visibility (v->line.file);
+ struct flist *fli;
+ const char *if_marked = NULL;
+ const char *length = NULL;
+ options_p o;
+
+ for (o = v->opt; o; o = o->next)
+ if (strcmp (o->name, "length") == 0)
+ length = (const char *)o->info;
+ else if (strcmp (o->name, "if_marked") == 0)
+ if_marked = (const char *) o->info;
+
+ if (if_marked == NULL)
+ continue;
+
+ if (v->type->kind != TYPE_POINTER
+ || v->type->u.p->kind != TYPE_PARAM_STRUCT
+ || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
+ {
+ error_at_line (&v->line, "if_marked option used but not hash table");
+ continue;
+ }
+
+ for (fli = flp; fli; fli = fli->next)
+ if (fli->f == f)
+ break;
+ if (! fli->started_p)
+ {
+ fli->started_p = 1;
+
+ fputs ("const struct ggc_cache_tab gt_ggc_rc_", f);
+ put_mangled_filename (f, v->line.file);
+ fputs ("[] = {\n", f);
+ }
+
+ write_gc_root (f, v, create_pointer (v->type->u.p->u.param_struct.param),
+ v->name, length != NULL, &v->line, if_marked);
+ }
+
+ finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
+ "gt_ggc_cache_rtab");
}
@@ -1768,8 +1831,6 @@ main(argc, argv)
exit (1);
set_gc_used (variables);
- set_gc_used_type (find_structure ("mem_attrs", 0), GC_POINTED_TO);
- set_gc_used_type (find_structure ("type_hash", 0), GC_POINTED_TO);
open_base_files ();
write_gc_types (structures, param_structs);
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.46.4.13
diff -p -u -p -r1.46.4.13 ggc-common.c
--- ggc-common.c 12 May 2002 06:11:47 -0000 1.46.4.13
+++ ggc-common.c 14 May 2002 00:06:59 -0000
@@ -99,55 +99,6 @@ ggc_add_tree_varray_root (base, nelt)
ggc_mark_tree_varray_ptr);
}
-/* Add a hash table to be scanned when all roots have been processed. We
- delete any entry in the table that has not been marked. */
-
-struct d_htab_root
-{
- struct d_htab_root *next;
- htab_t htab;
- ggc_htab_marked_p marked_p;
- ggc_htab_mark mark;
-};
-
-static struct d_htab_root *d_htab_roots;
-
-/* Add X, an htab, to a list of htabs that contain objects which are allocated
- from GC memory. Once all other roots are marked, we check each object in
- the htab to see if it has already been marked. If not, it is deleted.
-
- MARKED_P, if specified, is a function that returns 1 if the entry is to
- be considered as "marked". If not present, the data structure pointed to
- by the htab slot is tested. This function should be supplied if some
- other object (such as something pointed to by that object) should be tested
- in which case the function tests whether that object (or objects) are
- marked (using ggc_marked_p) and returns nonzero if it is.
-
- MARK, if specified, is a function that is passed the contents of a slot
- that has been determined to have been "marked" (via the above function)
- and marks any other objects pointed to by that object. For example,
- we might have a hash table of memory attribute blocks, which are pointed
- to by a MEM RTL but have a pointer to a DECL. MARKED_P in that case will
- not be specified because we want to know if the attribute block is pointed
- to by the MEM, but MARK must be specified because if the block has been
- marked, we need to mark the DECL. */
-
-void
-ggc_add_deletable_htab (x, marked_p, mark)
- PTR x;
- ggc_htab_marked_p marked_p;
- ggc_htab_mark mark;
-{
- struct d_htab_root *r
- = (struct d_htab_root *) xmalloc (sizeof (struct d_htab_root));
-
- r->next = d_htab_roots;
- r->htab = (htab_t) x;
- r->marked_p = marked_p ? marked_p : ggc_marked_p;
- r->mark = mark;
- d_htab_roots = r;
-}
-
/* Process a slot of an htab by deleting it if it has not been marked. */
static int
@@ -155,12 +106,12 @@ ggc_htab_delete (slot, info)
void **slot;
void *info;
{
- struct d_htab_root *r = (struct d_htab_root *) info;
+ const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
if (! (*r->marked_p) (*slot))
- htab_clear_slot (r->htab, slot);
- else if (r->mark)
- (*r->mark) (*slot);
+ htab_clear_slot (*r->base, slot);
+ else
+ (*r->cb) (*slot);
return 1;
}
@@ -171,9 +122,10 @@ void
ggc_mark_roots ()
{
struct ggc_root *x;
- struct d_htab_root *y;
const struct ggc_root_tab *const *rt;
const struct ggc_root_tab *rti;
+ const struct ggc_cache_tab *const *ct;
+ const struct ggc_cache_tab *cti;
size_t i;
for (rt = gt_ggc_deletable_rtab; *rt; rt++)
@@ -198,8 +150,9 @@ ggc_mark_roots ()
/* Now scan all hash tables that have objects which are to be deleted if
they are not already marked. */
- for (y = d_htab_roots; y != NULL; y = y->next)
- htab_traverse (y->htab, ggc_htab_delete, (PTR) y);
+ for (ct = gt_ggc_cache_rtab; *ct; ct++)
+ for (cti = *ct; cti->base != NULL; cti++)
+ htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
}
/* R had not been previously marked, but has now been marked via
Index: ggc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc.h,v
retrieving revision 1.39.6.14
diff -p -u -p -r1.39.6.14 ggc.h
--- ggc.h 12 May 2002 06:11:47 -0000 1.39.6.14
+++ ggc.h 14 May 2002 00:06:59 -0000
@@ -50,16 +50,18 @@ struct ggc_root_tab {
extern const struct ggc_root_tab * const gt_ggc_rtab[];
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
-/* Types used for mark test and marking functions, if specified, in call
- below. */
-typedef int (*ggc_htab_marked_p) PARAMS ((const void *));
-typedef void (*ggc_htab_mark) PARAMS ((const void *));
-
-/* Add a hash table to be scanned when all roots have been processed. We
- delete any entry in the table that has not been marked. The argument is
- really htab_t. */
-extern void ggc_add_deletable_htab PARAMS ((PTR, ggc_htab_marked_p,
- ggc_htab_mark));
+/* Structure for hash table cache marking. */
+struct htab;
+struct ggc_cache_tab {
+ struct htab * *base;
+ size_t nelt;
+ size_t stride;
+ void (*cb) PARAMS ((void *));
+ int (*marked_p) PARAMS ((const void *));
+};
+#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL }
+/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
+extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
/* Mark nodes from the gc_add_root callback. These functions follow
pointers to mark other objects too. */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.230.2.8
diff -p -u -p -r1.230.2.8 tree.c
--- tree.c 10 May 2002 17:14:11 -0000 1.230.2.8
+++ tree.c 14 May 2002 00:07:00 -0000
@@ -120,7 +120,8 @@ struct type_hash GTY(())
same table, they are completely independent, and the hash code is
computed differently for each of these. */
-htab_t type_hash_table;
+static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash)))
+ htab_t type_hash_table;
static void set_type_quals PARAMS ((tree, int));
static void append_random_chars PARAMS ((char *));
@@ -144,8 +145,6 @@ init_obstacks ()
/* Initialize the hash table of types. */
type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
type_hash_eq, 0);
- ggc_add_deletable_htab (type_hash_table, type_hash_marked_p,
- gt_ggc_m_type_hash);
}
============================================================
More information about the Gcc-patches
mailing list