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]

[PCH] fix merging macros


This patch handles saving & restoring the macro part of the symbol
table around the PCH restore of the symbol table.

With this patch, all the small PCH testcases pass.  Next step is to
improve the testsuite to compare .s files with/without PCH, which
ought to bring more bugs to light.

Bootstrapped & tested on powerpc-darwin.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/pchbranch-macromerge.patch================
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 1.12690.2.76
diff -u -p -u -p -r1.12690.2.76 ChangeLog
--- ChangeLog	4 Nov 2002 19:00:13 -0000	1.12690.2.76
+++ ChangeLog	9 Nov 2002 00:56:35 -0000
@@ -1,3 +1,24 @@
+2002-11-08  Geoffrey Keating  <geoffk@apple.com>
+
+	* c-pch.c (c_common_write_pch): Write the macro definitions after
+	the GCed data.
+	(c_common_read_pch): Call cpp_prepare_state.  Restore the macro
+	definitions after the GCed data.
+	* cpplib.c (save_macros): New.
+	(reset_ht): New.
+	(cpp_write_pch_deps): Split out of cpp_write_pch.
+	(cpp_write_pch_state): Split out of cpp_write_pch.
+	(cpp_write_pch): Delete.
+	(struct save_macro_data): Delete.
+	(cpp_prepare_state): New.
+	(cpp_read_state): Erase and restore initial macro definitions.
+	* cpplib.h (struct save_macro_data): Forward-declare.
+	(cpp_write_pch_deps): Prototype.
+	(cpp_write_pch_state): Prototype.
+	(cpp_write_pch): Delete prototype.
+	(cpp_prepare_state): Prototype.
+	(cpp_read_state): Add fourth argument.
+
 2002-11-04  Geoffrey Keating  <geoffk@apple.com>
 
 	* gengtype.c (adjust_field_rtx_def): Don't use skip on valid fields.
Index: c-pch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-pch.c,v
retrieving revision 1.1.2.4
diff -u -p -u -p -r1.1.2.4 c-pch.c
--- c-pch.c	26 Oct 2002 06:12:46 -0000	1.1.2.4
+++ c-pch.c	9 Nov 2002 00:56:35 -0000
@@ -75,7 +75,7 @@ c_common_write_pch ()
   off_t written;
   struct c_pch_header h;
 
-  cpp_write_pch (parse_in, pch_outfile);
+  cpp_write_pch_deps (parse_in, pch_outfile);
 
   asm_file_end = ftello (asm_out_file);
   h.asm_size = asm_file_end - asm_file_startpos;
@@ -103,6 +103,7 @@ c_common_write_pch ()
   free (buf);
 
   gt_pch_save (pch_outfile);
+  cpp_write_pch_state (parse_in, pch_outfile);
 
   fclose (pch_outfile);
 }
@@ -171,6 +172,7 @@ c_common_read_pch (pfile, name, fd)
   struct c_pch_header h;
   char *buf;
   unsigned long written;
+  struct save_macro_data *smd;
   
   f = fdopen (fd, "rb");
   if (f == NULL)
@@ -181,9 +183,6 @@ c_common_read_pch (pfile, name, fd)
 
   allow_pch = 0;
 
-  if (cpp_read_state (pfile, name, f) != 0)
-    return;
-
   if (fread (&h, sizeof (h), 1, f) != 1)
     {
       cpp_errno (pfile, DL_ERROR, "reading");
@@ -203,7 +202,12 @@ c_common_read_pch (pfile, name, fd)
     }
   free (buf);
 
+  cpp_prepare_state (pfile, &smd);
+
   gt_pch_restore (f);
+
+  if (cpp_read_state (pfile, name, f, smd) != 0)
+    return;
 
   fclose (f);
 }
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.199.4.11
diff -u -p -u -p -r1.199.4.11 cpplib.h
--- cpplib.h	25 Sep 2002 19:15:57 -0000	1.199.4.11
+++ cpplib.h	9 Nov 2002 00:56:35 -0000
@@ -731,10 +731,15 @@ extern int cpp_included	PARAMS ((cpp_rea
 extern void cpp_make_system_header PARAMS ((cpp_reader *, int, int));
 
 /* In cpppch.c */
+struct save_macro_data;
 extern int cpp_save_state PARAMS ((cpp_reader *, FILE *));
-extern int cpp_write_pch PARAMS ((cpp_reader *, FILE *));
+extern int cpp_write_pch_deps PARAMS ((cpp_reader *, FILE *));
+extern int cpp_write_pch_state PARAMS ((cpp_reader *, FILE *));
 extern int cpp_valid_state PARAMS ((cpp_reader *, const char *, int));
-extern int cpp_read_state PARAMS ((cpp_reader *, const char *, FILE *));
+extern void cpp_prepare_state PARAMS ((cpp_reader *, 
+				       struct save_macro_data **));
+extern int cpp_read_state PARAMS ((cpp_reader *, const char *, FILE *,
+				   struct save_macro_data *));
 
 /* In cppmain.c */
 extern void cpp_preprocess_file PARAMS ((cpp_reader *, const char *, FILE *));
Index: cpppch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cpppch.c,v
retrieving revision 1.1.4.2
diff -u -p -u -p -r1.1.4.2 cpppch.c
--- cpppch.c	3 Sep 2002 23:04:57 -0000	1.1.4.2
+++ cpppch.c	9 Nov 2002 00:56:35 -0000
@@ -30,6 +30,8 @@ static hashval_t cpp_string_hash PARAMS 
 static int cpp_string_eq PARAMS ((const void *, const void *));
 static int count_defs PARAMS ((cpp_reader *, cpp_hashnode *, void *));
 static int write_defs PARAMS ((cpp_reader *, cpp_hashnode *, void *));
+static int save_macros PARAMS ((cpp_reader *, cpp_hashnode *, void *));
+static int reset_ht PARAMS ((cpp_reader *, cpp_hashnode *, void *));
 
 /* This structure represents a macro definition on disk.  */
 struct macrodef_struct 
@@ -293,11 +295,11 @@ write_defs (pfile, hn, ss_p)
     }
 }
 
-/* Write out the definitions of the preprocessor, in a form suitable for
-   cpp_read_state.  */
+/* Write out the remainder of the dependency information.  This should be
+   called after the PCH is ready to be saved.  */
 
 int
-cpp_write_pch (r, f)
+cpp_write_pch_deps (r, f)
      cpp_reader *r;
      FILE *f;
 {
@@ -325,7 +327,19 @@ cpp_write_pch (r, f)
   /* Free the saved state.  */
   free (ss);
   r->savedstate = NULL;
-  
+  return 0;
+}
+
+/* Write out the definitions of the preprocessor, in a form suitable for
+   cpp_read_state.  */
+
+int
+cpp_write_pch_state (r, f)
+     cpp_reader *r;
+     FILE *f;
+{
+  struct macrodef_struct z;
+
   /* Write out the list of defined identifiers.  */
   cpp_forall_identifiers (r, write_macdef, f);
   memset (&z, 0, sizeof (z));
@@ -462,20 +476,119 @@ cpp_valid_state (r, name, fd)
   return 1;
 }
 
+/* Save all the existing macros and assertions.  
+   This code assumes that there might be hundreds, but not thousands of
+   existing definitions.  */
+
+struct save_macro_data {
+  struct save_macro_data *next;
+  size_t count;
+  struct cpp_hashnode macs[64];
+};
+
+
+static int 
+save_macros (r, h, data_p)
+     cpp_reader *r ATTRIBUTE_UNUSED;
+     cpp_hashnode *h;
+     void *data_p;
+{
+  struct save_macro_data **data = (struct save_macro_data **)data_p;
+  if (h->type != NT_VOID
+      && (h->flags & NODE_BUILTIN) == 0)
+    {
+      cpp_hashnode *save;
+      if ((*data)->count == ARRAY_SIZE ((*data)->macs))
+	{
+	  struct save_macro_data *d = *data;
+	  *data = xmalloc (sizeof (struct save_macro_data));
+	  (*data)->next = d;
+	  (*data)->count = 0;
+	}
+      save = (*data)->macs + (*data)->count;
+      (*data)->count++;
+      memcpy (save, h, sizeof (struct cpp_hashnode));
+      HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)),
+				       HT_LEN (HT_NODE (save)),
+				       HT_LEN (HT_NODE (save)) + 1);
+    }
+  return 1;
+}
+
+void
+cpp_prepare_state (r, data)
+     cpp_reader *r;
+     struct save_macro_data **data;
+{
+  struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
+  
+  d->next = NULL;
+  d->count = 0;
+  cpp_forall_identifiers (r, save_macros, &d);
+  *data = d;
+}
+
+
+/* Erase all the existing macros and assertions.  */
+
+static int 
+reset_ht (r, h, unused)
+     cpp_reader *r ATTRIBUTE_UNUSED;
+     cpp_hashnode *h;
+     void *unused ATTRIBUTE_UNUSED;
+{
+  if (h->type != NT_VOID
+      && (h->flags & NODE_BUILTIN) == 0)
+    {
+      h->type = NT_VOID;
+      memset (&h->value, 0, sizeof (h->value));
+    }
+  return 1;
+}
+
 /* Given a precompiled header that was previously determined to be valid,
    apply all its definitions (and undefinitions) to the current state. 
    DEPNAME is passed to deps_restore.  */
 
 int
-cpp_read_state (r, name, f)
+cpp_read_state (r, name, f, data)
      cpp_reader *r;
      const char *name;
      FILE *f;
+     struct save_macro_data *data;
 {
   struct macrodef_struct m;
   size_t defnlen = 256;
   unsigned char *defn = xmalloc (defnlen);
   struct lexer_state old_state;
+  struct save_macro_data *d;
+  size_t i;
+
+  /* First, erase all the existing hashtable entries for macros.  At
+     this point, they're all from the PCH file, and their pointers
+     won't be valid.  */
+  cpp_forall_identifiers (r, reset_ht, NULL);
+
+  /* Run through the carefully-saved macros, insert them.  */
+  d = data;
+  while (d)
+    {
+      struct save_macro_data *nextd;
+      for (i = 0; i < d->count; i++)
+	{
+	  cpp_hashnode *h;
+	  
+	  h = cpp_lookup (r, HT_STR (HT_NODE (&d->macs[i])), 
+			  HT_LEN (HT_NODE (&d->macs[i])));
+	  h->type = d->macs[i].type;
+	  h->flags = d->macs[i].flags;
+	  h->value = d->macs[i].value;
+	  free ((void *)HT_STR (HT_NODE (&d->macs[i])));
+	}
+      nextd = d->next;
+      free (d);
+      d = nextd;
+    }
 
   old_state = r->state;
 
Index: testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.1552.2.12
diff -u -p -u -p -r1.1552.2.12 ChangeLog
--- testsuite/ChangeLog	4 Nov 2002 19:00:24 -0000	1.1552.2.12
+++ testsuite/ChangeLog	9 Nov 2002 00:56:39 -0000
@@ -1,27 +1,32 @@
+2002-11-08  Geoffrey Keating  <geoffk@apple.com>
+
+	* gcc.dg/pch/macro-3.c: New.
+	* gcc.dg/pch/macro-3.h: New.
+
 2002-11-04  Geoffrey Keating  <geoffk@apple.com>
 
-	* common-1.c: New.
-	* common-1.h: New.
-	* decl-1.c: New.
-	* decl-1.h: New.
-	* decl-2.c: New.
-	* decl-2.h: New.
-	* decl-3.c: New.
-	* decl-3.h: New.
-	* decl-4.c: New.
-	* decl-4.h: New.
-	* decl-5.c: New.
-	* decl-5.h: New.
-	* global-1.c: New.
-	* global-1.h: New.
-	* inline-1.c: New.
-	* inline-1.h: New.
-	* inline-2.c: New.
-	* inline-2.h: New.
-	* static-1.c: New.
-	* static-1.h: New.
-	* static-2.c: New.
-	* static-2.h: New.
+	* gcc.dg/pch/common-1.c: New.
+	* gcc.dg/pch/common-1.h: New.
+	* gcc.dg/pch/decl-1.c: New.
+	* gcc.dg/pch/decl-1.h: New.
+	* gcc.dg/pch/decl-2.c: New.
+	* gcc.dg/pch/decl-2.h: New.
+	* gcc.dg/pch/decl-3.c: New.
+	* gcc.dg/pch/decl-3.h: New.
+	* gcc.dg/pch/decl-4.c: New.
+	* gcc.dg/pch/decl-4.h: New.
+	* gcc.dg/pch/decl-5.c: New.
+	* gcc.dg/pch/decl-5.h: New.
+	* gcc.dg/pch/global-1.c: New.
+	* gcc.dg/pch/global-1.h: New.
+	* gcc.dg/pch/inline-1.c: New.
+	* gcc.dg/pch/inline-1.h: New.
+	* gcc.dg/pch/inline-2.c: New.
+	* gcc.dg/pch/inline-2.h: New.
+	* gcc.dg/pch/static-1.c: New.
+	* gcc.dg/pch/static-1.h: New.
+	* gcc.dg/pch/static-2.c: New.
+	* gcc.dg/pch/static-2.h: New.
 
 2002-09-01  Geoffrey Keating  <geoffk@redhat.com>
 
Index: testsuite/gcc.dg/pch/macro-3.c
===================================================================
RCS file: testsuite/gcc.dg/pch/macro-3.c
diff -N testsuite/gcc.dg/pch/macro-3.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/pch/macro-3.c	9 Nov 2002 00:56:41 -0000
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+#define DEFINED_FUNC_2(x) (3 + (x))
+
+#include "macro-3.hp"
+
+int main(void) 
+{
+  return DEFINED_FUNC (1) - DEFINED_FUNC_2 (-1);
+}
Index: testsuite/gcc.dg/pch/macro-3.h
===================================================================
RCS file: testsuite/gcc.dg/pch/macro-3.h
diff -N testsuite/gcc.dg/pch/macro-3.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/pch/macro-3.h	9 Nov 2002 00:56:41 -0000
@@ -0,0 +1,2 @@
+#define DEFINED_FUNC(x) 3 - (x)
+
============================================================


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