lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into boundaries.
authorJan Hubicka <jh@suse.cz>
Sat, 3 Aug 2013 19:54:18 +0000 (21:54 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 3 Aug 2013 19:54:18 +0000 (19:54 +0000)
* lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into
boundaries.
* lto-streamer-out.c (tree_is_indexable): Results decls and
parm decls are not indexable.
(DFS_write_tree_body): Do not follow args and results.
(hash_tree): Likewise.
(output_functions): Rearrange so struct function is needed
only when real body is output; be able to also ouptut abstract
functions; output DECL_ARGUMENTS and DECL_RESULT.
(lto_output): When not in WPA, ale store abstract functions.
(write_symbol): Do not care about RESULT_DECL.
(output_symbol_p): Handle correctly sbtract decls.
* lto-streamer-in.c (input_function): Rearrange so struct
function can be NULL at entry; allow streaming of
functions w/o body; store DECL_ARGUMENTS and DECL_RESULT.
* ipa.c (symtab_remove_unreachable_nodes): Silence confused
sanity check during LTO.
* tree-streamer-out.c (write_ts_decl_non_common_tree_pointers): Skip
RESULT_DECl and DECL_ARGUMENTS.
* tree-streamer-in.c (lto_input_ts_decl_non_common_tree_pointers):
Likewise.

* lto.c (lto_materialize_function): Do not push struct function.
* lto-partition.c (get_symbol_class): Handle abstracts correctly.
(may_need_named_section_p): Even abstract origins may need
named section.

From-SVN: r201468

gcc/ChangeLog
gcc/ipa.c
gcc/lto-cgraph.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto/ChangeLog
gcc/lto/lto-partition.c
gcc/lto/lto.c
gcc/tree-streamer-in.c
gcc/tree-streamer-out.c

index c1727829e3ee348316949d434d6380467d031884..dbac14039bef0224115fb7e7b3f1091e6393c746 100644 (file)
@@ -1,3 +1,27 @@
+2013-08-02  Jan Hubicka  <jh@suse.cz>
+
+       * lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into
+       boundaries.
+       * lto-streamer-out.c (tree_is_indexable): Results decls and
+       parm decls are not indexable.
+       (DFS_write_tree_body): Do not follow args and results.
+       (hash_tree): Likewise.
+       (output_functions): Rearrange so struct function is needed
+       only when real body is output; be able to also ouptut abstract
+       functions; output DECL_ARGUMENTS and DECL_RESULT.
+       (lto_output): When not in WPA, ale store abstract functions.
+       (write_symbol): Do not care about RESULT_DECL.
+       (output_symbol_p): Handle correctly sbtract decls.
+       * lto-streamer-in.c (input_function): Rearrange so struct
+       function can be NULL at entry; allow streaming of
+       functions w/o body; store DECL_ARGUMENTS and DECL_RESULT.
+       * ipa.c (symtab_remove_unreachable_nodes): Silence confused
+       sanity check during LTO.
+       * tree-streamer-out.c (write_ts_decl_non_common_tree_pointers): Skip
+       RESULT_DECl and DECL_ARGUMENTS.
+       * tree-streamer-in.c (lto_input_ts_decl_non_common_tree_pointers):
+       Likewise.
+
 2013-08-03  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * pretty-print.h (pp_underscore): New.
index f42de4dac693942e379a5f7a8391954956358cac..2f60a98cb874f194da0b831ac9f7244a34558508 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -371,7 +371,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
          if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
            cgraph_release_function_body (node);
          else if (!node->clone_of)
-           gcc_assert (DECL_RESULT (node->symbol.decl));
+           gcc_assert (in_lto_p || DECL_RESULT (node->symbol.decl));
          if (node->symbol.definition)
            {
              if (file)
@@ -382,7 +382,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
        }
       else
        gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node)
-                   || DECL_RESULT (node->symbol.decl));
+                   || in_lto_p || DECL_RESULT (node->symbol.decl));
     }
 
   /* Inline clones might be kept around so their materializing allows further
index 3f9c56de7334268e2291bdaeb3751b051e24a213..c3c393f6ec91c39d20cc4232a00cb6ed1190a62c 100644 (file)
@@ -749,6 +749,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
       add_node_to (encoder, node, true);
       lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
       add_references (encoder, &node->symbol.ref_list);
+      /* For proper debug info, we need to ship the origins, too.  */
+      if (DECL_ABSTRACT_ORIGIN (node->symbol.decl))
+       {
+         struct cgraph_node *origin_node
+         = cgraph_get_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
+         add_node_to (encoder, origin_node, true);
+       }
     }
   for (lsei = lsei_start_variable_in_partition (in_encoder);
        !lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
@@ -758,6 +765,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
       lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
       lto_set_symtab_encoder_encode_initializer (encoder, vnode);
       add_references (encoder, &vnode->symbol.ref_list);
+      /* For proper debug info, we need to ship the origins, too.  */
+      if (DECL_ABSTRACT_ORIGIN (vnode->symbol.decl))
+       {
+         struct varpool_node *origin_node
+         = varpool_get_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
+         lto_set_symtab_encoder_in_partition (encoder, (symtab_node)origin_node);
+       }
     }
   /* Pickle in also the initializer of all referenced readonly variables
      to help folding.  Constant pool variables are not shared, so we must
index fe7ab7c5067d58fa6812814b47287a77b7657156..70a87d1738ba82b04c8fef292a5507ce65918c7c 100644 (file)
@@ -851,7 +851,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
 
 static void
 input_function (tree fn_decl, struct data_in *data_in,
-               struct lto_input_block *ib)
+               struct lto_input_block *ib, struct lto_input_block *ib_cfg)
 {
   struct function *fn;
   enum LTO_tags tag;
@@ -859,13 +859,30 @@ input_function (tree fn_decl, struct data_in *data_in,
   basic_block bb;
   struct cgraph_node *node;
 
-  fn = DECL_STRUCT_FUNCTION (fn_decl);
   tag = streamer_read_record_start (ib);
+  lto_tag_check (tag, LTO_function);
+
+  /* Read decls for parameters and args.  */
+  DECL_RESULT (fn_decl) = stream_read_tree (ib, data_in);
+  DECL_ARGUMENTS (fn_decl) = streamer_read_chain (ib, data_in);
+
+  /* Read the tree of lexical scopes for the function.  */
+  DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
+
+  if (!streamer_read_uhwi (ib))
+    return;
+
+  push_struct_function (fn_decl);
+  fn = DECL_STRUCT_FUNCTION (fn_decl);
+  init_tree_ssa (fn);
+  /* We input IL in SSA form.  */
+  cfun->gimple_df->in_ssa_p = true;
 
   gimple_register_cfg_hooks ();
-  lto_tag_check (tag, LTO_function);
 
+  node = cgraph_get_create_node (fn_decl);
   input_struct_function_base (fn, data_in, ib);
+  input_cfg (ib_cfg, fn, node->count_materialization_scale);
 
   /* Read all the SSA names.  */
   input_ssa_names (ib, data_in, fn);
@@ -873,11 +890,8 @@ input_function (tree fn_decl, struct data_in *data_in,
   /* Read the exception handling regions in the function.  */
   input_eh_regions (ib, data_in, fn);
 
-  /* Read the tree of lexical scopes for the function.  */
-  DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
   gcc_assert (DECL_INITIAL (fn_decl));
   DECL_SAVED_TREE (fn_decl) = NULL_TREE;
-  node = cgraph_get_create_node (fn_decl);
 
   /* Read all the basic blocks.  */
   tag = streamer_read_record_start (ib);
@@ -987,28 +1001,21 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
 
   if (section_type == LTO_section_function_body)
     {
-      struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
       struct lto_in_decl_state *decl_state;
       struct cgraph_node *node = cgraph_get_node (fn_decl);
       unsigned from;
 
       gcc_checking_assert (node);
-      push_cfun (fn);
-      init_tree_ssa (fn);
-
-      /* We input IL in SSA form.  */
-      cfun->gimple_df->in_ssa_p = true;
 
       /* Use the function's decl state. */
       decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
       gcc_assert (decl_state);
       file_data->current_decl_state = decl_state;
 
-      input_cfg (&ib_cfg, fn, node->count_materialization_scale);
 
       /* Set up the struct function.  */
       from = data_in->reader_cache->nodes.length ();
-      input_function (fn_decl, data_in, &ib_main);
+      input_function (fn_decl, data_in, &ib_main, &ib_cfg);
       /* And fixup types we streamed locally.  */
        {
          struct streamer_tree_cache_d *cache = data_in->reader_cache;
index a962e9c50032df189a2b7d378dbe2d31ddc03d01..ab7a89968612685f48756a633f5eaa465e74e901 100644 (file)
@@ -124,8 +124,8 @@ output_type_ref (struct output_block *ob, tree node)
 static bool
 tree_is_indexable (tree t)
 {
-  if (TREE_CODE (t) == PARM_DECL)
-    return true;
+  if (TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
+    return false;
   else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
           && !TREE_STATIC (t))
     return false;
@@ -506,13 +506,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));
     }
@@ -936,13 +930,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));
     }
@@ -1772,50 +1760,63 @@ 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_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             gimple stmt = gsi_stmt (gsi);
+             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 ();
 }
 
 
@@ -1966,7 +1967,7 @@ lto_output (void)
 #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->symbol.decl) || !flag_wpa)
            output_function (node);
          else
            copy_function (node);
@@ -2149,9 +2150,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);
@@ -2254,7 +2255,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->symbol.definition || DECL_EXTERNAL (cnode->symbol.decl))
       && cnode->callers)
     return true;
 
@@ -2262,7 +2263,7 @@ 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->symbol.definition || DECL_EXTERNAL (node->symbol.decl))
     {
       int i;
       struct ipa_ref *ref;
index 37e8afdfb0008064fdb32224de814546d0608ea6..33f3b321d8155df0c39ee852ac5a1057b95b16b7 100644 (file)
@@ -1,3 +1,10 @@
+2013-08-02  Jan Hubicka  <jh@suse.cz>
+
+       * lto.c (lto_materialize_function): Do not push struct function.
+       * lto-partition.c (get_symbol_class): Handle abstracts correctly.
+       (may_need_named_section_p): Even abstract origins may need
+       named section.
+
 2013-07-30  David Malcolm  <dmalcolm@redhat.com>
 
        * Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and
index 63e6ab969014839f6b6208eba784cd65467385b3..879218ce2fa9b7c967ce963cf4258ac46067913e 100644 (file)
@@ -56,6 +56,10 @@ get_symbol_class (symtab_node node)
   /* Inline clones are always duplicated.
      This include external delcarations.   */
   cgraph_node *cnode = dyn_cast <cgraph_node> (node);
+
+  if (DECL_ABSTRACT (node->symbol.decl))
+    return SYMBOL_EXTERNAL;
+
   if (cnode && cnode->global.inlined_to)
     return SYMBOL_DUPLICATE;
 
@@ -840,8 +844,6 @@ may_need_named_section_p (lto_symtab_encoder_t encoder, symtab_node node)
     return false;
   if (symtab_real_symbol_p (node))
     return false;
-  if (!cnode->global.inlined_to && !cnode->clones)
-    return false;
   return (!encoder
          || (lto_symtab_encoder_lookup (encoder, node) != LCC_NOT_FOUND
               && lto_symtab_encoder_encode_body_p (encoder,
index 32f8326147b0c18b0f45c32c1bc370e49e88da5e..42d67f1bd3ddeaef40b61bd3700cf28c1ca78191 100644 (file)
@@ -225,7 +225,6 @@ lto_materialize_function (struct cgraph_node *node)
 
          gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
 
-         push_struct_function (decl);
          announce_function (decl);
          lto_input_function_body (file_data, decl, data);
          if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
@@ -233,7 +232,6 @@ lto_materialize_function (struct cgraph_node *node)
          lto_stats.num_function_bodies++;
          lto_free_section_data (file_data, LTO_section_function_body, name,
                                 data, len);
-         pop_cfun ();
          ggc_collect ();
        }
     }
index 00f78a13df3a46c03ccf8418d442ef711391230a..9efd099104149537ae24e98d1ed09d529311e8fb 100644 (file)
@@ -678,12 +678,7 @@ static void
 lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
                                            struct data_in *data_in, tree expr)
 {
-  if (TREE_CODE (expr) == FUNCTION_DECL)
-    {
-      DECL_ARGUMENTS (expr) = streamer_read_chain (ib, data_in);
-      DECL_RESULT (expr) = stream_read_tree (ib, data_in);
-    }
-  else if (TREE_CODE (expr) == TYPE_DECL)
+  if (TREE_CODE (expr) == TYPE_DECL)
     DECL_ORIGINAL_TYPE (expr) = stream_read_tree (ib, data_in);
   DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
 }
index fa50ef5b7ad1df71319768630e0a854e47e935d9..692a46aae859daf39744cc5567bb20aaf3ef1b2e 100644 (file)
@@ -606,12 +606,7 @@ static void
 write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
                                        bool ref_p)
 {
-  if (TREE_CODE (expr) == FUNCTION_DECL)
-    {
-      streamer_write_chain (ob, DECL_ARGUMENTS (expr), ref_p);
-      stream_write_tree (ob, DECL_RESULT (expr), ref_p);
-    }
-  else if (TREE_CODE (expr) == TYPE_DECL)
+  if (TREE_CODE (expr) == TYPE_DECL)
     stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
   stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
 }