OSDN Git Service

2010-05-19 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 May 2010 15:43:22 +0000 (15:43 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 May 2010 15:43:22 +0000 (15:43 +0000)
* doc/invoke.texi (-fwhopr): Document new optional jobs argument.
* common.opt (fwhopr=): New.
* opts.c (common_handle_option): Handle OPT_fwhopr.
* gcc.c (LINK_COMMAND_SPEC): Pass fwhopr*.
* collect2.c (main): Match -fwhopr*.
* lto-wrapper.c (run_gcc): Handle jobs argument of -fwhopr.
Execute ltrans stage in parallel when jobs is bigger than 1.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159573 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/collect2.c
gcc/common.opt
gcc/doc/invoke.texi
gcc/gcc.c
gcc/lto-wrapper.c
gcc/opts.c

index 35d39a0..ec47a66 100644 (file)
@@ -1,3 +1,13 @@
+2010-05-19  Richard Guenther  <rguenther@suse.de>
+
+       * doc/invoke.texi (-fwhopr): Document new optional jobs argument.
+       * common.opt (fwhopr=): New.
+       * opts.c (common_handle_option): Handle OPT_fwhopr.
+       * gcc.c (LINK_COMMAND_SPEC): Pass fwhopr*.
+       * collect2.c (main): Match -fwhopr*.
+       * lto-wrapper.c (run_gcc): Handle jobs argument of -fwhopr.
+       Execute ltrans stage in parallel when jobs is bigger than 1.
+
 2010-05-19  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * config.gcc (i[34567]86-*-solaris2*): Default with_arch_32 to
index 0669a4e..42db3cb 100644 (file)
@@ -1207,7 +1207,7 @@ main (int argc, char **argv)
            use_verbose = true;
            lto_mode = LTO_MODE_LTO;
          }
-        else if (! strcmp (argv[i], "-fwhopr") && ! use_plugin)
+        else if (! strncmp (argv[i], "-fwhopr", 7) && ! use_plugin)
          {
            use_verbose = true;
            lto_mode = LTO_MODE_WHOPR;
@@ -1482,7 +1482,8 @@ main (int argc, char **argv)
              break;
 
             case 'f':
-             if (strcmp (arg, "-flto") == 0 || strcmp (arg, "-fwhopr") == 0)
+             if (strcmp (arg, "-flto") == 0
+                 || strncmp (arg, "-fwhopr", 7) == 0)
                {
 #ifdef ENABLE_LTO
                  /* Do not pass LTO flag to the linker. */
index 8cda912..6c2ca93 100644 (file)
@@ -1484,8 +1484,12 @@ Common Report Var(flag_web) Init(2) Optimization
 Construct webs and split unrelated uses of single variable
 
 fwhopr
-Common Var(flag_whopr)
-Enable partitioned link-time optimization.
+Common
+Enable partitioned link-time optimization
+
+fwhopr=
+Common RejectNegative UInteger Joined Var(flag_whopr)
+Enable partitioned link-time optimization with specified number of parallel jobs
 
 ftree-builtin-call-dce
 Common Report Var(flag_tree_builtin_call_dce) Init(0) Optimization
index 6afc713..195cdfb 100644 (file)
@@ -391,7 +391,7 @@ Objective-C and Objective-C++ Dialects}.
 -funit-at-a-time -funroll-all-loops -funroll-loops @gol
 -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
 -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
--fwhole-program -fwhopr -fwpa -fuse-linker-plugin @gol
+-fwhole-program -fwhopr[=@var{n}] -fwpa -fuse-linker-plugin @gol
 --param @var{name}=@var{value}
 -O  -O0  -O1  -O2  -O3  -Os}
 
@@ -7442,7 +7442,7 @@ information.  Combining @option{-flto} or @option{-fwhopr} with
 
 This option is disabled by default.
 
-@item -fwhopr
+@item -fwhopr[=@var{n}]
 @opindex fwhopr
 This option is identical in functionality to @option{-flto} but it
 differs in how the final link stage is executed.  Instead of loading
@@ -7454,6 +7454,10 @@ LTRANS)@.  This process allows optimizations on very large programs
 that otherwise would not fit in memory.  This option enables
 @option{-fwpa} and @option{-fltrans} automatically.
 
+If you specify the optional @var{n} the link stage is executed in
+parallel using @var{n} parallel jobs by utilizing an installed
+@code{make} program.
+
 Disabled by default.
 
 @item -fwpa
index 41569fc..39788be 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -785,7 +785,7 @@ proper position among the other output files.  */
     %{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)}    \
     %{static:-plugin-opt=-pass-through=-lc}    \
     } \
-    %{flto} %{fwhopr} %l " LINK_PIE_SPEC \
+    %{flto} %{fwhopr*} %l " LINK_PIE_SPEC \
    "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
index 5c9650e..3dbd96b 100644 (file)
@@ -148,7 +148,10 @@ collect_execute (char **argv)
   if (pex == NULL)
     fatal_perror ("pex_init failed");
 
-  errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, NULL,
+  /* Do not use PEX_LAST here, we use our stdout for communicating with
+     collect2 or the linker-plugin.  Any output from the sub-process
+     will confuse that.  */
+  errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
                    NULL, &err);
   if (errmsg != NULL)
     {
@@ -264,6 +267,7 @@ run_gcc (unsigned argc, char *argv[])
   const char *collect_gcc_options, *collect_gcc;
   struct obstack env_obstack;
   bool seen_o = false;
+  int parallel = 0;
 
   /* Get the driver and options.  */
   collect_gcc = getenv ("COLLECT_GCC");
@@ -329,8 +333,16 @@ run_gcc (unsigned argc, char *argv[])
        /* We've handled these LTO options, do not pass them on.  */
        if (strcmp (option, "-flto") == 0)
          lto_mode = LTO_MODE_LTO;
-       else if (strcmp (option, "-fwhopr") == 0)
-         lto_mode = LTO_MODE_WHOPR;
+       else if (strncmp (option, "-fwhopr", 7) == 0)
+         {
+           lto_mode = LTO_MODE_WHOPR;
+           if (option[7] == '=')
+             {
+               parallel = atoi (option+8);
+               if (parallel <= 1)
+                 parallel = 0;
+             }
+         }
        else
          *argv_ptr++ = option;
       }
@@ -416,13 +428,23 @@ run_gcc (unsigned argc, char *argv[])
   else if (lto_mode == LTO_MODE_WHOPR)
     {
       FILE *stream = fopen (ltrans_output_file, "r");
-      int nr = 0;
+      unsigned int nr = 0;
+      char **input_names = NULL;
+      char **output_names = NULL;
+      char *makefile = NULL;
+      FILE *mstream = NULL;
 
       if (!stream)
        fatal_perror ("fopen: %s", ltrans_output_file);
 
       argv_ptr[1] = "-fltrans";
 
+      if (parallel)
+       {
+         makefile = make_temp_file (".mk");
+         mstream = fopen (makefile, "w");
+       }
+
       for (;;)
        {
          const unsigned piece = 32;
@@ -444,10 +466,7 @@ cont:
          input_name[len - 1] = '\0';
 
          if (input_name[0] == '*')
-           {
-             continue;
-             output_name = &input_name[1];
-           }
+           output_name = &input_name[1];
          else
            {
              /* Otherwise, add FILES[I] to lto_execute_ltrans command line
@@ -467,7 +486,7 @@ cont:
                                        + sizeof(DUMPBASE_SUFFIX) + 1);
                  snprintf (dumpbase,
                            strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
-                           "%s.ltrans%d", linker_output, nr++);
+                           "%s.ltrans%u", linker_output, nr);
                  argv_ptr[0] = dumpbase;
                }
 
@@ -476,14 +495,52 @@ cont:
              argv_ptr[4] = input_name;
              argv_ptr[5] = NULL;
 
-             fork_execute (CONST_CAST (char **, new_argv));
-
-             maybe_unlink_file (input_name);
+             if (parallel)
+               {
+                 fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
+                 for (i = 1; new_argv[i] != NULL; ++i)
+                   fprintf (mstream, " '%s'", new_argv[i]);
+                 fprintf (mstream, "\n");
+               }
+             else
+               fork_execute (CONST_CAST (char **, new_argv));
            }
 
-         fputs (output_name, stdout);
+         nr++;
+         input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
+         output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
+         input_names[nr-1] = input_name;
+         output_names[nr-1] = output_name;
+       }
+      if (parallel)
+       {
+         struct pex_obj *pex;
+         char jobs[32];
+         fprintf (mstream, "all:");
+         for (i = 0; i < nr; ++i)
+           fprintf (mstream, " \\\n\t%s", output_names[i]);
+         fprintf (mstream, "\n");
+         fclose (mstream);
+         new_argv[0] = "make";
+         new_argv[1] = "-f";
+         new_argv[2] = makefile;
+         snprintf (jobs, 31, "-j%d", parallel);
+         new_argv[3] = jobs;
+         new_argv[4] = "all";
+         new_argv[5] = NULL;
+         pex = collect_execute (CONST_CAST (char **, new_argv));
+         collect_wait (new_argv[0], pex);
+         maybe_unlink_file (makefile);
+       }
+      for (i = 0; i < nr; ++i)
+       {
+         fputs (output_names[i], stdout);
          putc ('\n', stdout);
+         maybe_unlink_file (input_names[i]);
+         free (input_names[i]);
        }
+      free (output_names);
+      free (input_names);
       fclose (stream);
       maybe_unlink_file (ltrans_output_file);
       free (list_option_full);
index d5a9fb3..329f732 100644 (file)
@@ -2149,6 +2149,10 @@ common_handle_option (size_t scode, const char *arg, int value,
       flag_pedantic_errors = pedantic = 1;
       break;
 
+    case OPT_fwhopr:
+      flag_whopr = value;
+      break;
+
     case OPT_fsee:
     case OPT_fcse_skip_blocks:
     case OPT_floop_optimize: