OSDN Git Service

PR testsuite/46230
[pf3gnuchains/gcc-fork.git] / gcc / lto-cgraph.c
index 76597a0..6ca7abc 100644 (file)
@@ -46,7 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gcov-io.h"
 
 static void output_varpool (cgraph_node_set, varpool_node_set);
-static void output_cgraph_opt_summary (void);
+static void output_cgraph_opt_summary (cgraph_node_set set);
 static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes);
 
 
@@ -861,7 +861,7 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset)
   static bool asm_nodes_output = false;
 
   if (flag_wpa)
-    output_cgraph_opt_summary ();
+    output_cgraph_opt_summary (set);
 
   ob = lto_create_simple_output_block (LTO_section_cgraph);
 
@@ -1596,26 +1596,53 @@ input_cgraph (void)
 /* True when we need optimization summary for NODE.  */
 
 static int
-output_cgraph_opt_summary_p (struct cgraph_node *node)
+output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set)
 {
-  if (!node->clone_of)
-    return false;
-  return (node->clone.tree_map
-          || node->clone.args_to_skip
-          || node->clone.combined_args_to_skip);
+  struct cgraph_edge *e;
+
+  if (cgraph_node_in_set_p (node, set))
+    {
+      for (e = node->callees; e; e = e->next_callee)
+       if (e->indirect_info
+           && e->indirect_info->thunk_delta != 0)
+         return true;
+
+      for (e = node->indirect_calls; e; e = e->next_callee)
+       if (e->indirect_info->thunk_delta != 0)
+         return true;
+    }
+
+  return (node->clone_of
+         && (node->clone.tree_map
+             || node->clone.args_to_skip
+             || node->clone.combined_args_to_skip));
+}
+
+/* Output optimization summary for EDGE to OB.  */
+static void
+output_edge_opt_summary (struct output_block *ob,
+                        struct cgraph_edge *edge)
+{
+  if (edge->indirect_info)
+    lto_output_sleb128_stream (ob->main_stream,
+                              edge->indirect_info->thunk_delta);
+  else
+    lto_output_sleb128_stream (ob->main_stream, 0);
 }
 
 /* Output optimization summary for NODE to OB.  */
 
 static void
 output_node_opt_summary (struct output_block *ob,
-                        struct cgraph_node *node)
+                        struct cgraph_node *node,
+                        cgraph_node_set set)
 {
   unsigned int index;
   bitmap_iterator bi;
   struct ipa_replace_map *map;
   struct bitpack_d bp;
   int i;
+  struct cgraph_edge *e;
 
   lto_output_uleb128_stream (ob->main_stream,
                             bitmap_count_bits (node->clone.args_to_skip));
@@ -1646,13 +1673,21 @@ output_node_opt_summary (struct output_block *ob,
       bp_pack_value (&bp, map->ref_p, 1);
       lto_output_bitpack (&bp);
     }
+
+  if (cgraph_node_in_set_p (node, set))
+    {
+      for (e = node->callees; e; e = e->next_callee)
+       output_edge_opt_summary (ob, e);
+      for (e = node->indirect_calls; e; e = e->next_callee)
+       output_edge_opt_summary (ob, e);
+    }
 }
 
 /* Output optimization summaries stored in callgraph.
    At the moment it is the clone info structure.  */
 
 static void
-output_cgraph_opt_summary (void)
+output_cgraph_opt_summary (cgraph_node_set set)
 {
   struct cgraph_node *node;
   int i, n_nodes;
@@ -1664,23 +1699,40 @@ output_cgraph_opt_summary (void)
   encoder = ob->decl_state->cgraph_node_encoder;
   n_nodes = lto_cgraph_encoder_size (encoder);
   for (i = 0; i < n_nodes; i++)
-    if (output_cgraph_opt_summary_p (lto_cgraph_encoder_deref (encoder, i)))
+    if (output_cgraph_opt_summary_p (lto_cgraph_encoder_deref (encoder, i),
+                                    set))
       count++;
   lto_output_uleb128_stream (ob->main_stream, count);
   for (i = 0; i < n_nodes; i++)
     {
       node = lto_cgraph_encoder_deref (encoder, i);
-      if (output_cgraph_opt_summary_p (node))
+      if (output_cgraph_opt_summary_p (node, set))
        {
          lto_output_uleb128_stream (ob->main_stream, i);
-         output_node_opt_summary (ob, node);
+         output_node_opt_summary (ob, node, set);
        }
     }
   produce_asm (ob, NULL);
   destroy_output_block (ob);
 }
 
-/* Input optimiation summary of NODE.  */
+/* Input optimisation summary of EDGE.  */
+
+static void
+input_edge_opt_summary (struct cgraph_edge *edge,
+                       struct lto_input_block *ib_main)
+{
+  HOST_WIDE_INT thunk_delta;
+  thunk_delta = lto_input_sleb128 (ib_main);
+  if (thunk_delta != 0)
+    {
+      gcc_assert (!edge->indirect_info);
+      edge->indirect_info = cgraph_allocate_init_indirect_info ();
+      edge->indirect_info->thunk_delta = thunk_delta;
+    }
+}
+
+/* Input optimisation summary of NODE.  */
 
 static void
 input_node_opt_summary (struct cgraph_node *node,
@@ -1691,6 +1743,7 @@ input_node_opt_summary (struct cgraph_node *node,
   int count;
   int bit;
   struct bitpack_d bp;
+  struct cgraph_edge *e;
 
   count = lto_input_uleb128 (ib_main);
   if (count)
@@ -1726,6 +1779,10 @@ input_node_opt_summary (struct cgraph_node *node,
       map->replace_p = bp_unpack_value (&bp, 1);
       map->ref_p = bp_unpack_value (&bp, 1);
     }
+  for (e = node->callees; e; e = e->next_callee)
+    input_edge_opt_summary (e, ib_main);
+  for (e = node->indirect_calls; e; e = e->next_callee)
+    input_edge_opt_summary (e, ib_main);
 }
 
 /* Read section in file FILE_DATA of length LEN with data DATA.  */
@@ -1759,7 +1816,7 @@ input_cgraph_opt_section (struct lto_file_decl_data *file_data,
       input_node_opt_summary (VEC_index (cgraph_node_ptr, nodes, ref),
                              &ib_main, data_in);
     }
-  lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
+  lto_free_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, data,
                         len);
   lto_data_in_delete (data_in);
 }