#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);
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);
/* 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));
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;
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,
int count;
int bit;
struct bitpack_d bp;
+ struct cgraph_edge *e;
count = lto_input_uleb128 (ib_main);
if (count)
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. */
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);
}