]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/lto-streamer-out.c
Merge from trunk.
[thirdparty/gcc.git] / gcc / lto-streamer-out.c
index a962e9c50032df189a2b7d378dbe2d31ddc03d01..733119f6953262c1b13732b379a102df60a43c38 100644 (file)
@@ -25,15 +25,19 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "stor-layout.h"
+#include "stringpool.h"
 #include "expr.h"
 #include "flags.h"
 #include "params.h"
 #include "input.h"
 #include "hashtab.h"
 #include "basic-block.h"
-#include "tree-flow.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-ssa.h"
+#include "tree-ssanames.h"
 #include "tree-pass.h"
-#include "cgraph.h"
 #include "function.h"
 #include "ggc.h"
 #include "diagnostic-core.h"
@@ -124,8 +128,11 @@ output_type_ref (struct output_block *ob, tree node)
 static bool
 tree_is_indexable (tree t)
 {
-  if (TREE_CODE (t) == PARM_DECL)
-    return true;
+  /* Parameters and return values of functions of variably modified types
+     must go to global stream, because they may be used in the type
+     definition.  */
+  if (TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
+    return variably_modified_type_p (TREE_TYPE (DECL_CONTEXT (t)), NULL_TREE);
   else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
           && !TREE_STATIC (t))
     return false;
@@ -364,7 +371,7 @@ lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
 {
   if (!lto_is_streamable (expr))
     internal_error ("tree code %qs is not supported in LTO streams",
-                   tree_code_name[TREE_CODE (expr)]);
+                   get_tree_code_name (TREE_CODE (expr)));
 
   /* Write the header, containing everything needed to materialize
      EXPR on the reading side.  */
@@ -506,13 +513,7 @@ DFS_write_tree_body (struct output_block *ob,
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
     {
-      if (TREE_CODE (expr) == FUNCTION_DECL)
-       {
-         for (tree t = DECL_ARGUMENTS (expr); t; t = TREE_CHAIN (t))
-           DFS_follow_tree_edge (t);
-         DFS_follow_tree_edge (DECL_RESULT (expr));
-       }
-      else if (TREE_CODE (expr) == TYPE_DECL)
+      if (TREE_CODE (expr) == TYPE_DECL)
        DFS_follow_tree_edge (DECL_ORIGINAL_TYPE (expr));
       DFS_follow_tree_edge (DECL_VINDEX (expr));
     }
@@ -648,9 +649,8 @@ DFS_write_tree_body (struct output_block *ob,
       FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t)
        DFS_follow_tree_edge (t);
 
-      DFS_follow_tree_edge (BINFO_INHERITANCE_CHAIN (expr));
-      DFS_follow_tree_edge (BINFO_SUBVTT_INDEX (expr));
-      DFS_follow_tree_edge (BINFO_VPTR_INDEX (expr));
+      /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+        and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -714,8 +714,11 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
 
   if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
     {
-      v = iterative_hash_host_wide_int (TREE_INT_CST_LOW (t), v);
-      v = iterative_hash_host_wide_int (TREE_INT_CST_HIGH (t), v);
+      int i; 
+      v = iterative_hash_host_wide_int (TREE_INT_CST_NUNITS (t), v);
+      v = iterative_hash_host_wide_int (TREE_INT_CST_EXT_NUNITS (t), v);
+      for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
+       v = iterative_hash_host_wide_int (TREE_INT_CST_ELT (t, i), v);
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
@@ -754,7 +757,6 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
       v = iterative_hash_host_wide_int (DECL_ALIGN (t), v);
       if (code == LABEL_DECL)
        {
-         v = iterative_hash_host_wide_int (DECL_ERROR_ISSUED (t), v);
          v = iterative_hash_host_wide_int (EH_LANDING_PAD_NR (t), v);
          v = iterative_hash_host_wide_int (LABEL_DECL_UID (t), v);
        }
@@ -787,23 +789,27 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
     {
-      v = iterative_hash_host_wide_int (DECL_DEFER_OUTPUT (t)
-                                       | (DECL_COMMON (t) << 1)
-                                       | (DECL_DLLIMPORT_P (t) << 2)
-                                       | (DECL_WEAK (t) << 3)
-                                       | (DECL_SEEN_IN_BIND_EXPR_P (t) << 4)
-                                       | (DECL_COMDAT (t) << 5)
+      v = iterative_hash_host_wide_int ((DECL_COMMON (t))
+                                       | (DECL_DLLIMPORT_P (t) << 1)
+                                       | (DECL_WEAK (t) << 2)
+                                       | (DECL_SEEN_IN_BIND_EXPR_P (t) << 3)
+                                       | (DECL_COMDAT (t) << 4)
                                        | (DECL_VISIBILITY_SPECIFIED (t) << 6),
                                        v);
       v = iterative_hash_host_wide_int (DECL_VISIBILITY (t), v);
       if (code == VAR_DECL)
        {
+         /* DECL_IN_TEXT_SECTION is set during final asm output only.  */
          v = iterative_hash_host_wide_int (DECL_HARD_REGISTER (t)
-                                           | (DECL_IN_TEXT_SECTION (t) << 1)
-                                           | (DECL_IN_CONSTANT_POOL (t) << 2),
+                                           | (DECL_IN_CONSTANT_POOL (t) << 1),
                                            v);
          v = iterative_hash_host_wide_int (DECL_TLS_MODEL (t), v);
        }
+      if (TREE_CODE (t) == FUNCTION_DECL)
+       v = iterative_hash_host_wide_int (DECL_FINAL_P (t)
+                                         | (DECL_CXX_CONSTRUCTOR_P (t) << 1)
+                                         | (DECL_CXX_DESTRUCTOR_P (t) << 2),
+                                         v);
       if (VAR_OR_FUNCTION_DECL_P (t))
        v = iterative_hash_host_wide_int (DECL_INIT_PRIORITY (t), v);
     }
@@ -844,7 +850,10 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
                                        | (TYPE_USER_ALIGN (t) << 5)
                                        | (TYPE_READONLY (t) << 6), v);
       if (RECORD_OR_UNION_TYPE_P (t))
-       v = iterative_hash_host_wide_int (TYPE_TRANSPARENT_AGGR (t), v);
+       {
+         v = iterative_hash_host_wide_int (TYPE_TRANSPARENT_AGGR (t)
+                                           | (TYPE_FINAL_P (t) << 1), v);
+       }
       else if (code == ARRAY_TYPE)
        v = iterative_hash_host_wide_int (TYPE_NONALIASED_COMPONENT (t), v);
       v = iterative_hash_host_wide_int (TYPE_PRECISION (t), v);
@@ -936,13 +945,7 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
     {
-      if (code == FUNCTION_DECL)
-       {
-         for (tree a = DECL_ARGUMENTS (t); a; a = DECL_CHAIN (a))
-           visit (a);
-         visit (DECL_RESULT (t));
-       }
-      else if (code == TYPE_DECL)
+      if (code == TYPE_DECL)
        visit (DECL_ORIGINAL_TYPE (t));
       visit (DECL_VINDEX (t));
     }
@@ -1033,9 +1036,8 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
       visit (BINFO_VPTR_FIELD (t));
       FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (t), i, b)
        visit (b);
-      visit (BINFO_INHERITANCE_CHAIN (t));
-      visit (BINFO_SUBVTT_INDEX (t));
-      visit (BINFO_VPTR_INDEX (t));
+      /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+        and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -1246,7 +1248,7 @@ DFS_write_tree (struct output_block *ob, sccs *from_state,
                  if (!lto_is_streamable (t))
                    internal_error ("tree code %qs is not supported "
                                    "in LTO streams",
-                                   tree_code_name[TREE_CODE (t)]);
+                                   get_tree_code_name (TREE_CODE (t)));
 
                  gcc_checking_assert (!streamer_handle_as_builtin_p (t));
 
@@ -1595,7 +1597,7 @@ output_cfg (struct output_block *ob, struct function *fn)
 
   streamer_write_hwi (ob, -1);
 
-  bb = ENTRY_BLOCK_PTR;
+  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
   while (bb->next_bb)
     {
       streamer_write_hwi (ob, bb->next_bb->index);
@@ -1632,14 +1634,24 @@ output_cfg (struct output_block *ob, struct function *fn)
       streamer_write_hwi (ob, loop->any_upper_bound);
       if (loop->any_upper_bound)
        {
-         streamer_write_uhwi (ob, loop->nb_iterations_upper_bound.low);
-         streamer_write_hwi (ob, loop->nb_iterations_upper_bound.high);
+         int len = loop->nb_iterations_upper_bound.get_len ();
+         int i;
+
+         streamer_write_uhwi (ob, loop->nb_iterations_upper_bound.get_precision ());
+         streamer_write_uhwi (ob, len);
+         for (i = 0; i < len; i++)
+           streamer_write_hwi (ob, loop->nb_iterations_upper_bound.elt (i));
        }
       streamer_write_hwi (ob, loop->any_estimate);
       if (loop->any_estimate)
        {
-         streamer_write_uhwi (ob, loop->nb_iterations_estimate.low);
-         streamer_write_hwi (ob, loop->nb_iterations_estimate.high);
+         int len = loop->nb_iterations_estimate.get_len ();
+         int i;
+
+         streamer_write_uhwi (ob, loop->nb_iterations_estimate.get_precision ());
+         streamer_write_uhwi (ob, len);
+         for (i = 0; i < len; i++)
+           streamer_write_hwi (ob, loop->nb_iterations_estimate.elt (i));
        }
     }
 
@@ -1755,7 +1767,7 @@ output_function (struct cgraph_node *node)
   basic_block bb;
   struct output_block *ob;
 
-  function = node->symbol.decl;
+  function = node->decl;
   fn = DECL_STRUCT_FUNCTION (function);
   ob = create_output_block (LTO_section_function_body);
 
@@ -1772,50 +1784,83 @@ output_function (struct cgraph_node *node)
 
   streamer_write_record_start (ob, LTO_function);
 
-  output_struct_function_base (ob, fn);
-
-  /* Output all the SSA names used in the function.  */
-  output_ssa_names (ob, fn);
-
-  /* Output any exception handling regions.  */
-  output_eh_regions (ob, fn);
+  /* Output decls for parameters and args.  */
+  stream_write_tree (ob, DECL_RESULT (function), true);
+  streamer_write_chain (ob, DECL_ARGUMENTS (function), true);
 
   /* Output DECL_INITIAL for the function, which contains the tree of
      lexical scopes.  */
   stream_write_tree (ob, DECL_INITIAL (function), true);
 
-  /* We will renumber the statements.  The code that does this uses
-     the same ordering that we use for serializing them so we can use
-     the same code on the other end and not have to write out the
-     statement numbers.  We do not assign UIDs to PHIs here because
-     virtual PHIs get re-computed on-the-fly which would make numbers
-     inconsistent.  */
-  set_gimple_stmt_max_uid (cfun, 0);
-  FOR_ALL_BB (bb)
-    {
-      gimple_stmt_iterator gsi;
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+  /* We also stream abstract functions where we stream only stuff needed for
+     debug info.  */
+  if (gimple_has_body_p (function))
+    {
+      streamer_write_uhwi (ob, 1);
+      output_struct_function_base (ob, fn);
+
+      /* Output all the SSA names used in the function.  */
+      output_ssa_names (ob, fn);
+
+      /* Output any exception handling regions.  */
+      output_eh_regions (ob, fn);
+
+
+      /* We will renumber the statements.  The code that does this uses
+        the same ordering that we use for serializing them so we can use
+        the same code on the other end and not have to write out the
+        statement numbers.  We do not assign UIDs to PHIs here because
+        virtual PHIs get re-computed on-the-fly which would make numbers
+        inconsistent.  */
+      set_gimple_stmt_max_uid (cfun, 0);
+      FOR_ALL_BB (bb)
        {
-         gimple stmt = gsi_stmt (gsi);
-         gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+         gimple_stmt_iterator gsi;
+         for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             gimple stmt = gsi_stmt (gsi);
+
+             /* Virtual PHIs are not going to be streamed.  */
+             if (!virtual_operand_p (gimple_phi_result (stmt)))
+               gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+           }
+         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             gimple stmt = gsi_stmt (gsi);
+             gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+           }
+       }
+      /* To avoid keeping duplicate gimple IDs in the statements, renumber
+        virtual phis now.  */
+      FOR_ALL_BB (bb)
+       {
+         gimple_stmt_iterator gsi;
+         for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             gimple stmt = gsi_stmt (gsi);
+             if (virtual_operand_p (gimple_phi_result (stmt)))
+               gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+           }
        }
-    }
 
-  /* Output the code for the function.  */
-  FOR_ALL_BB_FN (bb, fn)
-    output_bb (ob, bb, fn);
+      /* Output the code for the function.  */
+      FOR_ALL_BB_FN (bb, fn)
+       output_bb (ob, bb, fn);
 
-  /* The terminator for this function.  */
-  streamer_write_record_start (ob, LTO_null);
+      /* The terminator for this function.  */
+      streamer_write_record_start (ob, LTO_null);
+
+      output_cfg (ob, fn);
 
-  output_cfg (ob, fn);
+      pop_cfun ();
+   }
+  else
+    streamer_write_uhwi (ob, 0);
 
   /* Create a section to hold the pickled output of this function.   */
   produce_asm (ob, function);
 
   destroy_output_block (ob);
-
-  pop_cfun ();
 }
 
 
@@ -1881,8 +1926,8 @@ lto_output_toplevel_asms (void)
 static void
 copy_function (struct cgraph_node *node)
 {
-  tree function = node->symbol.decl;
-  struct lto_file_decl_data *file_data = node->symbol.lto_file_data;
+  tree function = node->decl;
+  struct lto_file_decl_data *file_data = node->lto_file_data;
   struct lto_output_stream *output_stream = XCNEW (struct lto_output_stream);
   const char *data;
   size_t len;
@@ -1909,7 +1954,7 @@ copy_function (struct cgraph_node *node)
 
   /* Copy decls. */
   in_state =
-    lto_get_function_in_decl_state (node->symbol.lto_file_data, function);
+    lto_get_function_in_decl_state (node->lto_file_data, function);
   gcc_assert (in_state);
 
   for (i = 0; i < LTO_N_DECL_STREAMS; i++)
@@ -1936,7 +1981,7 @@ copy_function (struct cgraph_node *node)
 
 /* Main entry point from the pass manager.  */
 
-static void
+void
 lto_output (void)
 {
   struct lto_out_decl_state *decl_state;
@@ -1953,26 +1998,25 @@ lto_output (void)
   /* Process only the functions with bodies.  */
   for (i = 0; i < n_nodes; i++)
     {
-      symtab_node snode = lto_symtab_encoder_deref (encoder, i);
+      symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
       cgraph_node *node = dyn_cast <cgraph_node> (snode);
       if (node
          && lto_symtab_encoder_encode_body_p (encoder, node)
-         && !node->symbol.alias
-         && !node->thunk.thunk_p)
+         && !node->alias)
        {
 #ifdef ENABLE_CHECKING
-         gcc_assert (!bitmap_bit_p (output, DECL_UID (node->symbol.decl)));
-         bitmap_set_bit (output, DECL_UID (node->symbol.decl));
+         gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl)));
+         bitmap_set_bit (output, DECL_UID (node->decl));
 #endif
          decl_state = lto_new_out_decl_state ();
          lto_push_out_decl_state (decl_state);
-         if (gimple_has_body_p (node->symbol.decl))
+         if (gimple_has_body_p (node->decl) || !flag_wpa)
            output_function (node);
          else
            copy_function (node);
          gcc_assert (lto_get_out_decl_state () == decl_state);
          lto_pop_out_decl_state ();
-         lto_record_function_out_decl_state (node->symbol.decl, decl_state);
+         lto_record_function_out_decl_state (node->decl, decl_state);
        }
     }
 
@@ -1987,36 +2031,6 @@ lto_output (void)
 #endif
 }
 
-struct ipa_opt_pass_d pass_ipa_lto_gimple_out =
-{
- {
-  IPA_PASS,
-  "lto_gimple_out",                    /* name */
-  OPTGROUP_NONE,                        /* optinfo_flags */
-  gate_lto_out,                                /* gate */
-  NULL,                                        /* execute */
-  NULL,                                        /* sub */
-  NULL,                                        /* next */
-  0,                                   /* static_pass_number */
-  TV_IPA_LTO_GIMPLE_OUT,                       /* tv_id */
-  0,                                   /* properties_required */
-  0,                                   /* properties_provided */
-  0,                                   /* properties_destroyed */
-  0,                                   /* todo_flags_start */
-  0                                     /* todo_flags_finish */
- },
- NULL,                                 /* generate_summary */
- lto_output,                                   /* write_summary */
- NULL,                                 /* read_summary */
- lto_output,                                   /* write_optimization_summary */
- NULL,                                 /* read_optimization_summary */
- NULL,                                 /* stmt_fixup */
- 0,                                    /* TODOs */
- NULL,                                 /* function_transform */
- NULL                                  /* variable_transform */
-};
-
-
 /* Write each node in encoded by ENCODER to OB, as well as those reachable
    from it and required for correct representation of its semantics.
    Each node in ENCODER must be a global declaration or a type.  A node
@@ -2149,9 +2163,9 @@ write_symbol (struct streamer_tree_cache_d *cache,
   if (!TREE_PUBLIC (t)
       || is_builtin_fn (t)
       || DECL_ABSTRACT (t)
-      || TREE_CODE (t) == RESULT_DECL
       || (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)))
     return;
+  gcc_assert (TREE_CODE (t) != RESULT_DECL);
 
   gcc_assert (TREE_CODE (t) == VAR_DECL
              || TREE_CODE (t) == FUNCTION_DECL);
@@ -2187,10 +2201,10 @@ write_symbol (struct streamer_tree_cache_d *cache,
 
       /* When something is defined, it should have node attached.  */
       gcc_assert (alias || TREE_CODE (t) != VAR_DECL
-                 || varpool_get_node (t)->symbol.definition);
+                 || varpool_get_node (t)->definition);
       gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
                  || (cgraph_get_node (t)
-                     && cgraph_get_node (t)->symbol.definition));
+                     && cgraph_get_node (t)->definition));
     }
 
   /* Imitate what default_elf_asm_output_external do.
@@ -2204,7 +2218,7 @@ write_symbol (struct streamer_tree_cache_d *cache,
       && !targetm.binds_local_p (t))
     visibility = GCCPV_DEFAULT;
   else
-    switch (DECL_VISIBILITY(t))
+    switch (DECL_VISIBILITY (t))
       {
       case VISIBILITY_DEFAULT:
        visibility = GCCPV_DEFAULT;
@@ -2245,7 +2259,7 @@ write_symbol (struct streamer_tree_cache_d *cache,
 /* Return true if NODE should appear in the plugin symbol table.  */
 
 bool
-output_symbol_p (symtab_node node)
+output_symbol_p (symtab_node *node)
 {
   struct cgraph_node *cnode;
   if (!symtab_real_symbol_p (node))
@@ -2254,7 +2268,7 @@ output_symbol_p (symtab_node node)
      and devirtualization.  We do not want to see them in symbol table as
      references unless they are really used.  */
   cnode = dyn_cast <cgraph_node> (node);
-  if (cnode && DECL_EXTERNAL (cnode->symbol.decl)
+  if (cnode && (!node->definition || DECL_EXTERNAL (cnode->decl))
       && cnode->callers)
     return true;
 
@@ -2262,18 +2276,18 @@ output_symbol_p (symtab_node node)
     part of the compilation unit until they are used by folding.  Some symbols,
     like references to external construction vtables can not be referred to at all.
     We decide this at can_refer_decl_in_current_unit_p.  */
- if (DECL_EXTERNAL (node->symbol.decl))
+ if (!node->definition || DECL_EXTERNAL (node->decl))
     {
       int i;
       struct ipa_ref *ref;
-      for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
+      for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list,
                                                  i, ref); i++)
        {
          if (ref->use == IPA_REF_ALIAS)
            continue;
           if (is_a <cgraph_node> (ref->referring))
            return true;
-         if (!DECL_EXTERNAL (ref->referring->symbol.decl))
+         if (!DECL_EXTERNAL (ref->referring->decl))
            return true;
        }
       return false;
@@ -2307,20 +2321,20 @@ produce_symtab (struct output_block *ob)
   for (lsei = lsei_start (encoder);
        !lsei_end_p (lsei); lsei_next (&lsei))
     {
-      symtab_node node = lsei_node (lsei);
+      symtab_node *node = lsei_node (lsei);
 
-      if (!output_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl))
+      if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl))
        continue;
-      write_symbol (cache, &stream, node->symbol.decl, seen, false);
+      write_symbol (cache, &stream, node->decl, seen, false);
     }
   for (lsei = lsei_start (encoder);
        !lsei_end_p (lsei); lsei_next (&lsei))
     {
-      symtab_node node = lsei_node (lsei);
+      symtab_node *node = lsei_node (lsei);
 
-      if (!output_symbol_p (node) || !DECL_EXTERNAL (node->symbol.decl))
+      if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl))
        continue;
-      write_symbol (cache, &stream, node->symbol.decl, seen, false);
+      write_symbol (cache, &stream, node->decl, seen, false);
     }
 
   lto_write_stream (&stream);
@@ -2336,7 +2350,7 @@ produce_symtab (struct output_block *ob)
    this file to be written in to a section that can then be read in to
    recover these on other side.  */
 
-static void
+void
 produce_asm_for_decls (void)
 {
   struct lto_out_decl_state *out_state;
@@ -2414,7 +2428,7 @@ produce_asm_for_decls (void)
       lto_output_decl_state_refs (ob, decl_state_stream, fn_out_state);
     }
   lto_write_stream (decl_state_stream);
-  free(decl_state_stream);
+  free (decl_state_stream);
 
   lto_write_stream (ob->main_stream);
   lto_write_stream (ob->string_stream);
@@ -2440,33 +2454,3 @@ produce_asm_for_decls (void)
   lto_function_decl_states.release ();
   destroy_output_block (ob);
 }
-
-
-struct ipa_opt_pass_d pass_ipa_lto_finish_out =
-{
- {
-  IPA_PASS,
-  "lto_decls_out",                     /* name */
-  OPTGROUP_NONE,                        /* optinfo_flags */
-  gate_lto_out,                                /* gate */
-  NULL,                                        /* execute */
-  NULL,                                        /* sub */
-  NULL,                                        /* next */
-  0,                                   /* static_pass_number */
-  TV_IPA_LTO_DECL_OUT,                 /* tv_id */
-  0,                                   /* properties_required */
-  0,                                   /* properties_provided */
-  0,                                   /* properties_destroyed */
-  0,                                   /* todo_flags_start */
-  0                                     /* todo_flags_finish */
- },
- NULL,                                 /* generate_summary */
- produce_asm_for_decls,                        /* write_summary */
- NULL,                                 /* read_summary */
- produce_asm_for_decls,                        /* write_optimization_summary */
- NULL,                                 /* read_optimization_summary */
- NULL,                                 /* stmt_fixup */
- 0,                                    /* TODOs */
- NULL,                                 /* function_transform */
- NULL                                  /* variable_transform */
-};