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] searching


This cleans up some of the previous patch (following many helpful
suggestions), and adds support for searching for PCH files.

PCH now actually works, with some limitations, for instance the file
to be precompiled has to be contain only whitespace (but the speedup
when precompiling huge files containing only whitespace is very
significant :-).

I'd appreciate it if someone who knows cpplib can comment on the
mangling I did to cppfiles.c.

The branch now probably doesn't build C++.  I tested C only.

-- 
Geoff Keating <geoffk@redhat.com>

===File ~/patches/pchbranch-search.patch====================
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 1.12690.2.67
diff -p -u -p -r1.12690.2.67 ChangeLog
--- ChangeLog	18 Aug 2002 03:33:23 -0000	1.12690.2.67
+++ ChangeLog	25 Aug 2002 00:39:10 -0000
@@ -1,3 +1,39 @@
+2002-08-24  Geoffrey Keating  <geoffk@redhat.com>
+
+	* c-pch.c: New file.
+	* toplev.h (late_init_hook): Declare.
+	* toplev.c (late_init_hook): Define.
+	(version_flag): Make globally visible.
+	(compile_file): Call late_init_hook.
+	(init_asm_output): Make output file seekable.
+	* gcc.c (default_compilers): Update c-header rule.
+	* flags.h (version_flag): Declare.
+	* cpplib.h (struct cpp_callbacks): Add 'valid_pch' and 'read_pch'
+	fields.
+	* cppfiles.c (struct include_file): Add 'pch' field.
+	(INCLUDE_PCH_P): New.
+	(open_file_pch): New.
+	(stack_include_file): Handle PCH files specially.
+	(find_include_file): Call open_file_pch instead of open_file.
+	(_cpp_read_file): Explain why open_file is used instead of
+	open_file_pch.
+	* c-opts.c (c_common_decode_option): Correct OPT__output_pch case.
+	* c-objc-common.c (c_objc_common_finish_file): Call c_write_pch.
+	* c-lex.c (init_c_lex): Set valid_pch and read_pch fields
+	in cpplib callbacks.
+	* c-common.c (pch_file): Correct comment.
+	(allow_pch): Define.
+	(c_common_init): Call pch_init.
+	* c-common.h (allow_pch): Declare.
+	(pch_init): Declare.
+	(c_valid_pch): Declare.
+	(c_read_pch): Declare.
+	(c_write_pch): Declare.
+	* Makefile.in (c-pch.o): New.
+	(C_AND_OBJC_OBJS): Add c-pch.o.
+	* doc/invoke.texi (Precompiled Headers): Add index entries,
+	complete truncated paragraph.
+
 2002-08-17  Geoffrey Keating  <geoffk@redhat.com>
 
 	* c-common.c: (pch_file): Define.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.822.2.30
diff -p -u -p -r1.822.2.30 Makefile.in
--- Makefile.in	13 Aug 2002 17:56:12 -0000	1.822.2.30
+++ Makefile.in	25 Aug 2002 00:39:10 -0000
@@ -722,7 +722,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
 # Language-specific object files for C and Objective C.
 C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
   c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
-  c-objc-common.o c-dump.o libcpp.a $(C_TARGET_OBJS)
+  c-objc-common.o c-dump.o c-pch.o libcpp.a $(C_TARGET_OBJS)
 
 # Language-specific object files for C.
 C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
@@ -1259,6 +1259,9 @@ c-semantics.o : c-semantics.c $(CONFIG_H
 	$(EXPR_H) $(PREDICT_H)
 
 c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) tree-dump.h
+
+c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) $(TREE_H) c-common.h \
+	output.h toplev.h
 
 # Language-independent files.
 
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.286.4.12
diff -p -u -p -r1.286.4.12 c-common.c
--- c-common.c	18 Aug 2002 03:33:30 -0000	1.286.4.12
+++ c-common.c	25 Aug 2002 00:39:11 -0000
@@ -192,12 +192,16 @@ enum c_language_kind c_language;
 
 tree c_global_trees[CTI_MAX];
 
+/* Nonzero if we can read a PCH file now.  */
+
+int allow_pch = 1;
+
 /* Switches common to the C front ends.  */
 
 /* Nonzero if prepreprocessing only.  */
 int flag_preprocess_only;
 
-/* The filename to which we should write a precompiled header, or
+/* The file name to which we should write a precompiled header, or
    NULL if no header will be written in this compile.  */
 
 const char *pch_file;
@@ -4926,6 +4930,8 @@ c_common_init (filename)
   filename = init_c_lex (filename);
 
   init_pragma ();
+
+  pch_init ();
 
   if (!c_attrs_initialized)
     c_init_attributes ();
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.112.4.13
diff -p -u -p -r1.112.4.13 c-common.h
--- c-common.h	18 Aug 2002 03:33:30 -0000	1.112.4.13
+++ c-common.h	25 Aug 2002 00:39:11 -0000
@@ -367,23 +367,30 @@ struct c_lang_decl GTY(()) {
 
 extern c_language_kind c_language;
 
+/* Nonzero if we can read a PCH file now.  */
 
+extern int allow_pch;
+
+
 /* Switches common to the C front ends.  */
 
 /* Nonzero if prepreprocessing only.  */
+
 extern int flag_preprocess_only;
 
-/* The filename to which we should write a precompiled header, or
+/* The file name to which we should write a precompiled header, or
    NULL if no header will be written in this compile.  */
 
 extern const char *pch_file;
 
 /* Nonzero if an ISO standard was selected.  It rejects macros in the
    user's namespace.  */
+
 extern int flag_iso;
 
 /* Nonzero if -undef was given.  It suppresses target built-in macros
    and assertions.  */
+
 extern int flag_undef;
 
 /* Nonzero means don't recognize the non-ANSI builtin functions.  */
@@ -1230,5 +1237,13 @@ struct c_fileinfo *get_fileinfo			PARAMS
 extern void dump_time_statistics		PARAMS ((void));
 
 extern int c_dump_tree				PARAMS ((void *, tree));
+
+extern void pch_init				PARAMS ((void));
+extern int c_valid_pch				PARAMS ((cpp_reader *pfile,
+							 const char *name,
+							 int fd));
+extern void c_read_pch				PARAMS ((cpp_reader *pfile,
+							 int fd));
+extern void c_write_pch				PARAMS ((void));
 
 #endif /* ! GCC_C_COMMON_H */
Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.163.4.6
diff -p -u -p -r1.163.4.6 c-lex.c
--- c-lex.c	24 Jul 2002 20:08:59 -0000	1.163.4.6
+++ c-lex.c	25 Aug 2002 00:39:11 -0000
@@ -122,6 +122,8 @@ init_c_lex (filename)
   cb->ident = cb_ident;
   cb->file_change = cb_file_change;
   cb->def_pragma = cb_def_pragma;
+  cb->valid_pch = c_valid_pch;
+  cb->read_pch = c_read_pch;
 
   /* Set the debug callbacks if we can use them.  */
   if (debug_info_level == DINFO_LEVEL_VERBOSE
Index: c-objc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-objc-common.c,v
retrieving revision 1.2.6.6
diff -p -u -p -r1.2.6.6 c-objc-common.c
--- c-objc-common.c	24 Jul 2002 20:08:59 -0000	1.2.6.6
+++ c-objc-common.c	25 Aug 2002 00:39:11 -0000
@@ -344,6 +344,9 @@ c_objc_common_finish_file ()
 {
   expand_deferred_fns ();
 
+  if (pch_file)
+    c_write_pch ();
+
   if (static_ctors)
     {
       tree body = start_cdtor ('I');
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.10.2.2
diff -p -u -p -r1.10.2.2 c-opts.c
--- c-opts.c	18 Aug 2002 03:33:30 -0000	1.10.2.2
+++ c-opts.c	25 Aug 2002 00:39:11 -0000
@@ -516,7 +516,7 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT__output_pch:
-      pch_file = xstrdup (arg + strlen ("--output-pch="));
+      pch_file = arg;
       break;
 
     case OPT_C:
Index: c-pch.c
===================================================================
RCS file: c-pch.c
diff -N c-pch.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ c-pch.c	25 Aug 2002 00:39:11 -0000
@@ -0,0 +1,216 @@
+/* Precompiled header implementation for the C languages.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "c-common.h"
+#include "output.h"
+#include "toplev.h"
+
+struct c_pch_header 
+{
+  unsigned long asm_size;
+};
+
+static const char pch_ident[8] = "gpchC010";
+
+static FILE *pch_outfile;
+
+extern char *asm_file_name;
+static off_t asm_file_startpos;
+static void (*old_late_init_hook) PARAMS((void));
+
+static void save_asm_offset PARAMS((void));
+
+static void
+save_asm_offset ()
+{
+  if (old_late_init_hook)
+    old_late_init_hook ();
+  asm_file_startpos = ftello (asm_out_file);
+}
+
+void
+pch_init ()
+{
+  FILE *f;
+  
+  if (pch_file)
+    {
+      f = fopen (pch_file, "wb");
+      if (f == NULL)
+	fatal_io_error ("can't open %s", pch_file);
+      pch_outfile = f;
+      
+      if (fwrite (pch_ident, sizeof (pch_ident), 1, f) != 1)
+	fatal_io_error ("can't write to %s", pch_file);
+#if 0
+      cpp_save_state (&parse_in, f);
+#endif
+
+      /* We need to be able to re-read the output.  */
+      /* The driver always provides a valid -o option.  */
+      if (asm_file_name == NULL
+	  || strcmp (asm_file_name, "-") == 0)
+	fatal_error ("`%s' is not a valid output file", asm_file_name);
+
+      old_late_init_hook = late_init_hook;
+      late_init_hook = save_asm_offset;
+    }
+}
+
+void
+c_write_pch ()
+{
+  char *buf;
+  off_t asm_file_end;
+  off_t written;
+  struct c_pch_header h;
+
+#if 0
+  cpp_write_pch (&parse_in, pch_outfile);
+#endif
+
+  asm_file_end = ftello (asm_out_file);
+  h.asm_size = asm_file_end - asm_file_startpos;
+  
+  if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
+    fatal_io_error ("can't write %s", pch_file);
+  
+  buf = xmalloc (16384);
+  fflush (asm_out_file);
+
+  if (fseeko (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
+    fatal_io_error ("can't seek in %s", asm_file_name);
+
+  for (written = asm_file_startpos; written < asm_file_end; )
+    {
+      off_t size = asm_file_end - written;
+      if (size > 16384)
+	size = 16384;
+      if (fread (buf, size, 1, asm_out_file) != 1)
+	fatal_io_error ("can't read %s", asm_file_name);
+      if (fwrite (buf, size, 1, pch_outfile) != 1)
+	fatal_io_error ("can't write %s", pch_file);
+      written += size;
+    }
+  free (buf);
+
+  fclose (pch_outfile);
+}
+
+int
+c_valid_pch (pfile, name, fd)
+     cpp_reader *pfile;
+     const char *name;
+     int fd;
+{
+  int sizeread;
+  int result;
+  char ident[sizeof (pch_ident)];
+
+  if (! allow_pch)
+    return 2;
+
+  /* Perform a quick test of whether this is a valid
+     precompiled header for C.  */
+
+  sizeread = read (fd, ident, sizeof (pch_ident));
+  if (sizeread == -1)
+    {
+      fatal_io_error ("can't read %s", name);
+      return 2;
+    }
+  else if (sizeread != sizeof (pch_ident))
+    return 2;
+  
+  if (memcmp (ident, pch_ident, sizeof (pch_ident)) != 0)
+    {
+      if (memcmp (ident, pch_ident, 5) == 0)
+	/* It's a PCH, for the right language, but has the wrong version.  */
+	cpp_error (pfile, DL_WARNING, "not compatible with this GCC version");
+      else if (memcmp (ident, pch_ident, 4) == 0)
+	/* It's a PCH for the wrong language.  */
+	cpp_error (pfile, DL_WARNING, "not for C language");
+      return 2;
+    }
+
+#if 0
+  /* Check the preprocessor macros are the same as when the PCH was
+     generated.  */
+  
+  result = cpp_valid_state (pfile, fd);
+  if (result == -1)
+    return 2;
+  else
+    return result == 0;
+#else
+  return 1;
+#endif
+}
+
+void
+c_read_pch (pfile, fd)
+     cpp_reader *pfile;
+     int fd;
+{
+  FILE *f;
+  struct c_pch_header h;
+  char *buf;
+  unsigned long written;
+  
+  f = fdopen (fd, "rb");
+  if (f == NULL)
+    {
+      cpp_errno (pfile, DL_ERROR, "calling fdopen");
+      return;
+    }
+
+  allow_pch = 0;
+
+#if 0
+  if (cpp_read_state (pfile, f) != 0)
+    return;
+#endif
+
+  if (fread (&h, sizeof (h), 1, f) != 1)
+    {
+      cpp_errno (pfile, DL_ERROR, "reading");
+      return;
+    }
+
+  buf = xmalloc (16384);
+  for (written = 0; written < h.asm_size; )
+    {
+      off_t size = h.asm_size - written;
+      if (size > 16384)
+	size = 16384;
+      if (fread (buf, size, 1, f) != 1
+	  || fwrite (buf, size, 1, asm_out_file) != 1)
+	cpp_errno (pfile, DL_ERROR, "reading");
+      written += size;
+    }
+  free (buf);
+
+  fclose (f);
+}
+
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.143.2.5
diff -p -u -p -r1.143.2.5 cppfiles.c
--- cppfiles.c	13 Aug 2002 17:56:22 -0000	1.143.2.5
+++ cppfiles.c	25 Aug 2002 00:39:11 -0000
@@ -91,6 +91,13 @@ struct include_file
   unsigned short include_count;	/* number of times file has been read */
   unsigned short refcnt;	/* number of stacked buffers using this file */
   unsigned char mapped;		/* file buffer is mmapped */
+  unsigned char pch;		/* 0: file not known to be a PCH.
+				   1: file is a PCH 
+				      (on return from find_include_file).
+				   2: file is not and never will be a valid
+				      precompiled header.
+				   3: file is always a valid precompiled
+				      header.  */
 };
 
 /* Variable length record files on VMS will have a stat size that includes
@@ -111,6 +118,7 @@ struct include_file
 ((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
 		   || (inc)->cmacro->type == NT_MACRO))
 #define NO_INCLUDE_PATH ((struct include_file *) -1)
+#define INCLUDE_PCH_P(F) (((F)->pch & 1) != 0)
 
 static struct file_name_map *read_name_map
 				PARAMS ((cpp_reader *, const char *));
@@ -123,6 +131,8 @@ static struct include_file *
 	find_include_file PARAMS ((cpp_reader *, const cpp_token *,
 				   enum include_type));
 static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
+static struct include_file *open_file_pch PARAMS ((cpp_reader *, 
+						   const char *));
 static int read_include_file	PARAMS ((cpp_reader *, struct include_file *));
 static bool stack_include_file	PARAMS ((cpp_reader *, struct include_file *));
 static void purge_cache 	PARAMS ((struct include_file *));
@@ -299,6 +309,36 @@ open_file (pfile, filename)
   return 0;
 }
 
+/* Like open_file, but also look for a precompiled header if (a) one exists
+   and (b) it is valid.  */
+static struct include_file *
+open_file_pch (pfile, filename)
+     cpp_reader *pfile;
+     const char *filename;
+{
+  if (filename[0] != '\0'
+      && pfile->cb.valid_pch != NULL)
+    {
+      size_t namelen = strlen (filename);
+      char *pchname = alloca (namelen + 5);
+      struct include_file * file;
+      
+      memcpy (pchname, filename, namelen);
+      memcpy (pchname + namelen, ".pch", 5);
+      file = open_file (pfile, pchname);
+      if (file != NULL)
+	{
+	  if ((file->pch & 2) == 0)
+	    file->pch = pfile->cb.valid_pch (pfile, pchname, file->fd);
+	  if (INCLUDE_PCH_P (file))
+	    return file;
+	  close (file->fd);
+	  file->fd = -1;
+	}
+    }
+  return open_file (pfile, filename);
+}
+
 /* Place the file referenced by INC into a new buffer on the buffer
    stack, unless there are errors, or the file is not re-included
    because of e.g. multiple-include guards.  Returns true if a buffer
@@ -322,31 +362,47 @@ stack_include_file (pfile, inc)
   if (CPP_OPTION (pfile, print_deps) > !!sysp && !inc->include_count)
     deps_add_dep (pfile->deps, inc->name);
 
-  /* Not in cache?  */
-  if (! inc->buffer)
+  /* PCH files get dealt with immediately.  
+     We stack a zero-sized buffer below.  
+     The reason for this is that reading a PCH directly into memory
+     will approximately double the memory consumption of the compiler.  */
+  if (INCLUDE_PCH_P (inc))
     {
-      if (read_include_file (pfile, inc))
-	{
-	  /* If an error occurs, do not try to read this file again.  */
-	  _cpp_never_reread (inc);
-	  return false;
-	}
-      /* Mark a regular, zero-length file never-reread.  We read it,
-	 NUL-terminate it, and stack it once, so preprocessing a main
-	 file of zero length does not raise an error.  */
-      if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
-	_cpp_never_reread (inc);
+      pfile->cb.read_pch (pfile, inc->fd);
       close (inc->fd);
       inc->fd = -1;
+      
+      fp = cpp_push_buffer (pfile, (unsigned char *)"", 0, 0, 0);
+    }
+  else
+    {
+      /* Not in cache?  */
+      if (! inc->buffer)
+	{
+	  if (read_include_file (pfile, inc))
+	    {
+	      /* If an error occurs, do not try to read this file again.  */
+	      _cpp_never_reread (inc);
+	      return false;
+	    }
+	  /* Mark a regular, zero-length file never-reread.  We read it,
+	     NUL-terminate it, and stack it once, so preprocessing a main
+	     file of zero length does not raise an error.  */
+	  if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
+	    _cpp_never_reread (inc);
+	  close (inc->fd);
+	  inc->fd = -1;
+	}
+      
+      if (pfile->buffer)
+	/* We don't want MI guard advice for the main file.  */
+	inc->include_count++;
+      
+      /* Push a buffer.  */
+      fp = cpp_push_buffer (pfile, inc->buffer, inc->st.st_size,
+			    /* from_stage3 */ CPP_OPTION (pfile, preprocessed),
+			    0);
     }
-
-  if (pfile->buffer)
-    /* We don't want MI guard advice for the main file.  */
-    inc->include_count++;
-
-  /* Push a buffer.  */
-  fp = cpp_push_buffer (pfile, inc->buffer, inc->st.st_size,
-			/* from_stage3 */ CPP_OPTION (pfile, preprocessed), 0);
   fp->inc = inc;
   fp->inc->refcnt++;
 
@@ -557,7 +613,7 @@ find_include_file (pfile, header, type)
   char *name, *n;
 
   if (IS_ABSOLUTE_PATHNAME (fname))
-    return open_file (pfile, fname);
+    return open_file_pch (pfile, fname);
 
   /* For #include_next, skip in the search path past the dir in which
      the current file was found, but if it was found via an absolute
@@ -593,7 +649,7 @@ find_include_file (pfile, header, type)
       else
 	n = name;
 
-      file = open_file (pfile, n);
+      file = open_file_pch (pfile, n);
       if (file)
 	{
 	  file->foundhere = path;
@@ -734,6 +790,9 @@ _cpp_read_file (pfile, fname)
      cpp_reader *pfile;
      const char *fname;
 {
+  /* This uses open_file, because we don't allow a PCH to be used as
+     the toplevel compilation (that would prevent re-compiling an
+     existing PCH without deleting it first).  */
   struct include_file *f = open_file (pfile, fname);
 
   if (f == NULL)
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.199.4.7
diff -p -u -p -r1.199.4.7 cpplib.h
--- cpplib.h	13 Aug 2002 17:56:23 -0000	1.199.4.7
+++ cpplib.h	25 Aug 2002 00:39:11 -0000
@@ -429,6 +429,8 @@ struct cpp_callbacks
   /* Called when the client has a chance to properly register
      built-ins with cpp_define() and cpp_assert().  */
   void (*register_builtins) PARAMS ((cpp_reader *));
+  int (*valid_pch) PARAMS ((cpp_reader *, const char *, int));
+  void (*read_pch) PARAMS ((cpp_reader *, int));
 };
 
 /* Name under which this program was invoked.  */
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.76.2.5
diff -p -u -p -r1.76.2.5 flags.h
--- flags.h	13 Aug 2002 17:56:27 -0000	1.76.2.5
+++ flags.h	25 Aug 2002 00:39:11 -0000
@@ -226,6 +226,10 @@ extern int in_system_header;
    pattern and alternative used.  */
 
 extern int flag_print_asm_name;
+
+/* Print compiler version information.  -v.  */
+
+extern int version_flag;
 
 /* Now the symbols that are set with `-f' switches.  */
 
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.285.4.8
diff -p -u -p -r1.285.4.8 gcc.c
--- gcc.c	18 Aug 2002 03:33:31 -0000	1.285.4.8
+++ gcc.c	25 Aug 2002 00:39:12 -0000
@@ -846,11 +846,20 @@ static const struct compiler default_com
     %(trad_capable_cpp) %{ansi:-std=c89} %(cpp_options)", 0},
   {".h", "@c-header", 0},
   {"@c-header",
-   "%{E|M|MM:%(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options) \
-      %(cpp_debug_options)}\
-    %{!E:cc1 %{ansi:-std=c89} %(cpp_unique_options) %(cc1_options) \
-     -o %g.s %{!o*:--output-pch=%i.pch} %W{^o*:--output-pch=%*}%V} ",
-   0},
+   /* cc1 has an integrated ISO C preprocessor.  We should invoke the
+      external preprocessor if -save-temps is given.  */
+     "%{E|M|MM:%(trad_capable_cpp) %{ansi:-std=c89} %(cpp_options)\
+	  %(cpp_debug_options)}\
+      %{!E:%{!M:%{!MM:\
+	  %{save-temps|traditional-cpp:%(trad_capable_cpp) \
+		%{ansi:-std=c89} %(cpp_options) %b.i \n\
+		    cc1 -fpreprocessed %b.i %(cc1_options)\
+                        -o %g.s %{!o*:--output-pch=%i.pch}\
+                        %W{^o*:--output-pch=%*}%V}\
+	  %{!save-temps:%{!traditional-cpp:\
+		cc1 %{ansi:-std=c89} %(cpp_unique_options) %(cc1_options)\
+                    -o %g.s %{!o*:--output-pch=%i.pch}\
+                    %W{^o*:--output-pch=%*}%V}}}}}", 0},
   {".i", "@cpp-output", 0},
   {"@cpp-output",
    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.571.2.9
diff -p -u -p -r1.571.2.9 toplev.c
--- toplev.c	13 Aug 2002 17:56:42 -0000	1.571.2.9
+++ toplev.c	25 Aug 2002 00:39:12 -0000
@@ -138,6 +138,9 @@ const char *progname;
 /* Copy of arguments to toplev_main.  */
 int save_argc;
 char **save_argv;
+
+/* A hook for last-second initialisations.  */
+void (*late_init_hook) PARAMS((void));
 
 /* Name of current original source file (what was input to cpp).
    This comes from each #-command in the actual input.  */
@@ -308,10 +311,13 @@ static void close_dump_file PARAMS ((enu
 
 int rtl_dump_and_exit;
 int flag_print_asm_name;
-static int version_flag;
 static char *filename;
 enum graph_dump_types graph_dump_format;
 
+/* Print compiler version information.  -v.  */
+
+int version_flag;
+
 /* Name for output file of assembly code, specified with -o.  */
 
 char *asm_file_name;
@@ -2123,6 +2129,10 @@ compile_file ()
   init_final (main_input_filename);
   init_branch_prob (aux_base_name);
 
+  /* Last call, time to go... */
+  if (late_init_hook)
+    late_init_hook ();
+
   timevar_push (TV_PARSE);
 
   /* Call the parser, which parses the entire file (calling
@@ -4649,7 +4659,7 @@ init_asm_output (name)
       if (!strcmp (asm_file_name, "-"))
 	asm_out_file = stdout;
       else
-	asm_out_file = fopen (asm_file_name, "w");
+	asm_out_file = fopen (asm_file_name, "w+");
       if (asm_out_file == 0)
 	fatal_io_error ("can't open %s for writing", asm_file_name);
     }
Index: toplev.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.h,v
retrieving revision 1.82.2.4
diff -p -u -p -r1.82.2.4 toplev.h
--- toplev.h	13 Aug 2002 17:56:43 -0000	1.82.2.4
+++ toplev.h	25 Aug 2002 00:39:12 -0000
@@ -115,6 +115,9 @@ extern int target_flags_explicit;
 /* The hashtable, so that the C front ends can pass it to cpplib.  */
 extern struct ht *ident_hash;
 
+/* A hook for last-second initialisations.  */
+extern void (*late_init_hook) PARAMS((void));
+
 /* This function can be used by targets to set the flags originally
     implied by -ffast-math and -fno-fast-math.  */
 
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.107.2.8
diff -p -u -p -r1.107.2.8 invoke.texi
--- doc/invoke.texi	18 Aug 2002 03:33:33 -0000	1.107.2.8
+++ doc/invoke.texi	25 Aug 2002 00:39:17 -0000
@@ -10210,6 +10210,8 @@ preprocessor.
 
 @node Precompiled Headers
 @section Using Precompiled Headers
+@cindex precompiled headers
+@cindex speed of compilation
 
 Often large projects have many header files that are included in every
 source file.  The time the compiler takes to process these header files
@@ -10245,7 +10247,12 @@ used, you can put a file of the same nam
 directory containing an @code{#error} command.
 
 This also works with @option{-include}.  So yet another way to use
-precompiled headers is to simply 
+precompiled headers, good for projects not designed with precompiled
+header files in mind, is to simply take most of the header files used by
+a project, include them from another header file, precompile that header
+file, and @option{-include} the precompiled header.  If the header files
+have guards against multiple inclusion, they will be skipped because
+they've already been included (in the precompiled header).
 
 There are many other possibilities, limited only by your imagination,
 good sense, and the constraints of your build system.
============================================================


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