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]

Support offset pointers in gengtype


This patch adds support for pointers which are offset from the start
of the object, as found in the stringpool (stringpool entries point
to the cpplib structure which is inside the tree identifier).

This patch is mostly infrastructure, although it may have a small speed
benefit (probably too small to measure).

Bootstrapped & tested on powerpc-darwin.

===File ~/patches/gcc-symtabpch.patch=======================
Index: libcpp/ChangeLog
2004-05-29  Geoffrey Keating  <geoffk@apple.com>

	* symtab.c (ht_create): Set entries_owned.
	(ht_destroy): Honour entries_owned.
	(ht_expand): Likewise.
	(ht_load): New.

Index: libcpp/include/ChangeLog
2004-05-29  Geoffrey Keating  <geoffk@apple.com>

	* symtab.h (struct ht): New field 'entries_owned'
	(ht_load): New prototype.

Index: gcc/ChangeLog
2004-05-29  Geoffrey Keating  <geoffk@apple.com>

	* gengtype-yacc.y: Add NESTED_PTR token.
	(option): Record `nested_ptr' option.
	* gengtype-lex.l: Handle `nested_ptr' keyword.
	* gengtype.c (walk_type): Process `nested_ptr' option.
	* gengtype.h (struct nested_ptr_data): New.
	* doc/gty.texi (GTY Options): Document `nested_ptr' option.
	* stringpool.c (struct string_pool_data): Make 'entries' point to
	ht_identifier instead of tree.
	(gt_pch_save_stringpool): Don't adjust pointers.
	(gt_pch_restore_stringpool): Call ht_load.

Index: gcc/gengtype-lex.l
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype-lex.l,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 gengtype-lex.l
--- gcc/gengtype-lex.l	13 May 2004 06:39:42 -0000	1.19
+++ gcc/gengtype-lex.l	30 May 2004 00:40:11 -0000
@@ -1,6 +1,6 @@
 /* -*- indented-text -*- */
 /* Process source files and output type information.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -235,6 +235,7 @@ ITYPE	{IWORD}({WS}{IWORD})*
 "struct"/[^[:alnum:]_]		{ return STRUCT; }
 "enum"/[^[:alnum:]_]		{ return ENUM; }
 "ptr_alias"/[^[:alnum:]_]	{ return ALIAS; }
+"nested_ptr"/[^[:alnum:]_]	{ return NESTED_PTR; }
 [0-9]+				{ return NUM; }
 "param"[0-9]*"_is"/[^[:alnum:]_]		{ 
   yylval.s = xmemdup (yytext, yyleng, yyleng+1);
Index: gcc/gengtype-yacc.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype-yacc.y,v
retrieving revision 1.12
diff -u -p -u -p -r1.12 gengtype-yacc.y
--- gcc/gengtype-yacc.y	13 May 2004 06:39:42 -0000	1.12
+++ gcc/gengtype-yacc.y	30 May 2004 00:40:11 -0000
@@ -1,6 +1,6 @@
 /* -*- indented-text -*- */
 /* Process source files and output type information.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -44,6 +44,7 @@ Software Foundation, 59 Temple Place - S
 %token STRUCT
 %token ENUM
 %token ALIAS
+%token NESTED_PTR
 %token <s>PARAM_IS
 %token NUM
 %token PERCENTPERCENT "%%"
@@ -279,6 +280,13 @@ option:   ID
             { $$ = create_option ($1, (void *)$3); }
 	| type_option '(' type ')'
 	    { $$ = create_option ($1, adjust_field_type ($3, NULL)); }
+	| NESTED_PTR '(' type ',' stringseq ',' stringseq ')'
+	    {
+	      struct nested_ptr_data d =
+	        { adjust_field_type ($3, NULL), $5, $7 };
+	      $$ = create_option ("nested_ptr",
+				  xmemdup (&d, sizeof (d), sizeof (d)));
+	    }
 	;
 
 optionseq: option
Index: gcc/gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.49
diff -u -p -u -p -r1.49 gengtype.c
--- gcc/gengtype.c	20 May 2004 11:45:19 -0000	1.49
+++ gcc/gengtype.c	30 May 2004 00:40:11 -0000
@@ -1509,6 +1509,7 @@ walk_type (type_p t, struct walk_type_da
   int use_param_num = -1;
   int use_params_p = 0;
   options_p oo;
+  const struct nested_ptr_data *nested_ptr_d = NULL;
 
   d->needs_cast_p = 0;
   for (oo = d->opt; oo; oo = oo->next)
@@ -1523,6 +1524,8 @@ walk_type (type_p t, struct walk_type_da
       use_params_p = 1;
     else if (strcmp (oo->name, "desc") == 0)
       desc = (const char *)oo->info;
+    else if (strcmp (oo->name, "nested_ptr") == 0)
+      nested_ptr_d = (const struct nested_ptr_data *)oo->info ;
     else if (strcmp (oo->name, "dot") == 0)
       ;
     else if (strcmp (oo->name, "tag") == 0)
@@ -1623,7 +1626,48 @@ walk_type (type_p t, struct walk_type_da
 		break;
 	      }
 
-	    d->process_field (t->u.p, d);
+	    if (nested_ptr_d)
+	      {
+		const char *oldprevval2 = d->prev_val[2];
+
+		if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
+		  {
+		    error_at_line (d->line,
+				   "field `%s' has invalid "
+				   "option `nested_ptr'\n",
+				   d->val);
+		    return;
+		  }
+
+		d->prev_val[2] = d->val;
+		oprintf (d->of, "%*s{\n", d->indent, "");
+		d->indent += 2;
+		d->val = xasprintf ("x%d", d->counter++);
+		oprintf (d->of, "%*s%s %s * %s =\n", d->indent, "",
+			 (nested_ptr_d->type->kind == TYPE_UNION 
+			  ? "union" : "struct"), 
+			 nested_ptr_d->type->u.s.tag, d->val);
+		oprintf (d->of, "%*s", d->indent + 2, "");
+		output_escaped_param (d, nested_ptr_d->convert_from,
+				      "nested_ptr");
+		oprintf (d->of, ";\n");
+
+		d->process_field (nested_ptr_d->type, d);
+
+		oprintf (d->of, "%*s%s = ", d->indent, "",
+			 d->prev_val[2]);
+		d->prev_val[2] = d->val;
+		output_escaped_param (d, nested_ptr_d->convert_to,
+				      "nested_ptr");
+		oprintf (d->of, ";\n");
+
+		d->indent -= 2;
+		oprintf (d->of, "%*s}\n", d->indent, "");
+		d->val = d->prev_val[2];
+		d->prev_val[2] = oldprevval2;
+	      }
+	    else
+	      d->process_field (t->u.p, d);
 	  }
 	else
 	  {
Index: gcc/gengtype.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.h,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 gengtype.h
--- gcc/gengtype.h	30 Mar 2004 19:18:55 -0000	1.10
+++ gcc/gengtype.h	30 May 2004 00:40:11 -0000
@@ -37,6 +37,17 @@ enum typekind {
   TYPE_PARAM_STRUCT
 };
 
+typedef struct pair *pair_p;
+typedef struct type *type_p;
+typedef unsigned lang_bitmap;
+
+/* Option data for the 'nested_ptr' option.  */
+struct nested_ptr_data {
+  type_p type;
+  const char *convert_to;
+  const char *convert_from;
+};    
+
 /* A way to pass data through to the output end.  */
 typedef struct options {
   struct options *next;
@@ -44,10 +55,6 @@ typedef struct options {
   const void *info;
 } *options_p;
 
-typedef struct pair *pair_p;
-typedef struct type *type_p;
-typedef unsigned lang_bitmap;
-
 /* A name and a type.  */
 struct pair {
   pair_p next;
Index: gcc/stringpool.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stringpool.c,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 stringpool.c
--- gcc/stringpool.c	28 May 2004 21:41:42 -0000	1.24
+++ gcc/stringpool.c	30 May 2004 00:40:11 -0000
@@ -1,5 +1,5 @@
 /* String pool for GCC.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -201,7 +201,11 @@ gt_pch_n_S (const void *x)
 
 struct string_pool_data GTY(())
 {
-  tree * GTY((length ("%h.nslots"))) entries;
+  struct ht_identifier * * 
+    GTY((length ("%h.nslots"),
+	 nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
+		     "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
+    entries;
   unsigned int nslots;
   unsigned int nelements;
 };
@@ -237,25 +241,20 @@ ht_copy_and_clear (cpp_reader *r ATTRIBU
 
 static struct ht *saved_ident_hash;
 
-/* The hash table contains pointers to the cpp_hashnode inside the
-   lang_identifier.  The PCH machinery can't handle pointers that refer
-   to the inside of an object, so to save the hash table for PCH the
-   pointers are adjusted and stored in the variable SPD.  */
+/* Prepare the stringpool to be written (by clearing all the cpp parts
+   of each entry) and place the data to be saved in SPD.  Save the
+   current state in SAVED_IDENT_HASH so that gt_pch_fixup_stringpool
+   can restore it.  */
 
 void
 gt_pch_save_stringpool (void)
 {
-  unsigned int i;
-
   spd = ggc_alloc (sizeof (*spd));
   spd->nslots = ident_hash->nslots;
   spd->nelements = ident_hash->nelements;
-  spd->entries = ggc_alloc (sizeof (tree *) * spd->nslots);
-  for (i = 0; i < spd->nslots; i++)
-    if (ident_hash->entries[i] != NULL)
-      spd->entries[i] = HT_IDENT_TO_GCC_IDENT (ident_hash->entries[i]);
-    else
-      spd->entries[i] = NULL;
+  spd->entries = ggc_alloc (sizeof (spd->entries[0]) * spd->nslots);
+  memcpy (spd->entries, ident_hash->entries,
+	  spd->nslots * sizeof (spd->entries[0]));
 
   saved_ident_hash = ht_create (14);
   saved_ident_hash->alloc_node = alloc_node;
@@ -274,23 +273,12 @@ gt_pch_fixup_stringpool (void)
 }
 
 /* A PCH file has been restored, which loaded SPD; fill the real hash table
-   with adjusted pointers from SPD.  */
+   from SPD.  */
 
 void
 gt_pch_restore_stringpool (void)
 {
-  unsigned int i;
-
-  ident_hash->nslots = spd->nslots;
-  ident_hash->nelements = spd->nelements;
-  ident_hash->entries = xrealloc (ident_hash->entries,
-				  sizeof (hashnode) * spd->nslots);
-  for (i = 0; i < spd->nslots; i++)
-    if (spd->entries[i] != NULL)
-      ident_hash->entries[i] = GCC_IDENT_TO_HT_IDENT (spd->entries[i]);
-    else
-      ident_hash->entries[i] = NULL;
-
+  ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
   spd = NULL;
 }
 
Index: gcc/doc/gty.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/gty.texi,v
retrieving revision 1.16
diff -u -p -u -p -r1.16 gty.texi
--- gcc/doc/gty.texi	11 May 2004 21:35:57 -0000	1.16
+++ gcc/doc/gty.texi	30 May 2004 00:40:13 -0000
@@ -291,6 +291,19 @@ this field is always @code{NULL}.  This 
 backends to define certain optional structures.  It doesn't work with
 language frontends.
 
+@findex nested_ptr
+@item nested_ptr (@var{type}, "@var{to expression}", "@var{from expression}")
+
+The type machinery expects all pointers to point to the start of an
+object.  Sometimes for abstraction purposes it's convenient to have
+a pointer which points inside an object.  So long as it's possible to
+convert the original object to and from the pointer, such pointers
+can still be used.  @var{type} is the type of the original object,
+the @var{to expression} returns the pointer given the original object,
+and the @var{from expression} returns the original object given
+the pointer.  The pointer will be available using the @code{%h}
+escape.
+
 @findex chain_next
 @findex chain_prev
 @item chain_next ("@var{expression}")
Index: libcpp/symtab.c
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/symtab.c,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 symtab.c
--- libcpp/symtab.c	24 May 2004 10:50:44 -0000	1.1
+++ libcpp/symtab.c	30 May 2004 00:40:17 -0000
@@ -1,5 +1,5 @@
 /* Hash tables.
-   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -68,6 +68,7 @@ ht_create (unsigned int order)
   obstack_alignment_mask (&table->stack) = 0;
 
   table->entries = xcalloc (nslots, sizeof (hashnode));
+  table->entries_owned = true;
   table->nslots = nslots;
   return table;
 }
@@ -78,7 +79,8 @@ void
 ht_destroy (hash_table *table)
 {
   obstack_free (&table->stack, NULL);
-  free (table->entries);
+  if (table->entries_owned)
+    free (table->entries);
   free (table);
 }
 
@@ -199,7 +201,9 @@ ht_expand (hash_table *table)
       }
   while (++p < limit);
 
-  free (table->entries);
+  if (table->entries_owned)
+    free (table->entries);
+  table->entries_owned = true;
   table->entries = nentries;
   table->nslots = size;
 }
@@ -222,6 +226,20 @@ ht_forall (hash_table *table, ht_cb cb, 
   while (++p < limit);
 }
 
+/* Restore the hash table.  */
+void
+ht_load (hash_table *ht, hashnode *entries,
+	 unsigned int nslots, unsigned int nelements,
+	 bool own)
+{
+  if (ht->entries_owned)
+    free (ht->entries);
+  ht->entries = entries;
+  ht->nslots = nslots;
+  ht->nelements = nelements;
+  ht->entries_owned = own;
+}
+
 /* Dump allocation statistics to stderr.  */
 
 void
Index: libcpp/include/symtab.h
===================================================================
RCS file: /cvs/gcc/gcc/libcpp/include/symtab.h,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 symtab.h
--- libcpp/include/symtab.h	24 May 2004 10:50:45 -0000	1.1
+++ libcpp/include/symtab.h	30 May 2004 00:40:17 -0000
@@ -1,5 +1,5 @@
 /* Hash tables.
-   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -58,6 +58,9 @@ struct ht
   /* Table usage statistics.  */
   unsigned int searches;
   unsigned int collisions;
+
+  /* Should 'entries' be freed when it is no longer needed?  */
+  bool entries_owned;
 };
 
 /* Initialize the hashtable with 2 ^ order entries.  */
@@ -75,6 +78,10 @@ extern hashnode ht_lookup (hash_table *,
 typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *);
 extern void ht_forall (hash_table *, ht_cb, const void *);
 
+/* Restore the hash table.  */
+extern void ht_load (hash_table *ht, hashnode *entries,
+		     unsigned int nslots, unsigned int nelements, bool own);
+
 /* Dump allocation statistics to stderr.  */
 extern void ht_dump_statistics (hash_table *);
 
============================================================


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