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: [RFA][lto merge]: support for gcc @file


On Fri, Apr 17, 2009 at 15:58, Diego Novillo <dnovillo@google.com> wrote:
> This patch http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00063.html adds
> support to the gcc driver to be invoked with @file to avoid
> massive command lines that are sometimes generated in the context
> of LTO.

Bugger.  I attached the wrong patch.  Sorry.



	Merge from lto branch

	2009-02-02  Rafael Avila de Espindola  <espindola@google.com>

		* gcc.c (create_at_file): New.
		(compile_input_file_p): New.
		(do_spec_1): Use @args files for %i. Use create_at_file for %o.
		* main.c (main): Update call to toplev_main.
		* toplev.c (toplev_main): Change signature. Call expandargv.
		* toplev.h (toplev_main): Change signature.

Index: gcc.c
===================================================================
--- gcc.c	(revision 146277)
+++ gcc.c	(working copy)
@@ -4741,6 +4741,49 @@ spec_path (char *path, void *data)
   return NULL;
 }

+/* Create a temporary FILE with the contents of ARGV. Add @FILE to the
+   argument list. */
+
+static void
+create_at_file (char **argv)
+{
+  char *temp_file = make_temp_file ("");
+  char *at_argument = concat ("@", temp_file, NULL);
+  FILE *f = fopen (temp_file, "w");
+  int status;
+
+  if (f == NULL)
+    fatal ("could not open temporary response file %s",
+	   temp_file);
+
+  status = writeargv (argv, f);
+
+  if (status)
+    fatal ("could not write to temporary response file %s",
+	   temp_file);
+
+  status = fclose (f);
+
+  if (EOF == status)
+    fatal ("could not close temporary response file %s",
+	   temp_file);
+
+  store_arg (at_argument, 0, 0);
+
+  record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
+}
+
+/* True if we should compile INFILE. */
+
+static bool
+compile_input_file_p (struct infile *infile)
+{
+  if ((!infile->language) || (infile->language[0] != '*'))
+    if (infile->incompiler == input_file_compiler)
+      return true;
+  return false;
+}
+
 /* Process the sub-spec SPEC as a portion of a larger spec.
    This is like processing a whole spec except that we do
    not initialize at the beginning and we do not supply a
@@ -5107,9 +5150,37 @@ do_spec_1 (const char *spec, int inswitc
 	  case 'i':
 	    if (combine_inputs)
 	      {
-		for (i = 0; (int) i < n_infiles; i++)
-		  if ((!infiles[i].language) || (infiles[i].language[0] != '*'))
-		    if (infiles[i].incompiler == input_file_compiler)
+		if (at_file_supplied)
+		  {
+		    /* We are going to expand `%i' to `@FILE', where FILE
+		       is a newly-created temporary filename.  The filenames
+		       that would usually be expanded in place of %o will be
+		       written to the temporary file.  */
+		    char **argv;
+		    int n_files = 0;
+		    int j;
+
+		    for (i = 0; i < n_infiles; i++)
+		      if (compile_input_file_p (&infiles[i]))
+			n_files++;
+
+		    argv = (char **) alloca (sizeof (char *) * (n_files + 1));
+
+		    /* Copy the strings over.  */
+		    for (i = 0, j = 0; i < n_infiles; i++)
+		      if (compile_input_file_p (&infiles[i]))
+			{
+			  argv[j] = CONST_CAST (char *, infiles[i].name);
+			  infiles[i].compiled = true;
+			  j++;
+			}
+		    argv[j] = NULL;
+
+		    create_at_file (argv);
+		  }
+		else
+		  for (i = 0; (int) i < n_infiles; i++)
+		    if (compile_input_file_p (&infiles[i]))
 		      {
 			store_arg (infiles[i].name, 0, 0);
 			infiles[i].compiled = true;
@@ -5187,14 +5258,8 @@ do_spec_1 (const char *spec, int inswitc
                      that would usually be expanded in place of %o will be
                      written to the temporary file.  */

-                  char *temp_file = make_temp_file ("");
-                  char *at_argument;
                   char **argv;
-                  int n_files, j, status;
-                  FILE *f;
-
-                  at_argument = concat ("@", temp_file, NULL);
-                  store_arg (at_argument, 0, 0);
+                  int n_files, j;

                   /* Convert OUTFILES into a form suitable for writeargv.  */

@@ -5213,25 +5278,7 @@ do_spec_1 (const char *spec, int inswitc
                       }
                   argv[j] = NULL;

-                  f = fopen (temp_file, "w");
-
-                  if (f == NULL)
-                    fatal ("could not open temporary response file %s",
-                           temp_file);
-
-                  status = writeargv (argv, f);
-
-                  if (status)
-                    fatal ("could not write to temporary response file %s",
-                           temp_file);
-
-                  status = fclose (f);
-
-                  if (EOF == status)
-                    fatal ("could not close temporary response file %s",
-                           temp_file);
-
-                  record_temp_file (temp_file, !save_temps_flag,
!save_temps_flag);
+		  create_at_file (argv);
                 }
               else
                 for (i = 0; i < max; i++)
Index: toplev.c
===================================================================
--- toplev.c	(revision 146277)
+++ toplev.c	(working copy)
@@ -2261,16 +2261,18 @@ do_compile (void)
    It is not safe to call this function more than once.  */

 int
-toplev_main (unsigned int argc, const char **argv)
+toplev_main (int argc, char **argv)
 {
-  save_argv = argv;
+  expandargv (&argc, &argv);
+
+  save_argv = (const char **) argv;

   /* Initialization of GCC's environment, and diagnostics.  */
   general_init (argv[0]);

   /* Parse the options and do minimal processing; basically just
      enough to default flags appropriately.  */
-  decode_options (argc, argv);
+  decode_options (argc, (const char **) argv);

   init_local_tick ();

Index: toplev.h
===================================================================
--- toplev.h	(revision 146277)
+++ toplev.h	(working copy)
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3.
 #define skip_leading_substring(whole,  part) \
    (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))

-extern int toplev_main (unsigned int, const char **);
+extern int toplev_main (int, char **);
 extern int read_integral_parameter (const char *, const char *, const int);
 extern void strip_off_ending (char *, int);
 extern const char *trim_filename (const char *);
Index: main.c
===================================================================
--- main.c	(revision 146277)
+++ main.c	(working copy)
@@ -32,5 +32,5 @@ int main (int argc, char **argv);
 int
 main (int argc, char **argv)
 {
-  return toplev_main (argc, (const char **) argv);
+  return toplev_main (argc, argv);
 }


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