[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, "    &gt_ggc_m_%s\n", tp->u.s.tag);
+	    fprintf (f, "    &gt_ggc_m_%s", tp->u.s.tag);
 	  }
 	else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
 	  {
-	    fprintf (f, "    &gt_ggc_mm_%d%s_%s\n",
+	    fprintf (f, "    &gt_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, "    &gt_ggc_ma_%s\n", name);
+	    fprintf (f, "    &gt_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