OSDN Git Service

* tree-pass.h (ipa_opt_pass_d): Rename function_read_summary;
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Apr 2010 17:44:03 +0000 (17:44 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 01:08:43 +0000 (10:08 +0900)
add write_optimization_summary, read_optimization_summary.
(ipa_write_summaries_of_cgraph_node_set): Remove.
(ipa_write_optimization_summaries): Declare.
(ipa_read_optimization_summaries): Declare.
* ipa-cp.c (pass_ipa_cp): Update.
* ipa-reference.c (pass_ipa_reference): Update.
* ipa-pure-const.c (pass_ipa_pure_const): Update.
* lto-streamer-out.c (pass_ipa_lto_gimple, pass_ipa_lto_finish):
Update.
* ipa-inline.c (pass_ipa_inline): Update.
* ipa.c (pass_ipa_whole_program): Update.
* lto-wpa-fixup.c (pass_ipa_lto_wpa_fixup): Update.
* passes.c (ipa_write_summaries_1): Do not test wpa.
(ipa_write_optimization_summaries_1): New.
(ipa_write_optimization_summaries): New.
(ipa_read_summaries): Do not test ltrans.
(ipa_read_optimization_summaries_1): New.
(ipa_read_optimization_summaries): New.

* lto.c (lto_wpa_write_files): Update.
(read_cgraph_and_symbols): Be more verbose.
(materialize_cgraph): Likewise.
(do_whole_program_analysis): Likewise.

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

gcc/ChangeLog
gcc/ipa-cp.c
gcc/ipa-inline.c
gcc/ipa-reference.c
gcc/ipa.c
gcc/lto-wpa-fixup.c [new file with mode: 0644]
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/passes.c
gcc/tree-pass.h

index bb8e0aa..85d4103 100644 (file)
@@ -1,5 +1,27 @@
 2010-04-21  Jan Hubicka  <jh@suse.cz>
 
+       * tree-pass.h (ipa_opt_pass_d): Rename function_read_summary;
+       add write_optimization_summary, read_optimization_summary.
+       (ipa_write_summaries_of_cgraph_node_set): Remove.
+       (ipa_write_optimization_summaries): Declare.
+       (ipa_read_optimization_summaries): Declare.
+       * ipa-cp.c (pass_ipa_cp): Update.
+       * ipa-reference.c (pass_ipa_reference): Update.
+       * ipa-pure-const.c (pass_ipa_pure_const): Update.
+       * lto-streamer-out.c (pass_ipa_lto_gimple, pass_ipa_lto_finish):
+       Update.
+       * ipa-inline.c (pass_ipa_inline): Update.
+       * ipa.c (pass_ipa_whole_program): Update.
+       * lto-wpa-fixup.c (pass_ipa_lto_wpa_fixup): Update.
+       * passes.c (ipa_write_summaries_1): Do not test wpa.
+       (ipa_write_optimization_summaries_1): New.
+       (ipa_write_optimization_summaries): New.
+       (ipa_read_summaries): Do not test ltrans.
+       (ipa_read_optimization_summaries_1): New.
+       (ipa_read_optimization_summaries): New.
+
+2010-04-21  Jan Hubicka  <jh@suse.cz>
+
        * lto-cgraph.c (lto_output_node): Do not output comdat groups
        for boundary nodes.
        (output_cgraph): Do not arrange comdat groups for boundary nodes.
index 5c953b4..ca7c0e6 100644 (file)
@@ -131,7 +131,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "timevar.h"
 #include "diagnostic.h"
-#include "tree-pretty-print.h"
 #include "tree-dump.h"
 #include "tree-inline.h"
 #include "fibheap.h"
@@ -184,7 +183,6 @@ ipcp_analyze_node (struct cgraph_node *node)
   /* Unreachable nodes should have been eliminated before ipcp.  */
   gcc_assert (node->needed || node->reachable);
 
-  node->local.versionable = tree_versionable_function_p (node->decl);
   ipa_initialize_node_params (node);
   ipa_detect_param_modifications (node);
 }
@@ -417,21 +415,35 @@ ipcp_print_all_lattices (FILE * f)
 static bool
 ipcp_versionable_function_p (struct cgraph_node *node)
 {
-  struct cgraph_edge *edge;
+  tree decl = node->decl;
+  basic_block bb;
 
   /* There are a number of generic reasons functions cannot be versioned.  */
-  if (!node->local.versionable)
+  if (!tree_versionable_function_p (decl))
     return false;
 
-  /* Removing arguments doesn't work if the function takes varargs
-     or use __builtin_apply_args. */
-  for (edge = node->callees; edge; edge = edge->next_callee)
+  /* Removing arguments doesn't work if the function takes varargs.  */
+  if (DECL_STRUCT_FUNCTION (decl)->stdarg)
+    return false;
+
+  /* Removing arguments doesn't work if we use __builtin_apply_args.  */
+  FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (decl))
     {
-      tree t = edge->callee->decl;
-      if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
-         && (DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS
-            || DECL_FUNCTION_CODE (t) == BUILT_IN_VA_START))
-       return false;
+      gimple_stmt_iterator gsi;
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         const_gimple stmt = gsi_stmt (gsi);
+         tree t;
+
+         if (!is_gimple_call (stmt))
+           continue;
+         t = gimple_call_fndecl (stmt);
+         if (t == NULL_TREE)
+           continue;
+         if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
+             && DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS)
+           return false;
+       }
     }
 
   return true;
@@ -615,6 +627,7 @@ static void
 ipcp_init_stage (void)
 {
   struct cgraph_node *node;
+  struct cgraph_edge *cs;
 
   for (node = cgraph_nodes; node; node = node->next)
     if (node->analyzed)
@@ -623,10 +636,19 @@ ipcp_init_stage (void)
     {
       if (!node->analyzed)
        continue;
-
-      ipa_analyze_params_uses (node);
       /* building jump functions  */
-      ipa_compute_jump_functions (node);
+      for (cs = node->callees; cs; cs = cs->next_callee)
+       {
+         /* We do not need to bother analyzing calls to unknown
+            functions unless they may become known during lto/whopr.  */
+         if (!cs->callee->analyzed && !flag_lto && !flag_whopr)
+           continue;
+         ipa_count_arguments (cs);
+         if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
+             != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
+           ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
+         ipa_compute_jump_functions (cs);
+       }
     }
 }
 
@@ -908,9 +930,12 @@ ipcp_update_callgraph (void)
        for (i = 0; i < count; i++)
          {
            struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
+           tree parm_tree = ipa_get_param (info, i);
 
            /* We can proactively remove obviously unused arguments.  */
-           if (!ipa_is_param_used (info, i))
+           if (is_gimple_reg (parm_tree)
+               && !gimple_default_def (DECL_STRUCT_FUNCTION (orig_node->decl),
+                                       parm_tree))
              {
                bitmap_set_bit (args_to_skip, i);
                continue;
@@ -983,9 +1008,12 @@ ipcp_estimate_growth (struct cgraph_node *node)
   for (i = 0; i < count; i++)
     {
       struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
+      tree parm_tree = ipa_get_param (info, i);
 
       /* We can proactively remove obviously unused arguments.  */
-      if (!ipa_is_param_used (info, i))
+      if (is_gimple_reg (parm_tree)
+         && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
+                                 parm_tree))
        removable_args++;
 
       if (lat->type == IPA_CONST_VALUE)
@@ -1053,9 +1081,12 @@ ipcp_const_param_count (struct cgraph_node *node)
   for (i = 0; i < count; i++)
     {
       struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
+      tree parm_tree = ipa_get_param (info, i);
       if (ipcp_lat_is_insertable (lat)
          /* Do not count obviously unused arguments.  */
-          && ipa_is_param_used (info, i))
+         && (!is_gimple_reg (parm_tree)
+             || gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
+                                    parm_tree)))
        const_param++;
     }
   return const_param;
@@ -1159,7 +1190,9 @@ ipcp_insert_stage (void)
          parm_tree = ipa_get_param (info, i);
 
          /* We can proactively remove obviously unused arguments.  */
-          if (!ipa_is_param_used (info, i))
+         if (is_gimple_reg (parm_tree)
+             && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
+                                     parm_tree))
            {
              bitmap_set_bit (args_to_skip, i);
              continue;
@@ -1249,7 +1282,7 @@ ipcp_driver (void)
       ipcp_print_profile_data (dump_file);
     }
   /* Free all IPCP structures.  */
-  ipa_free_all_structures_after_ipa_cp ();
+  free_all_ipa_structures_after_ipa_cp ();
   if (dump_file)
     fprintf (dump_file, "\nIPA constant propagation end\n");
   return 0;
@@ -1271,8 +1304,7 @@ ipcp_generate_summary (void)
 
 /* Write ipcp summary for nodes in SET.  */
 static void
-ipcp_write_summary (cgraph_node_set set,
-                   varpool_node_set vset ATTRIBUTE_UNUSED)
+ipcp_write_summary (cgraph_node_set set)
 {
   ipa_prop_write_jump_functions (set);
 }
@@ -1307,14 +1339,14 @@ struct ipa_opt_pass_d pass_ipa_cp =
   0,                           /* properties_destroyed */
   0,                           /* todo_flags_start */
   TODO_dump_cgraph | TODO_dump_func |
-  TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */
+  TODO_remove_functions /* todo_flags_finish */
  },
  ipcp_generate_summary,                        /* generate_summary */
  ipcp_write_summary,                   /* write_summary */
  ipcp_read_summary,                    /* read_summary */
  NULL,                                 /* write_optimization_summary */
  NULL,                                 /* read_optimization_summary */
NULL,                                 /* stmt_fixup */
lto_ipa_fixup_call_notes,             /* stmt_fixup */
  0,                                    /* TODOs */
  NULL,                                 /* function_transform */
  NULL,                                 /* variable_transform */
index 8957990..fbd695d 100644 (file)
@@ -2135,7 +2135,8 @@ struct ipa_opt_pass_d pass_ipa_inline =
  inline_generate_summary,              /* generate_summary */
  inline_write_summary,                 /* write_summary */
  inline_read_summary,                  /* read_summary */
- NULL,                                 /* function_read_summary */
+ NULL,                                 /* write_optimization_summary */
+ NULL,                                 /* read_optimization_summary */
  lto_ipa_fixup_call_notes,             /* stmt_fixup */
  0,                                    /* TODOs */
  inline_transform,                     /* function_transform */
index 9eac3b1..7183e65 100644 (file)
@@ -1514,7 +1514,8 @@ struct ipa_opt_pass_d pass_ipa_reference =
  generate_summary,                     /* generate_summary */
  ipa_reference_write_summary,          /* write_summary */
  ipa_reference_read_summary,           /* read_summary */
- NULL,                                 /* function_read_summary */
+ NULL,                                 /* write_optimization_summary */
+ NULL,                                 /* read_optimization_summary */
  NULL,                                 /* stmt_fixup */
  0,                                    /* TODOs */
  NULL,                                 /* function_transform */
index d559ab2..3a5ef16 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -271,6 +271,8 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
                      node->analyzed = false;
                      node->local.inlinable = false;
                    }
+                 else
+                   gcc_assert (!clone->in_other_partition);
                  cgraph_node_remove_callees (node);
                  if (node->prev_sibling_clone)
                    node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
@@ -574,7 +576,8 @@ struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
  NULL,                                 /* generate_summary */
  NULL,                                 /* write_summary */
  NULL,                                 /* read_summary */
- NULL,                                 /* function_read_summary */
+ NULL,                                 /* write_optimization_summary */
+ NULL,                                 /* read_optimization_summary */
  NULL,                                 /* stmt_fixup */
  0,                                    /* TODOs */
  NULL,                                 /* function_transform */
diff --git a/gcc/lto-wpa-fixup.c b/gcc/lto-wpa-fixup.c
new file mode 100644 (file)
index 0000000..46d66e5
--- /dev/null
@@ -0,0 +1,283 @@
+/* Write and read any fix-up information generated by the WPA mode.
+
+   Copyright 2009 Free Software Foundation, Inc.
+   Contributed by Doug Kwan <dougkwan@google.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "toplev.h"
+#include "tree.h"
+#include "expr.h"
+#include "flags.h"
+#include "cgraph.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "vec.h"
+#include "bitmap.h"
+#include "timevar.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "lto-streamer.h"
+
+/* LTO fix-up.
+
+   In WPA mode, LTO cannot access function bodies.  Some modifications in
+   IR require additional updates in function bodies,  which are not possible
+   in WPA mode.  So we write out information about these modifications for
+   LTRANS to fix up the function bodies accordingly.  */
+
+/* The vectors records function DECLs having multiple copies with different
+   exception throwing attributes.  We do not mark a DECL if all copies of it
+   have the same exception throwing attribute. */
+static bitmap lto_nothrow_fndecls;
+
+/* We need to fix up GIMPLE bodies due to changes in exception setting.
+   Consider this example:
+
+   a.h:
+   class a {
+   public:
+     a();
+     ~a();
+   };
+
+   main.cc:
+   #include "a.h"
+
+   int
+   main (int argc, char **argv)
+   {
+     a x;
+     return 0;
+   }
+
+   a.cc:
+   #include "a.h"
+   a::a() {}
+   a::~a() {}
+
+   When main.cc is compiled, gcc only sees the constructor declaration, so
+   the constructor and hence the call to it are marked as exception throwing.
+   When a.cc is compiled, the body of the constructor is available and is
+   obviously not exception throwing. Thus DECL of a::a in a.o has the NOTHROW
+   attribute.  When LTO runs, two DECLs of a::a with different exception
+   attributes are merged.  We want the merged DECL to be not exception
+   throwing for better generated code.  To do that, we need to fix up any
+   function calls that have been marked as exception throwing.  */
+
+/* Fix up all the call statements whose target fndecls might have changed
+   to NOTHROW.   Note that this problem is not WPA specific.  We can also
+   run into this problem in normal LTO with multiple input files.  */
+
+void
+lto_fixup_nothrow_decls (void)
+{
+  struct cgraph_node *node;
+  struct cgraph_edge *edge;
+  struct function *caller_function;
+  gimple call_stmt;
+
+  /* Quit if we are in WPA mode or have not marked any DECLs.  */
+  if (flag_wpa || !lto_nothrow_fndecls)
+    return;
+
+  /* For each node that has been marked, go over all call edges to it.  */
+  for (node = cgraph_nodes; node; node = node->next)
+    if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (node->decl)))
+      {
+       gcc_assert (TREE_NOTHROW (node->decl));
+       for (edge = node->callers; edge; edge = edge->next_caller)
+         {
+           caller_function = DECL_STRUCT_FUNCTION (edge->caller->decl);
+           call_stmt = edge->call_stmt;
+           gcc_assert (call_stmt);
+           if (lookup_stmt_eh_lp_fn (caller_function, call_stmt) != 0)
+             remove_stmt_from_eh_lp_fn (caller_function, call_stmt);
+         }
+      }
+}
+
+/* Mark FNDECL as becoming not exception throwing.  */
+
+void
+lto_mark_nothrow_fndecl (tree fndecl)
+{
+  gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
+  if (!lto_nothrow_fndecls)
+    lto_nothrow_fndecls = lto_bitmap_alloc ();
+
+  bitmap_set_bit (lto_nothrow_fndecls, DECL_UID (fndecl));
+}
+
+/* Write out fix-up information.  Currently the only WPA fix-up
+   information is the list of DECLs marked as not exception throwing. SET
+   is a cgraph node set whose fix-up information is to be written.  */
+
+static void
+lto_output_wpa_fixup (cgraph_node_set set)
+{
+  struct lto_simple_output_block *ob;
+  cgraph_node_set_iterator csi;
+  tree fndecl;
+  bitmap seen_decls;
+  VEC(tree, heap) *decls = NULL;
+  unsigned HOST_WIDE_INT i, count;
+
+  ob = lto_create_simple_output_block (LTO_section_wpa_fixup);
+
+  /* Accumulate the DECLs to be written out.  Since we do not want
+     duplicates, we need to use a bitmap and a vector to save the
+     DECLs we want.  Note that we need to check if lto_nothrow_fndecls
+     is NULL.  This happens when no DECL has been marked.  */
+  seen_decls = lto_bitmap_alloc ();
+  if (lto_nothrow_fndecls)
+    for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
+      {
+       struct cgraph_edge *e;
+       struct cgraph_node *n;
+
+       n = csi_node (csi);
+       fndecl = n->decl;
+
+       /* Check if the N's function is in the set of nothrow functions.  */
+       if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl)))
+         {
+           bitmap_set_bit (seen_decls, (DECL_UID (fndecl)));
+           if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl)))
+             VEC_safe_push (tree, heap, decls, fndecl);
+         }
+
+       /* Now check the callees and also add them if they are nothrow.  This
+          is needed because node N may end up in a different partition than
+          its callees.  In which case, when the file holding N is compiled,
+          the calls it makes to nothrow functions will not be fixed up,
+          causing verification issues.  */
+       for (e = n->callees; e; e = e->next_callee)
+         {
+           fndecl = e->callee->decl;
+           if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl)))
+             {
+               bitmap_set_bit (seen_decls, (DECL_UID (fndecl)));
+               if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl)))
+                 VEC_safe_push (tree, heap, decls, fndecl);
+             }
+         }
+      }
+
+  /* Write out number of DECLs, followed by the DECLs.  */
+  count = VEC_length (tree, decls);
+  lto_output_uleb128_stream (ob->main_stream, count);
+  for (i = 0; i < count; i++)
+    {
+      fndecl = VEC_index (tree, decls, i);
+      lto_output_fn_decl_index (ob->decl_state, ob->main_stream, fndecl);
+    }
+
+  /* Release resources.  */
+  lto_destroy_simple_output_block (ob);
+  VEC_free(tree, heap, decls);
+  lto_bitmap_free (seen_decls);
+}
+
+/* Read in WPA fix-up information from one file. FILE_DATA points to
+   DECL information of the file where as IB is the input block for the
+   WPA fix-up section.  */
+
+static void
+lto_input_wpa_fixup_1 (struct lto_file_decl_data *file_data,
+                  struct lto_input_block *ib)
+{
+  unsigned HOST_WIDE_INT i, count, decl_index;
+  tree fndecl;
+
+  count = lto_input_uleb128 (ib);
+  for (i = 0; i < count; i++)
+    {
+      decl_index = lto_input_uleb128 (ib);
+      fndecl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
+      lto_mark_nothrow_fndecl (fndecl);
+    }
+}
+
+/* Read in WPA fix-up information. */
+
+static void
+lto_input_wpa_fixup (void)
+{
+  struct lto_file_decl_data ** file_data_vec
+    = lto_get_file_decl_data ();
+  struct lto_file_decl_data * file_data;
+  int i = 0;
+
+  /* Fix up information is only used in LTRANS mode.  */
+  if (!flag_ltrans)
+    return;
+
+  while ((file_data = file_data_vec[i++]))
+    {
+      const char *data;
+      size_t len;
+      struct lto_input_block *ib
+       = lto_create_simple_input_block (file_data, LTO_section_wpa_fixup,
+                                        &data, &len);
+
+      lto_input_wpa_fixup_1 (file_data, ib);
+      lto_destroy_simple_input_block (file_data, LTO_section_wpa_fixup, ib,
+                                     data, len);
+    }
+}
+
+/* Gate function for all lto streaming passes.  */
+
+static bool
+gate_wpa_fixup (void)
+{
+  return (flag_wpa || flag_ltrans) && gate_lto_out ();
+}
+
+struct ipa_opt_pass_d pass_ipa_lto_wpa_fixup =
+{
+ {
+  IPA_PASS,
+  "lto_wpa_fixup",                     /* name */
+  gate_wpa_fixup,                      /* gate */
+  NULL,                                        /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_WHOPR_WPA_FIXUP,                  /* tv_id */
+  0,                                   /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_dump_func                        /* todo_flags_finish */
+ },
+ NULL,                                 /* generate_summary */
+ NULL,                                 /* write_summary */
+ NULL,                                 /* read_summary */
+ lto_output_wpa_fixup,                 /* write_optimization_summary */
+ lto_input_wpa_fixup,                  /* read_optimization_summary */
+ NULL,                                 /* stmt_fixup */
+ 0,                                    /* TODOs */
+ NULL,                                 /* function_transform */
+ NULL                                  /* variable_transform */
+};
+
index a97314c..74e0650 100644 (file)
@@ -1,5 +1,12 @@
 2010-04-21  Jan Hubicka  <jh@suse.cz>
 
+       * lto.c (lto_wpa_write_files): Update.
+       (read_cgraph_and_symbols): Be more verbose.
+       (materialize_cgraph): Likewise.
+       (do_whole_program_analysis): Likewise.
+
+2010-04-21  Jan Hubicka  <jh@suse.cz>
+
        * lto.c (globalize_cross_file_statics): When function has address taken,
        it needs to be public.
 
index ea8f03a..12475f1 100644 (file)
@@ -1046,7 +1046,7 @@ lto_wpa_write_files (void)
 
          lto_set_current_out_file (file);
 
-         ipa_write_summaries_of_cgraph_node_set (set);
+         ipa_write_optimization_summaries (set);
 
          lto_set_current_out_file (NULL);
          lto_elf_file_close (file);
@@ -1822,10 +1822,18 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
       gcc_assert (num_objects == nfiles);
     }
 
+  if (!quiet_flag)
+    fprintf (stderr, "Reading object files:");
+
   /* Read all of the object files specified on the command line.  */
   for (i = 0, last_file_ix = 0; i < nfiles; ++i)
     {
       struct lto_file_decl_data *file_data = NULL;
+      if (!quiet_flag)
+       {
+         fprintf (stderr, " %s", fnames[i]);
+         fflush (stderr);
+       }
 
       current_lto_file = lto_elf_file_open (fnames[i], false);
       if (!current_lto_file)
@@ -1852,9 +1860,15 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   /* Each pass will set the appropriate timer.  */
   timevar_pop (TV_IPA_LTO_DECL_IO);
 
+  if (!quiet_flag)
+    fprintf (stderr, "\nReading the callgraph\n");
+
   /* Read the callgraph.  */
   input_cgraph ();
 
+  if (!quiet_flag)
+    fprintf (stderr, "Merging declarations\n");
+
   /* Merge global decls.  */
   lto_symtab_merge_decls ();
 
@@ -1862,8 +1876,14 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   lto_fixup_decls (all_file_decl_data);
   free_gimple_type_tables ();
 
+  if (!quiet_flag)
+    fprintf (stderr, "Reading summaries\n");
+
   /* Read the IPA summary data.  */
-  ipa_read_summaries ();
+  if (flag_ltrans)
+    ipa_read_optimization_summaries ();
+  else
+    ipa_read_summaries ();
 
   /* Finally merge the cgraph according to the decl merging decisions.  */
   lto_symtab_merge_cgraph_nodes ();
@@ -1909,6 +1929,11 @@ materialize_cgraph (void)
   unsigned i;
   timevar_id_t lto_timer;
 
+  if (!quiet_flag)
+    fprintf (stderr,
+            flag_wpa ? "Materializing decls:" : "Reading function bodies:");
+
+
   /* Now that we have input the cgraph, we need to clear all of the aux
      nodes and read the functions if we are not running in WPA mode.  */
   timevar_push (TV_IPA_LTO_GIMPLE_IO);
@@ -1927,6 +1952,7 @@ materialize_cgraph (void)
       if (node->local.lto_file_data
           && !DECL_IS_BUILTIN (node->decl))
        {
+         announce_function (node->decl);
          lto_materialize_function (node);
          lto_stats.num_input_cgraph_nodes++;
        }
@@ -1950,6 +1976,8 @@ materialize_cgraph (void)
 
   /* Fix up any calls to DECLs that have become not exception throwing.  */
   lto_fixup_nothrow_decls ();
+  if (!quiet_flag)
+    fprintf (stderr, "\n");
 
   timevar_pop (lto_timer);
 }
@@ -1987,7 +2015,14 @@ do_whole_program_analysis (void)
 
   lto_1_to_1_map ();
 
+  if (!quiet_flag)
+    {
+      fprintf (stderr, "\nStreaming out");
+      fflush (stderr);
+    }
   output_files = lto_wpa_write_files ();
+  if (!quiet_flag)
+    fprintf (stderr, "\n");
 
   /* Show the LTO report before launching LTRANS.  */
   if (flag_lto_report)
index 6437ab7..d9bf3cc 100644 (file)
@@ -1674,8 +1674,8 @@ ipa_write_summaries_1 (cgraph_node_set set)
   struct lto_out_decl_state *state = lto_new_out_decl_state ();
   lto_push_out_decl_state (state);
 
-  if (!flag_wpa)
-    ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
+  gcc_assert (!flag_wpa);
+  ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
   ipa_write_summaries_2 (all_lto_gen_passes, set, state);
 
   gcc_assert (lto_get_out_decl_state () == state);
@@ -1730,15 +1730,58 @@ ipa_write_summaries (void)
   ggc_free (set);
 }
 
+/* Same as execute_pass_list but assume that subpasses of IPA passes
+   are local passes. If SET is not NULL, write out optimization summaries of
+   only those node in SET. */
 
-/* Write all the summaries for the cgraph nodes in SET.  If SET is
+static void
+ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set,
+                      struct lto_out_decl_state *state)
+{
+  while (pass)
+    {
+      struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *)pass;
+      gcc_assert (!current_function_decl);
+      gcc_assert (!cfun);
+      gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
+      if (pass->type == IPA_PASS
+         && ipa_pass->write_optimization_summary
+         && (!pass->gate || pass->gate ()))
+       {
+         /* If a timevar is present, start it.  */
+         if (pass->tv_id)
+           timevar_push (pass->tv_id);
+
+         ipa_pass->write_optimization_summary (set);
+
+         /* If a timevar is present, start it.  */
+         if (pass->tv_id)
+           timevar_pop (pass->tv_id);
+       }
+
+      if (pass->sub && pass->sub->type != GIMPLE_PASS)
+       ipa_write_optimization_summaries_1 (pass->sub, set, state);
+
+      pass = pass->next;
+    }
+}
+
+/* Write all the optimization summaries for the cgraph nodes in SET.  If SET is
    NULL, write out all summaries of all nodes. */
 
 void
-ipa_write_summaries_of_cgraph_node_set (cgraph_node_set set)
+ipa_write_optimization_summaries (cgraph_node_set set)
 {
-  if (flag_generate_lto && !(errorcount || sorrycount))
-    ipa_write_summaries_1 (set);
+  struct lto_out_decl_state *state = lto_new_out_decl_state ();
+  lto_push_out_decl_state (state);
+
+  gcc_assert (flag_wpa);
+  ipa_write_optimization_summaries_1 (all_regular_ipa_passes, set, state);
+  ipa_write_optimization_summaries_1 (all_lto_gen_passes, set, state);
+
+  gcc_assert (lto_get_out_decl_state () == state);
+  lto_pop_out_decl_state ();
+  lto_delete_out_decl_state (state);
 }
 
 /* Same as execute_pass_list but assume that subpasses of IPA passes
@@ -1783,13 +1826,57 @@ ipa_read_summaries_1 (struct opt_pass *pass)
 void
 ipa_read_summaries (void)
 {
-  if (!flag_ltrans)
-    ipa_read_summaries_1 (all_regular_ipa_passes);
+  ipa_read_summaries_1 (all_regular_ipa_passes);
   ipa_read_summaries_1 (all_lto_gen_passes);
 }
 
 /* Same as execute_pass_list but assume that subpasses of IPA passes
    are local passes.  */
+
+static void
+ipa_read_optimization_summaries_1 (struct opt_pass *pass)
+{
+  while (pass)
+    {
+      struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
+
+      gcc_assert (!current_function_decl);
+      gcc_assert (!cfun);
+      gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
+
+      if (pass->gate == NULL || pass->gate ())
+       {
+         if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
+           {
+             /* If a timevar is present, start it.  */
+             if (pass->tv_id)
+               timevar_push (pass->tv_id);
+
+             ipa_pass->read_optimization_summary ();
+
+             /* Stop timevar.  */
+             if (pass->tv_id)
+               timevar_pop (pass->tv_id);
+           }
+
+         if (pass->sub && pass->sub->type != GIMPLE_PASS)
+           ipa_read_optimization_summaries_1 (pass->sub);
+       }
+      pass = pass->next;
+    }
+}
+
+/* Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes.  */
+
+void
+ipa_read_optimization_summaries (void)
+{
+  ipa_read_optimization_summaries_1 (all_regular_ipa_passes);
+  ipa_read_optimization_summaries_1 (all_lto_gen_passes);
+}
+
+/* Same as execute_pass_list but assume that subpasses of IPA passes
+   are local passes.  */
 void
 execute_ipa_pass_list (struct opt_pass *pass)
 {
index 5ed86b4..42ef8b2 100644 (file)
@@ -168,7 +168,6 @@ struct rtl_opt_pass
 struct varpool_node;
 struct cgraph_node;
 struct cgraph_node_set_def;
-struct varpool_node_set_def;
 
 /* Description of IPA pass with generate summary, write, execute, read and
    transform stages.  */
@@ -181,15 +180,13 @@ struct ipa_opt_pass_d
   void (*generate_summary) (void);
 
   /* This hook is used to serialize IPA summaries on disk.  */
-  void (*write_summary) (struct cgraph_node_set_def *,
-                        struct varpool_node_set_def *);
+  void (*write_summary) (struct cgraph_node_set_def *);
 
   /* This hook is used to deserialize IPA summaries from disk.  */
   void (*read_summary) (void);
 
   /* This hook is used to serialize IPA optimization summaries on disk.  */
-  void (*write_optimization_summary) (struct cgraph_node_set_def *,
-                                     struct varpool_node_set_def *);
+  void (*write_optimization_summary) (struct cgraph_node_set_def *);
 
   /* This hook is used to deserialize IPA summaries from disk.  */
   void (*read_optimization_summary) (void);
@@ -414,7 +411,6 @@ extern struct gimple_opt_pass pass_late_warn_uninitialized;
 extern struct gimple_opt_pass pass_cse_reciprocals;
 extern struct gimple_opt_pass pass_cse_sincos;
 extern struct gimple_opt_pass pass_optimize_bswap;
-extern struct gimple_opt_pass pass_optimize_widening_mul;
 extern struct gimple_opt_pass pass_warn_function_return;
 extern struct gimple_opt_pass pass_warn_function_noreturn;
 extern struct gimple_opt_pass pass_cselim;
@@ -462,7 +458,6 @@ extern struct simple_ipa_opt_pass pass_ipa_pta;
 extern struct simple_ipa_opt_pass pass_ipa_struct_reorg;
 extern struct ipa_opt_pass_d pass_ipa_lto_wpa_fixup;
 extern struct ipa_opt_pass_d pass_ipa_lto_finish_out;
-extern struct ipa_opt_pass_d pass_ipa_profile;
 
 extern struct gimple_opt_pass pass_all_optimizations;
 extern struct gimple_opt_pass pass_cleanup_cfg_post_optimizing;
@@ -515,7 +510,6 @@ extern struct rtl_opt_pass pass_stack_ptr_mod;
 extern struct rtl_opt_pass pass_initialize_regs;
 extern struct rtl_opt_pass pass_combine;
 extern struct rtl_opt_pass pass_if_after_combine;
-extern struct rtl_opt_pass pass_implicit_zee;
 extern struct rtl_opt_pass pass_partition_blocks;
 extern struct rtl_opt_pass pass_match_asm_constraints;
 extern struct rtl_opt_pass pass_regmove;
@@ -611,8 +605,7 @@ extern const char *get_current_pass_name (void);
 extern void print_current_pass (FILE *);
 extern void debug_pass (void);
 extern void ipa_write_summaries (void);
-extern void ipa_write_optimization_summaries (struct cgraph_node_set_def *,
-                                             struct varpool_node_set_def *);
+extern void ipa_write_optimization_summaries (struct cgraph_node_set_def *);
 extern void ipa_read_summaries (void);
 extern void ipa_read_optimization_summaries (void);
 extern void register_one_dump_file (struct opt_pass *);