This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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;