]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
lto-cgraph.c (asm_nodes_output): Make global.
authorJan Hubicka <hubicka@ucw.cz>
Wed, 5 Feb 2014 17:21:07 +0000 (18:21 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 5 Feb 2014 17:21:07 +0000 (17:21 +0000)
* lto-cgraph.c (asm_nodes_output): Make global.
* lto-wrapper.c (run_gcc): Pass down paralelizm to WPA.
* gcc.c (AS_NEEDS_DASH_FOR_PIPED_INPUT): Allow WPA
parameter
(driver_handle_option): Handle OPT_fwpa.

* lto.c (lto_parallelism): New static var.
(do_stream_out, wait_for_child, stream_out): New static functions.
(lto_wpa_write_files): Add support for parallel streaming.
(do_whole_program_analysis): Set parallelism.
* lang.opt (fwpa): Add parameter.
* lto-lang.c (lto_handle_option): Handle flag_wpa.
(lto_init): Update use of flag_wpa.
* lto-streamer.h (asm_nodes_output): Declare.

From-SVN: r207515

gcc/ChangeLog
gcc/gcc.c
gcc/lto-cgraph.c
gcc/lto-wrapper.c
gcc/lto/ChangeLog
gcc/lto/lang.opt
gcc/lto/lto-lang.c
gcc/lto/lto.c

index 32a6a3e4cd927653c9c95b0e7c04e7c0f13c7017..9f3902de34f97d099d35611eb200080876072d92 100644 (file)
@@ -1,3 +1,11 @@
+2014-02-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto-cgraph.c (asm_nodes_output): Make global.
+       * lto-wrapper.c (run_gcc): Pass down paralelizm to WPA.
+       * gcc.c (AS_NEEDS_DASH_FOR_PIPED_INPUT): Allow WPA
+       parameter
+       (driver_handle_option): Handle OPT_fwpa.
+
 2014-02-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR ipa/59947
index 35d1fe6bf1ab776047638a24961303890dd1efda..9f76f89a4507172413da80273593bbbe75864e3b 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -888,12 +888,12 @@ static const char *asm_options =
 
 static const char *invoke_as =
 #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
-"%{!fwpa:\
+"%{!fwpa*:\
    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
   }";
 #else
-"%{!fwpa:\
+"%{!fwpa*:\
    %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
    %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
   }";
@@ -3651,6 +3651,10 @@ driver_handle_option (struct gcc_options *opts,
       validated = true;
       break;
 
+    case OPT_fwpa:
+      flag_wpa = "";
+      break;
+
     default:
       /* Various driver options need no special processing at this
         point, having been handled in a prescan above or being
index 5c774b8ee81ef99ea46c324b198c5b4ebd620652..e772072864a958e062e2ccd265810a7b25f18ee3 100644 (file)
@@ -53,6 +53,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "pass_manager.h"
 #include "ipa-utils.h"
 
+/* True when asm nodes has been output.  */
+bool asm_nodes_output = false;
+
 static void output_cgraph_opt_summary (void);
 static void input_cgraph_opt_summary (vec<symtab_node *>  nodes);
 
@@ -890,7 +893,6 @@ output_symtab (void)
   lto_symtab_encoder_iterator lsei;
   int i, n_nodes;
   lto_symtab_encoder_t encoder;
-  static bool asm_nodes_output = false;
 
   if (flag_wpa)
     output_cgraph_opt_summary ();
index cc45e33a482cc7dd9870efff6d96ff1343579daa..5798a81f95808cba07d98fd3f74035cb9f26f68a 100644 (file)
@@ -745,7 +745,16 @@ run_gcc (unsigned argc, char *argv[])
       tmp += list_option_len;
       strcpy (tmp, ltrans_output_file);
 
-      obstack_ptr_grow (&argv_obstack, "-fwpa");
+      if (jobserver)
+       obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
+      else if (parallel > 1)
+       {
+         char buf[256];
+         sprintf (buf, "-fwpa=%i", parallel);
+         obstack_ptr_grow (&argv_obstack, xstrdup (buf));
+       }
+      else
+        obstack_ptr_grow (&argv_obstack, "-fwpa");
     }
 
   /* Append the input objects and possible preceding arguments.  */
index 15610f277feb6ec5e3b5e937d2cbd6564bc36f80..454d9cd765e3fe198a3623da1988e23f5c946023 100644 (file)
@@ -1,3 +1,14 @@
+2014-02-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto.c (lto_parallelism): New static var.
+       (do_stream_out, wait_for_child, stream_out): New static functions.
+       (lto_wpa_write_files): Add support for parallel streaming.
+       (do_whole_program_analysis): Set parallelism.
+       * lang.opt (fwpa): Add parameter.
+       * lto-lang.c (lto_handle_option): Handle flag_wpa.
+       (lto_init): Update use of flag_wpa.
+       * lto-streamer.h (asm_nodes_output): Declare.
+
 2014-02-05  Richard Biener  <rguenther@suse.de>
 
        * lto.h (lto_global_var_decls): Remove.
index 74bb30bc5f44e6e91921611a068a04c11ce39590..07a119574036133c74bdb035aa0ddbc772434eec 100644 (file)
@@ -33,9 +33,13 @@ LTO Joined Var(ltrans_output_list)
 Specify a file to which a list of files output by LTRANS is written.
 
 fwpa
-LTO Driver Report Var(flag_wpa)
+LTO Driver Report
 Run the link-time optimizer in whole program analysis (WPA) mode.
 
+fwpa=
+LTO Driver RejectNegative Joined Var(flag_wpa)
+Whole program analysis (WPA) mode with number of parallel jobs specified.
+
 fresolution=
 LTO Joined
 The resolution file
index 0ef65cf5c86a6c035e9d094f44215619c11fb290..4d6d0f5ffd9d388e96da0fca3b659085939bc073 100644 (file)
@@ -749,6 +749,10 @@ lto_handle_option (size_t scode, const char *arg,
       warn_psabi = value;
       break;
 
+    case OPT_fwpa:
+      flag_wpa = value ? "" : NULL;
+      break;
+
     default:
       break;
     }
@@ -1157,7 +1161,7 @@ static bool
 lto_init (void)
 {
   /* We need to generate LTO if running in WPA mode.  */
-  flag_generate_lto = flag_wpa;
+  flag_generate_lto = (flag_wpa != NULL);
 
   /* Create the basic integer types.  */
   build_common_tree_nodes (flag_signed_char, /*short_double=*/false);
index 579c91c5864fd811a20aa187721450b707178772..fb81f3132f19f58b29c853e6fafdc23031e5cf76 100644 (file)
@@ -51,6 +51,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "pass_manager.h"
 
 
+/* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver.  */
+static int lto_parallelism;
+
 static GTY(()) tree first_personality_decl;
 
 /* Returns a hash code for P.  */
@@ -2437,6 +2440,98 @@ cmp_partitions_order (const void *a, const void *b)
   return orderb - ordera;
 }
 
+/* Actually stream out ENCODER into TEMP_FILENAME.  */
+
+static void
+do_stream_out (char *temp_filename, lto_symtab_encoder_t encoder)
+{
+  lto_file *file = lto_obj_file_open (temp_filename, true);
+  if (!file)
+    fatal_error ("lto_obj_file_open() failed");
+  lto_set_current_out_file (file);
+
+  ipa_write_optimization_summaries (encoder);
+
+  lto_set_current_out_file (NULL);
+  lto_obj_file_close (file);
+  free (file);
+}
+
+/* Wait for forked process and signal errors.  */
+#ifdef HAVE_WORKING_FORK
+static void
+wait_for_child ()
+{
+  int status;
+  do
+    {
+      int w = waitpid(0, &status, WUNTRACED | WCONTINUED);
+      if (w == -1)
+       fatal_error ("waitpid failed");
+
+      if (WIFEXITED (status) && WEXITSTATUS (status))
+       fatal_error ("streaming subprocess failed");
+      else if (WIFSIGNALED (status))
+       fatal_error ("streaming subprocess was killed by signal");
+    }
+  while (!WIFEXITED(status) && !WIFSIGNALED(status));
+}
+#endif
+
+/* Stream out ENCODER into TEMP_FILENAME
+   Fork if that seems to help.  */
+
+static void
+stream_out (char *temp_filename, lto_symtab_encoder_t encoder, bool last)
+{
+#ifdef HAVE_WORKING_FORK
+  static int nruns;
+
+  if (!lto_parallelism || lto_parallelism == 1)
+    {
+      do_stream_out (temp_filename, encoder);
+      return;
+    }
+
+  /* Do not run more than LTO_PARALLELISM streamings
+     FIXME: we ignore limits on jobserver.  */
+  if (lto_parallelism > 0 && nruns >= lto_parallelism)
+    {
+      wait_for_child ();
+      nruns --;
+    }
+  /* If this is not the last parallel partition, execute new
+     streaming process.  */
+  if (!last)
+    {
+      pid_t cpid = fork ();
+
+      if (!cpid)
+       {
+         setproctitle ("lto1-wpa-streaming");
+         do_stream_out (temp_filename, encoder);
+         exit (0);
+       }
+      /* Fork failed; lets do the job ourseleves.  */
+      else if (cpid == -1)
+        do_stream_out (temp_filename, encoder);
+      else
+       nruns++;
+    }
+  /* Last partition; stream it and wait for all children to die.  */
+  else
+    {
+      int i;
+      do_stream_out (temp_filename, encoder);
+      for (i = 0; i < nruns; i++)
+       wait_for_child ();
+    }
+  asm_nodes_output = true;
+#else
+  do_stream_out (temp_filename, encoder);
+#endif
+}
+
 /* Write all output files in WPA mode and the file with the list of
    LTRANS units.  */
 
@@ -2444,18 +2539,15 @@ static void
 lto_wpa_write_files (void)
 {
   unsigned i, n_sets;
-  lto_file *file;
   ltrans_partition part;
   FILE *ltrans_output_list_stream;
   char *temp_filename;
+  vec <char *>temp_filenames = vNULL;
   size_t blen;
 
   /* Open the LTRANS output list.  */
   if (!ltrans_output_list)
     fatal_error ("no LTRANS output list filename provided");
-  ltrans_output_list_stream = fopen (ltrans_output_list, "w");
-  if (ltrans_output_list_stream == NULL)
-    fatal_error ("opening LTRANS output list %s: %m", ltrans_output_list);
 
   timevar_push (TV_WHOPR_WPA);
 
@@ -2494,14 +2586,10 @@ lto_wpa_write_files (void)
 
   for (i = 0; i < n_sets; i++)
     {
-      size_t len;
       ltrans_partition part = ltrans_partitions[i];
 
       /* Write all the nodes in SET.  */
       sprintf (temp_filename + blen, "%u.o", i);
-      file = lto_obj_file_open (temp_filename, true);
-      if (!file)
-       fatal_error ("lto_obj_file_open() failed");
 
       if (!quiet_flag)
        fprintf (stderr, " %s (%s %i insns)", temp_filename, part->name, part->insns);
@@ -2543,21 +2631,25 @@ lto_wpa_write_files (void)
        }
       gcc_checking_assert (lto_symtab_encoder_size (part->encoder) || !i);
 
-      lto_set_current_out_file (file);
-
-      ipa_write_optimization_summaries (part->encoder);
+      stream_out (temp_filename, part->encoder, i == n_sets - 1);
 
-      lto_set_current_out_file (NULL);
-      lto_obj_file_close (file);
-      free (file);
       part->encoder = NULL;
 
-      len = strlen (temp_filename);
-      if (fwrite (temp_filename, 1, len, ltrans_output_list_stream) < len
+      temp_filenames.safe_push (xstrdup (temp_filename));
+    }
+  ltrans_output_list_stream = fopen (ltrans_output_list, "w");
+  if (ltrans_output_list_stream == NULL)
+    fatal_error ("opening LTRANS output list %s: %m", ltrans_output_list);
+  for (i = 0; i < n_sets; i++)
+    {
+      unsigned int len = strlen (temp_filenames[i]);
+      if (fwrite (temp_filenames[i], 1, len, ltrans_output_list_stream) < len
          || fwrite ("\n", 1, 1, ltrans_output_list_stream) < 1)
        fatal_error ("writing to LTRANS output list %s: %m",
                     ltrans_output_list);
+     free (temp_filenames[i]);
     }
+  temp_filenames.release();
 
   lto_stats.num_output_files += n_sets;
 
@@ -3113,6 +3205,18 @@ do_whole_program_analysis (void)
 {
   symtab_node *node;
 
+  lto_parallelism = 1;
+
+  /* TODO: jobserver communicatoin is not supported, yet.  */
+  if (!strcmp (flag_wpa, "jobserver"))
+    lto_parallelism = -1;
+  else
+    {
+      lto_parallelism = atoi (flag_wpa);
+      if (lto_parallelism <= 0)
+       lto_parallelism = 0;
+    }
+
   timevar_start (TV_PHASE_OPT_GEN);
 
   /* Note that since we are in WPA mode, materialize_cgraph will not