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: [distcc] using distcc to speed up gcc bootstraps


On Aug 16, 2002, Alexandre Oliva <aoliva@redhat.com> wrote:

> An alternative I'm considering is to have cpp emit some different #
> directive that contains the full pathname of the source file, or
> perhaps just the directory name.  I.e., something like:

> # 1 "filename"
> # 1 "<directory> /path/name"
> # 1 "filename"
> ...

> I find this somewhat icky, but it's fully backward-compatible.  Neil,
> Zack, anyone else, what do you think?

Not having got any complaints about this proposal, I went ahead and
implemented it.  Patch below.  Ok to install?  Bootstrapped on
athlon-pc-linux-gnu.

Unfortunately, the bootstrap compare test still failed :-(

The reason is that gcc generates different debugging information for a
source file such as:

#define FOO(X)
int FOO((x, y,
         z, w)) bar;
int baz;

If we preprocess this code and compile it separately (e.g.,
-save-temps), the result is:

# 2 "<filename>"
int bar;

int baz;

i.e., the declaration of bar is moved from line 3 to line 2.  However,
with integrated preprocessing, the declaration of bar is correctly
flagged as in line 3 in debugging information.  This difference is
enough for the bootstrap compare to fail, since at least varray.h
contains a number of union member declarations like above, with
multi-line GTY() macro invocations between the types and the
declarators.  Oh, well...

This should probably be fixed.  I don't think it's good that compiling
with or without -save-temps can result in different assembly output.
Neil, Zack, any comments?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* cppinit.c (read_original_filename): Return bool to tell
	whether the current directory was present in the input stream.
	Call...
	(read_original_directory): New function.  Look for a # line
	"<directory>..." right after the original filename.
	(cpp_read_main_file): Emit <directory> directive if it was not
	emitted by read_original_directory.
	(cpp_finish_options): Don't translate <built-in> nor <command
	line>.
	* dbxout.c (dbxout_init): Call get_src_pwd() instead of getpwd().
	* dwarf2out.c (gen_compile_unit_die): Likewise.
	* dwarfout.c (output_compile_unit_die, dwarfout_init): Likewise.
	* toplev.c (src_pwd): New static variable.
	(set_src_pwd, get_src_pwd): New functions.
	* toplev.h (get_src_pwd, set_src_pwd): Declare.
	* c-lex.c (cb_file_change): Recognize <directory> markers.
	Rename main_input_file if it's the current input_file and an
	LC_RENAME directive comes up.

Index: gcc/c-lex.c
===================================================================
RCS file: /cvs/uberbaum/gcc/c-lex.c,v
retrieving revision 1.187
diff -u -p -r1.187 c-lex.c
--- gcc/c-lex.c 12 Aug 2002 06:02:53 -0000 1.187
+++ gcc/c-lex.c 23 Aug 2002 09:14:35 -0000
@@ -295,6 +295,14 @@ cb_file_change (pfile, new_map)
       
       (*debug_hooks->end_source_file) (to_line);
     }
+  else if (new_map->reason == LC_RENAME)
+    {
+      if (strncmp (new_map->to_file, "<directory>",
+		   strlen ("<directory>")) == 0)
+	set_src_pwd (new_map->to_file + strlen ("<directory>"));
+      if (input_filename == main_input_filename)
+	main_input_filename = new_map->to_file;
+    }
 
   update_header_times (new_map->to_file);
   in_system_header = new_map->sysp != 0;
Index: gcc/cppinit.c
===================================================================
RCS file: /cvs/uberbaum/gcc/cppinit.c,v
retrieving revision 1.260
diff -u -p -r1.260 cppinit.c
--- gcc/cppinit.c 21 Aug 2002 17:07:26 -0000 1.260
+++ gcc/cppinit.c 23 Aug 2002 09:14:36 -0000
@@ -106,7 +106,8 @@ static bool push_include		PARAMS ((cpp_r
 						 struct pending_option *));
 static void free_chain			PARAMS ((struct pending_option *));
 static void init_standard_includes	PARAMS ((cpp_reader *));
-static void read_original_filename	PARAMS ((cpp_reader *));
+static bool read_original_filename	PARAMS ((cpp_reader *));
+static bool read_original_directory	PARAMS ((cpp_reader *));
 static void new_pending_directive	PARAMS ((struct cpp_pending *,
 						 const char *,
 						 cl_directive_handler));
@@ -950,6 +951,8 @@ cpp_read_main_file (pfile, fname, table)
      const char *fname;
      hash_table *table;
 {
+  char *pwd;
+
   sanity_checks (pfile);
 
   post_options (pfile);
@@ -999,8 +1002,22 @@ cpp_read_main_file (pfile, fname, table)
 
   /* For foo.i, read the original filename foo.c now, for the benefit
      of the front ends.  */
-  if (CPP_OPTION (pfile, preprocessed))
-    read_original_filename (pfile);
+  if (CPP_OPTION (pfile, preprocessed)
+      && read_original_filename (pfile))
+    pwd = NULL;
+  else
+    pwd = getpwd ();
+
+  if (pwd)
+    {
+      char *dir = concat ("<directory>", pwd, NULL);
+      const char *name = pfile->map->to_file;
+      unsigned int line = pfile->line;
+      int sysp = pfile->map->sysp;
+      
+      _cpp_do_file_change (pfile, LC_RENAME, dir, 1, 0);
+      _cpp_do_file_change (pfile, LC_RENAME, name, line, sysp);
+    }
 
   return pfile->map->to_file;
 }
@@ -1009,7 +1026,7 @@ cpp_read_main_file (pfile, fname, table)
    handle the directive so we know the original file name.  This will
    generate file_change callbacks, which the front ends must handle
    appropriately given their state of initialization.  */
-static void
+static bool
 read_original_filename (pfile)
      cpp_reader *pfile;
 {
@@ -1027,12 +1044,61 @@ read_original_filename (pfile)
       if (token1->type == CPP_NUMBER)
 	{
 	  _cpp_handle_directive (pfile, token->flags & PREV_WHITE);
-	  return;
+	  return read_original_directory (pfile);
+	}
+    }
+
+  /* Backup as if nothing happened.  */
+  _cpp_backup_tokens (pfile, 1);
+  return false;
+}
+
+/* For preprocessed files, if the tokens following the first filename
+   line are of the form # NUM "<directory>...", handle the directive
+   so we know the original current directory.  This will generate
+   file_change callbacks, which the front ends must handle
+   appropriately given their state of initialization.  */
+static bool
+read_original_directory (pfile)
+     cpp_reader *pfile;
+{
+  const cpp_token *token, *token1, *token2;
+
+  /* Lex ahead; if the first tokens are of the form # NUM, then
+     process the directive, otherwise back up.  */
+  token = _cpp_lex_direct (pfile);
+  if (token->type == CPP_HASH)
+    {
+      token1 = _cpp_lex_direct (pfile);
+
+      /* If it's a #line directive, handle it.  */
+      if (token1->type == CPP_NUMBER)
+	{
+	  token2 = _cpp_lex_direct (pfile);
+	  _cpp_backup_tokens (pfile, 2);
+
+	  if (token2->type == CPP_STRING
+	      && strncmp ((const char *)token2->val.str.text, "<directory>",
+			  strlen ("<directory>")) == 0)
+	    {
+	      const char *name = pfile->map->to_file;
+	      unsigned int line = pfile->line;
+	      int sysp = pfile->map->sysp;
+
+	      _cpp_handle_directive (pfile, token->flags & PREV_WHITE);
+
+	      _cpp_do_file_change (pfile, LC_RENAME, name, line, sysp);
+	      return true;
+	    }
 	}
+      else
+	_cpp_backup_tokens (pfile, 1);
     }
 
   /* Backup as if nothing happened.  */
   _cpp_backup_tokens (pfile, 1);
+
+  return false;
 }
 
 /* Handle pending command line options: -D, -U, -A, -imacros and
@@ -1052,9 +1118,9 @@ cpp_finish_options (pfile)
     {
       struct pending_option *p;
 
-      _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0);
+      _cpp_do_file_change (pfile, LC_RENAME, "<built-in>", 1, 0);
       init_builtins (pfile);
-      _cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0);
+      _cpp_do_file_change (pfile, LC_RENAME, "<command line>", 1, 0);
       for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
 	(*p->handler) (pfile, p->arg);
 
Index: gcc/dbxout.c
===================================================================
RCS file: /cvs/uberbaum/gcc/dbxout.c,v
retrieving revision 1.124
diff -u -p -r1.124 dbxout.c
--- gcc/dbxout.c 15 Aug 2002 19:59:28 -0000 1.124
+++ gcc/dbxout.c 23 Aug 2002 09:14:38 -0000
@@ -431,7 +431,8 @@ dbxout_init (input_file_name)
   if (use_gnu_debug_info_extensions)
 #endif
     {
-      if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
+      if (!cwd && (cwd = get_src_pwd ())
+	  && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
 	cwd = concat (cwd, FILE_NAME_JOINER, NULL);
       if (cwd)
 	{
Index: gcc/dwarf2out.c
===================================================================
RCS file: /cvs/uberbaum/gcc/dwarf2out.c,v
retrieving revision 1.383
diff -u -p -r1.383 dwarf2out.c
--- gcc/dwarf2out.c 21 Aug 2002 02:41:43 -0000 1.383
+++ gcc/dwarf2out.c 23 Aug 2002 09:14:45 -0000
@@ -10719,7 +10719,7 @@ gen_compile_unit_die (filename)
 {
   dw_die_ref die;
   char producer[250];
-  const char *wd = getpwd ();
+  const char *wd = get_src_pwd ();
   const char *language_string = lang_hooks.name;
   int language;
 
Index: gcc/dwarfout.c
===================================================================
RCS file: /cvs/uberbaum/gcc/dwarfout.c,v
retrieving revision 1.115
diff -u -p -r1.115 dwarfout.c
--- gcc/dwarfout.c 15 Aug 2002 19:59:29 -0000 1.115
+++ gcc/dwarfout.c 23 Aug 2002 09:14:49 -0000
@@ -4146,7 +4146,7 @@ output_compile_unit_die (arg)
     stmt_list_attribute (LINE_BEGIN_LABEL);
 
   {
-    const char *wd = getpwd ();
+    const char *wd = get_src_pwd ();
     if (wd)
       comp_dir_attribute (wd);
   }
@@ -6271,7 +6271,7 @@ dwarfout_init (main_input_filename)
 	  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SFNAMES_SECTION);
 	  ASM_OUTPUT_LABEL (asm_out_file, SFNAMES_BEGIN_LABEL);
 	  {
-	    const char *pwd = getpwd ();
+	    const char *pwd = get_src_pwd ();
 	    char *dirname;
 
 	    if (!pwd)
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/uberbaum/gcc/toplev.c,v
retrieving revision 1.668
diff -u -p -r1.668 toplev.c
--- gcc/toplev.c 14 Aug 2002 06:36:51 -0000 1.668
+++ gcc/toplev.c 23 Aug 2002 09:14:53 -0000
@@ -1558,7 +1558,43 @@ static const lang_independent_options W_
   {"missing-noreturn", &warn_missing_noreturn, 1,
    N_("Warn about functions which might be candidates for attribute noreturn") }
 };
+
+/* The current working directory of a translation.  It's generally the
+   directory from which compilation was initiated, but a preprocessed
+   file may specify the original directory in which it was
+   created.  */
 
+static const char *src_pwd;
+
+/* Initialize src_pwd with the given string, and return true.  If it
+   was already initialized, return false.  As a special case, it may
+   be called with a NULL argument to test whether src_pwd has NOT been
+   initialized yet.  */
+
+bool
+set_src_pwd (pwd)
+     const char *pwd;
+{
+  if (src_pwd)
+    return false;
+
+  src_pwd = xstrdup (pwd);
+  return true;
+}
+
+/* Return the directory from which the translation unit was initiated,
+   in case set_src_pwd() was not called before to assign it a
+   different value.  */
+
+const char *
+get_src_pwd ()
+{
+  if (! src_pwd)
+    src_pwd = getpwd ();
+
+  return src_pwd;
+}
+
 void
 set_Wunused (setting)
      int setting;
Index: gcc/toplev.h
===================================================================
RCS file: /cvs/uberbaum/gcc/toplev.h,v
retrieving revision 1.89
diff -u -p -r1.89 toplev.h
--- gcc/toplev.h 4 Aug 2002 16:21:02 -0000 1.89
+++ gcc/toplev.h 23 Aug 2002 09:14:53 -0000
@@ -1,5 +1,6 @@
 /* toplev.h - Various declarations for functions found in toplev.c
-   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -132,5 +133,8 @@ extern bool fast_math_flags_set_p	PARAMS
 #endif
 extern int exact_log2_wide             PARAMS ((unsigned HOST_WIDE_INT));
 extern int floor_log2_wide             PARAMS ((unsigned HOST_WIDE_INT));
+
+extern const char *get_src_pwd	       PARAMS ((void));
+extern bool set_src_pwd		       PARAMS ((const char *));
 
 #endif /* ! GCC_TOPLEV_H */
-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer

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