This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ping patch] enhancing gengtype for plugins?


Basile STARYNKEVITCH wrote:
Hello All,

I am pinging http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00254.html with a small improvement (ability to handle several plugin files) and some documentation.

Please note that the PLUGIN_REGISTER_GGC_ROOTS pseudo-event nearly requires
such a facility, or an equivalent one. How could one use PLUGIN_REGISTER_GGC_ROOTS
without a GGC root table generated by gengtype (the alternative would be to hack gengtype to generate additional stuff, and cut&paste generated code into the plugin.c; that would be dirty!).



I am pinging again the patch. I resubmit it here (corrected some typos in source: missing space...)


This patch is very small, and perhaps not very clever, in the sense that it does the same work as the original gengtype, except that for plugins it does not print to files outside the plugin but all the computation remains the same; that seems ok to me because 1] gengtype runs fast enough. 2] it is not needed to rerun it extremely often. 3] hence the patch is very small, and hopefully easy to review.

On Wed, Jun 03, 2009 at 11:07:45AM +0200, Basile Starynkevitch wrote:
Dear All,

I suggest to enhance the gengtype generator, so that,

1. It behaves as usual with the two arguments (sourcedir and filelist)
-hence nothing is broken...

2. In addition, when invoked as

gengtype -p sourcedir filelist plugin1.c plugin2.c


here the sourcedir & filelist is as usual, and the plugin*.c are new files (you can have one or more such files) inside a plugin (not listed in the filelist), its generates a gt-plugin1.h
and gt-plugin2.h (one for each file plugin*.c, which are using GTY).

This patch is against trunk rev r148434. The gcc/ChangeLog is the same (except the date) as in previous submission


gcc/ChangeLog:
2009-06-12 Basile Starynkevitch <basile@starynkevitch.net>
* doc/plugins.texi (Interacting with the GCC Garbage Collector): Mention the plugin mode
of gengtype.
* doc/gty.texi (Source Files Containing Type Information): Likewise.
* gengtype.c: Updated copyright.


   (plugin_files, nb_plugin_files) Added new static variables.
   (measure_input_list) Care about plugin_files.
   (write_rtx_next): Added early return in plugin mode.
   (create_file): Updated copyright year in generated file. Added asserts.
   (oprintf): Added early return if null outf.
   (get_output_file_with_visibility): Care of plugin_files.
   (get_output_file_name): May return null.
   (close_output_files) Emit a verbose message in plugin mode.
   (write_local): Added early return.
   (put_mangled_filename): Ditto.
   (finish_root_table): Added check for base_files.
   (write_roots): Care about null when plugins.
   (main): added plugin mode.

Bootstrapped on x86_64-linux-gnu (Debian/Sid/AMD64). The extra functionality has been tested - see http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00255.html.
The usual functionality (the GTY handling inside GCC) did not change.


Ok for trunk?


-- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mines, sont seulement les miennes} ***

Index: gcc/doc/plugins.texi
===================================================================
--- gcc/doc/plugins.texi	(revision 148436)
+++ gcc/doc/plugins.texi	(working copy)
@@ -198,13 +198,15 @@ Some plugins may need to have GGC mark additional
 done by registering a callback (called with a null @code{gcc_data})
 for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the
 @code{ggc_set_mark} routine, preferably thru the @code{ggc_mark} macro
-(and conversly, these routines should usually not be used in plugins
-outside of the @code{PLUGIN_GGC_MARKING} event).
+(and conversely, these routines should usually not be used in plugins
+outside of the @code{PLUGIN_GGC_MARKING} event).  
 
 Some plugins may need to add extra GGC root tables, e.g. to handle
 their own @code{GTY}-ed data. This can be done with the
-@code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and the
-extra root table as @code{user_data}.
+@code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and
+the extra root table as @code{user_data}.  Running the @code{gengtype
+-p @var{source-dir} @var{file-list} @var{plugin*.c} ...} utility
+generates this extra root table.
 
 You should understand the details of memory management inside GCC
 before using @code{PLUGIN_GGC_MARKING} or
Index: gcc/doc/gty.texi
===================================================================
--- gcc/doc/gty.texi	(revision 148436)
+++ gcc/doc/gty.texi	(working copy)
@@ -450,6 +450,13 @@ For language frontends, there is another file that
 somewhere.  It will be called @file{gtype-@var{lang}.h}, where
 @var{lang} is the name of the subdirectory the language is contained in.
 
+Plugins can add additional root tables.  Run the @code{gengtype}
+utility in plugin mode as @code{gengtype -p @var{source-dir}
+@var{file-list} @var{plugin*.c}} with your plugin files
+@var{plugin*.c} using @code{GTY} to generate the corresponding
+@var{gt-plugin*.h} files.
+
+
 @node Invoking the garbage collector
 @section How to invoke the garbage collector
 @cindex garbage collector, invocation
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c	(revision 148436)
+++ gcc/gengtype.c	(working copy)
@@ -128,18 +128,24 @@ typedef struct outf * outf_p;
 
 /* An output file, suitable for definitions, that can see declarations
    made in INPUT_FILE and is linked into every language that uses
-   INPUT_FILE.  */
+   INPUT_FILE.  May return null in plugin mode. */
 extern outf_p get_output_file_with_visibility
    (const char *input_file);
 const char *get_output_file_name (const char *);
 
-/* Print, like fprintf, to O.  */
+/* Print, like fprintf, to O.  No-op if O is nil. */
 static void oprintf (outf_p o, const char *S, ...)
      ATTRIBUTE_PRINTF_2;
 
 /* The list of output files.  */
 static outf_p output_files;
 
+/* the plugin input files and their number; in that case only
+   corresponding gt-<plugin>.h are generated in the current
+   directory. */
+static char** plugin_files;
+static int nb_plugin_files;
+
 /* The output header file that is included into pretty much every
    source file.  */
 static outf_p header_file;
@@ -274,7 +280,7 @@ measure_input_list (FILE *list)
   int c;
   bool atbol = true;
   num_lang_dirs = 0;
-  num_gt_files = 0;
+  num_gt_files = plugin_files ? nb_plugin_files : 0;
   while ((c = getc (list)) != EOF)
     {
       n++;
@@ -455,6 +461,12 @@ read_input_list (const char *listname)
       /* Update the global counts now that we know accurately how many
 	 things there are.  (We do not bother resizing the arrays down.)  */
       num_lang_dirs = langno;
+      /* add the plugin files if provided */
+      if (plugin_files) {
+	int i=0;
+	for (i=0; i<nb_plugin_files; i++)
+	  gt_files[nfiles++] = plugin_files[i];
+      }
       num_gt_files = nfiles;
     }
 
@@ -962,6 +974,8 @@ write_rtx_next (void)
 {
   outf_p f = get_output_file_with_visibility (NULL);
   int i;
+  if (!f) 
+    return;
 
   oprintf (f, "\n/* Used to implement the RTX_NEXT macro.  */\n");
   oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
@@ -1449,7 +1463,7 @@ static outf_p
 create_file (const char *name, const char *oname)
 {
   static const char *const hdr[] = {
-    "   Copyright (C) 2004, 2007 Free Software Foundation, Inc.\n",
+    "   Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n",
     "\n",
     "This file is part of GCC.\n",
     "\n",
@@ -1472,6 +1486,8 @@ create_file (const char *name, const char *oname)
   outf_p f;
   size_t i;
 
+  gcc_assert (name != NULL);
+  gcc_assert (oname != NULL);
   f = XCNEW (struct outf);
   f->next = output_files;
   f->name = oname;
@@ -1495,6 +1511,11 @@ oprintf (outf_p o, const char *format, ...)
   size_t slength;
   va_list ap;
 
+  /* in plugin mode, the O could be a null pointer, so avoid crashing
+     in that case */
+  if (!o) 
+    return;
+
   va_start (ap, format);
   slength = vasprintf (&s, format, ap);
   if (s == NULL || (int)slength < 0)
@@ -1524,6 +1545,9 @@ open_base_files (void)
 {
   size_t i;
 
+  if (nb_plugin_files > 0 && plugin_files)
+    return;
+
   header_file = create_file ("GCC", "gtype-desc.h");
 
   base_files = XNEWVEC (outf_p, num_lang_dirs);
@@ -1686,6 +1710,18 @@ get_output_file_with_visibility (const char *input
   if (input_file == NULL)
     input_file = "system.h";
 
+  /* in plugin mode, return null unless the input_file is one of the
+     plugin_files */
+  if (plugin_files && nb_plugin_files > 0) 
+    { 
+      int ix= -1, i;
+      for (i= 0; i<nb_plugin_files && ix<0; i++)
+      if (!strcmp(input_file, plugin_files[i])) 
+	ix=i;
+      if (ix<0) 
+	return NULL;
+    }
+
   /* Determine the output file name.  */
   basename = get_file_basename (input_file);
 
@@ -1737,6 +1773,7 @@ get_output_file_with_visibility (const char *input
   /* If not, create it.  */
   r = create_file (for_name, output_name);
 
+  gcc_assert(r && r->name);
   return r;
 }
 
@@ -1747,7 +1784,10 @@ get_output_file_with_visibility (const char *input
 const char *
 get_output_file_name (const char *input_file)
 {
-  return get_output_file_with_visibility (input_file)->name;
+  outf_p o =  get_output_file_with_visibility (input_file);
+  if (o)
+    return o->name;
+  return NULL;
 }
 
 /* Copy the output to its final destination,
@@ -1787,6 +1827,9 @@ close_output_files (void)
 	fatal ("opening output file %s: %s", of->name, strerror (errno));
       if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
 	fatal ("writing output file %s: %s", of->name, strerror (errno));
+      if (plugin_files && nb_plugin_files > 0)
+	fprintf (stderr, "gengtype wrote output file %s for plugins\n",
+		 of->name);
       if (fclose (newfile) != 0)
 	fatal ("closing output file %s: %s", of->name, strerror (errno));
     }
@@ -2812,7 +2855,6 @@ write_local_func_for_structure (type_p orig_s, typ
 
   memset (&d, 0, sizeof (d));
   d.of = get_output_file_with_visibility (fn);
-
   d.process_field = write_types_local_process_field;
   d.opt = s->u.s.opt;
   d.line = &s->u.s.line;
@@ -2848,6 +2890,8 @@ write_local (type_p structures, type_p param_struc
 {
   type_p s;
 
+  if (!header_file) 
+    return;
   oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
   for (s = structures; s; s = s->next)
     if (s->gc_used == GC_POINTED_TO
@@ -2933,6 +2977,8 @@ write_enum_defn (type_p structures, type_p param_s
 {
   type_p s;
 
+  if (!header_file) 
+    return;
   oprintf (header_file, "\n/* Enumeration of types known.  */\n");
   oprintf (header_file, "enum gt_types_enum {\n");
   for (s = structures; s; s = s->next)
@@ -2983,6 +3029,8 @@ static void
 put_mangled_filename (outf_p f, const char *fn)
 {
   const char *name = get_output_file_name (fn);
+  if (!f || !name) 
+    return;
   for (; *name != 0; name++)
     if (ISALNUM (*name))
       oprintf (f, "%c", *name);
@@ -3007,7 +3055,7 @@ finish_root_table (struct flist *flp, const char *
 	oprintf (fli2->f, "};\n\n");
       }
 
-  for (fli2 = flp; fli2; fli2 = fli2->next)
+  for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
     if (fli2->started_p)
       {
 	lang_bitmap bitmap = get_lang_bitmap (fli2->name);
@@ -3026,7 +3074,7 @@ finish_root_table (struct flist *flp, const char *
 
   {
     size_t fnum;
-    for (fnum = 0; fnum < num_lang_dirs; fnum++)
+    for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
       oprintf (base_files [fnum],
 	       "EXPORTED_CONST struct %s * const %s[] = {\n",
 	       tname, name);
@@ -3041,7 +3089,7 @@ finish_root_table (struct flist *flp, const char *
 
 	fli2->started_p = 0;
 
-	for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
+	for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
 	  if (bitmap & 1)
 	    {
 	      oprintf (base_files[fnum], "  gt_%s_", pfx);
@@ -3052,7 +3100,7 @@ finish_root_table (struct flist *flp, const char *
 
   {
     size_t fnum;
-    for (fnum = 0; fnum < num_lang_dirs; fnum++)
+    for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
       {
 	oprintf (base_files[fnum], "  NULL\n");
 	oprintf (base_files[fnum], "};\n");
@@ -3309,7 +3357,7 @@ write_roots (pair_p variables)
 			 v->name, o->name);
 
       for (fli = flp; fli; fli = fli->next)
-	if (fli->f == f)
+	if (fli->f == f && f)
 	  break;
       if (fli == NULL)
 	{
@@ -3318,6 +3366,7 @@ write_roots (pair_p variables)
 	  fli->next = flp;
 	  fli->started_p = 0;
 	  fli->name = v->line.file;
+	  gcc_assert(fli->name);
 	  flp = fli;
 
 	  oprintf (f, "\n/* GC roots.  */\n\n");
@@ -3586,17 +3635,29 @@ main (int argc, char **argv)
 {
   size_t i;
   static struct fileloc pos = { this_file, 0 };
-
+  char* inputlist = 0;
   /* fatal uses this */
   progname = "gengtype";
 
-  if (argc != 3)
-    fatal ("usage: gengtype srcdir input-list");
+  if (argc >= 5 && !strcmp (argv[1], "-p")) 
+    {
+      srcdir = argv[2];
+      inputlist = argv[3];
+      plugin_files = argv+4;
+      nb_plugin_files = argc-4;
+    }
+  else if (argc == 3) 
+    {
+      srcdir = argv[1];
+      inputlist = argv[2];
+    } 
+  else
+    fatal ("usage: gengtype srcdir input-list\n"
+	   "\t| gengtype -p srcdir input-list plugin... #for plugins");
 
-  srcdir = argv[1];
   srcdir_len = strlen (srcdir);
 
-  read_input_list (argv[2]);
+  read_input_list (inputlist);
   if (hit_error)
     return 1;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]