diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/collect2.c | 5 | ||||
-rw-r--r-- | gcc/common.opt | 8 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 8 | ||||
-rw-r--r-- | gcc/gcc.c | 2 | ||||
-rw-r--r-- | gcc/lto-wrapper.c | 83 | ||||
-rw-r--r-- | gcc/opts.c | 4 |
7 files changed, 100 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 35d39a0..ec47a66 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/collect2.c b/gcc/collect2.c index 0669a4e..42db3cb 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -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. */ diff --git a/gcc/common.opt b/gcc/common.opt index 8cda912..6c2ca93 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6afc713..195cdfb 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 @@ -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\ diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 5c9650e..3dbd96b 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -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); @@ -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: |