aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-cgraph.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2010-04-28 16:05:54 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2010-04-28 16:05:54 +0200
commite33c6cd6af8a30a4f0ec49c83f1ac32e44a07eac (patch)
treec1439fe1fd5f33266aa3c67ebd246e03bffb1684 /gcc/lto-cgraph.c
parent18abb35edfc9f88c783813982e568978c2cb51cc (diff)
downloadgcc-e33c6cd6af8a30a4f0ec49c83f1ac32e44a07eac.zip
gcc-e33c6cd6af8a30a4f0ec49c83f1ac32e44a07eac.tar.gz
gcc-e33c6cd6af8a30a4f0ec49c83f1ac32e44a07eac.tar.bz2
cgraph.h (struct cgraph_node): New field indirect_calls.
2010-04-28 Martin Jambor <mjambor@suse.cz> * cgraph.h (struct cgraph_node): New field indirect_calls. (struct cgraph_indirect_call_info): New type. (struct cgraph_edge): Removed field indirect_call. New fields indirect_info, indirect_inlining_edge and indirect_unknown_callee. (cgraph_create_indirect_edge): Declare. (cgraph_make_edge_direct): Likewise. (enum LTO_cgraph_tags): New item LTO_cgraph_indirect_edge. * ipa-prop.h (struct ipa_param_call_note): Removed. (struct ipa_node_params): Removed field param_calls. (ipa_create_all_structures_for_iinln): Declare. * cgraph.c: Described indirect edges and uids in initial comment. (cgraph_add_edge_to_call_site_hash): New function. (cgraph_edge): Search also among the indirect edges, use cgraph_add_edge_to_call_site_hash to add edges to the call site hash. (cgraph_set_call_stmt): Possibly turn an indirect edge into a direct one, use cgraph_add_edge_to_call_site_hash to add edges to the call site hash. (initialize_inline_failed): Assign a reason to indirect edges. (cgraph_create_edge_1): New function. (cgraph_create_edge): Moved some functionality to cgraph_create_edge_1. (cgraph_create_indirect_edge): New function. (cgraph_edge_remove_callee): Add an assert checking for non-indirectness. (cgraph_edge_remove_caller): Special-case indirect edges. (cgraph_remove_edge): Likewise. (cgraph_set_edge_callee): New function. (cgraph_redirect_edge_callee): Use cgraph_set_edge_callee. (cgraph_make_edge_direct): New function. (cgraph_update_edges_for_call_stmt_node): Do nothing only when also the declaration of the call statement matches. (cgraph_node_remove_callees): Special-case indirect edges. (cgraph_clone_edge): Likewise. (cgraph_clone_node): Clone also the indirect edges. (dump_cgraph_node): Dump indirect_inlining_edge flag instead of indirect_call, dump count of indirect_calls edges. * ipa-prop.c (iinlining_processed_edges): New variable. (ipa_note_param_call): Create indirect edges instead of creating notes. New parameter node. (ipa_analyze_call_uses): New parameter node, pass it on to ipa_note_param_call. (ipa_analyze_stmt_uses): Likewise. (ipa_analyze_params_uses): Pass node to ipa_analyze_stmt_uses. (print_edge_addition_message): Work on edges rather than on notes. (update_call_notes_after_inlining): Likewise, renamed to update_indirect_edges_after_inlining. (ipa_create_all_structures_for_iinln): New function. (ipa_free_node_params_substructures): Do not free notes. (ipa_edge_duplication_hook): Propagate bits within iinlining_processed_edges bitmap. (ipa_node_duplication_hook): Do not duplicate notes. (free_all_ipa_structures_after_ipa_cp): Renamed to ipa_free_all_structures_after_ipa_cp. (free_all_ipa_structures_after_iinln): Renamed to ipa_free_all_structures_after_iinln.g (ipa_write_param_call_note): Removed. (ipa_read_param_call_note): Removed. (ipa_write_indirect_edge_info): New function. (ipa_read_indirect_edge_info): Likewise. (ipa_write_node_info): Do not stream notes, do stream information in indirect edges. (ipa_read_node_info): Likewise. (lto_ipa_fixup_call_notes): Removed. * ipa-cp.c (pass_ipa_cp): Set stmt_fixup to NULL. * ipa-inline.c (pass_ipa_inline): Likewise. * cgraphunit.c (verify_cgraph_node): Check also indirect edges. * cif-code.def (INDIRECT_UNKNOWN_CALL): New reason. * tree-inline.c (copy_bb): Removed an unnecessary double check for is_gimple_call. * tree-inline.c (get_indirect_callee_fndecl): Do not consider indirect edges. * lto-cgraph.c (output_outgoing_cgraph_edges): New function. (output_cgraph): Stream also indirect edges. (lto_output_edge): Added capability to stream indirect edges. (input_edge): Likewise. (input_cgraph_1): Likewise. * testsuite/gcc.dg/lto/20091209-1_0.c: New testcase. From-SVN: r158827
Diffstat (limited to 'gcc/lto-cgraph.c')
-rw-r--r--gcc/lto-cgraph.c80
1 files changed, 55 insertions, 25 deletions
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 6f22968..b805768 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -139,15 +139,21 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
intptr_t ref;
struct bitpack_d *bp;
- lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge);
+ if (edge->indirect_unknown_callee)
+ lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge);
+ else
+ lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge);
ref = lto_cgraph_encoder_lookup (encoder, edge->caller);
gcc_assert (ref != LCC_NOT_FOUND);
lto_output_sleb128_stream (ob->main_stream, ref);
- ref = lto_cgraph_encoder_lookup (encoder, edge->callee);
- gcc_assert (ref != LCC_NOT_FOUND);
- lto_output_sleb128_stream (ob->main_stream, ref);
+ if (!edge->indirect_unknown_callee)
+ {
+ ref = lto_cgraph_encoder_lookup (encoder, edge->callee);
+ gcc_assert (ref != LCC_NOT_FOUND);
+ lto_output_sleb128_stream (ob->main_stream, ref);
+ }
lto_output_sleb128_stream (ob->main_stream, edge->count);
@@ -157,7 +163,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
bp_pack_value (bp, edge->inline_failed, HOST_BITS_PER_INT);
bp_pack_value (bp, edge->frequency, HOST_BITS_PER_INT);
bp_pack_value (bp, edge->loop_nest, 30);
- bp_pack_value (bp, edge->indirect_call, 1);
+ bp_pack_value (bp, edge->indirect_inlining_edge, 1);
bp_pack_value (bp, edge->call_stmt_cannot_inline_p, 1);
bp_pack_value (bp, edge->can_throw_external, 1);
lto_output_bitpack (ob->main_stream, bp);
@@ -400,6 +406,25 @@ add_node_to (lto_cgraph_encoder_t encoder, struct cgraph_node *node)
lto_cgraph_encoder_encode (encoder, node);
}
+/* Output all callees or indirect outgoing edges. EDGE must be the first such
+ edge. */
+
+static void
+output_outgoing_cgraph_edges (struct cgraph_edge *edge,
+ struct lto_simple_output_block *ob,
+ lto_cgraph_encoder_t encoder)
+{
+ if (!edge)
+ return;
+
+ /* Output edges in backward direction, so the reconstructed callgraph match
+ and it is easy to associate call sites in the IPA pass summaries. */
+ while (edge->next_callee)
+ edge = edge->next_callee;
+ for (; edge; edge = edge->prev_callee)
+ lto_output_edge (ob, edge, encoder);
+}
+
/* Output the part of the cgraph in SET. */
void
@@ -468,16 +493,8 @@ output_cgraph (cgraph_node_set set)
for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
{
node = csi_node (csi);
- if (node->callees)
- {
- /* Output edges in backward direction, so the reconstructed callgraph
- match and it is easy to associate call sites in the IPA pass summaries. */
- edge = node->callees;
- while (edge->next_callee)
- edge = edge->next_callee;
- for (; edge; edge = edge->prev_callee)
- lto_output_edge (ob, edge, encoder);
- }
+ output_outgoing_cgraph_edges (node->callees, ob, encoder);
+ output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder);
}
lto_output_uleb128_stream (ob->main_stream, 0);
@@ -497,7 +514,6 @@ output_cgraph (cgraph_node_set set)
lto_destroy_simple_output_block (ob);
}
-
/* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
STACK_SIZE, SELF_TIME and SELF_SIZE. This is called either to initialize
NODE or to replace the values in it, for instance because the first
@@ -668,11 +684,14 @@ input_node (struct lto_file_decl_data *file_data,
}
-/* Read an edge from IB. NODES points to a vector of previously read
- nodes for decoding caller and callee of the edge to be read. */
+/* Read an edge from IB. NODES points to a vector of previously read nodes for
+ decoding caller and callee of the edge to be read. If INDIRECT is true, the
+ edge being read is indirect (in the sense that it has
+ indirect_unknown_callee set). */
static void
-input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
+input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes,
+ bool indirect)
{
struct cgraph_node *caller, *callee;
struct cgraph_edge *edge;
@@ -688,9 +707,14 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
if (caller == NULL || caller->decl == NULL_TREE)
internal_error ("bytecode stream: no caller found while reading edge");
- callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
- if (callee == NULL || callee->decl == NULL_TREE)
- internal_error ("bytecode stream: no callee found while reading edge");
+ if (!indirect)
+ {
+ callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
+ if (callee == NULL || callee->decl == NULL_TREE)
+ internal_error ("bytecode stream: no callee found while reading edge");
+ }
+ else
+ callee = NULL;
count = (gcov_type) lto_input_sleb128 (ib);
@@ -708,10 +732,14 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
|| caller_resolution == LDPR_PREEMPTED_IR)
return;
- edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
+ if (indirect)
+ edge = cgraph_create_indirect_edge (caller, NULL, count, freq, nest);
+ else
+ edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
+
+ edge->indirect_inlining_edge = bp_unpack_value (bp, 1);
edge->lto_stmt_uid = stmt_id;
edge->inline_failed = inline_failed;
- edge->indirect_call = bp_unpack_value (bp, 1);
edge->call_stmt_cannot_inline_p = bp_unpack_value (bp, 1);
edge->can_throw_external = bp_unpack_value (bp, 1);
bitpack_delete (bp);
@@ -734,7 +762,9 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
while (tag)
{
if (tag == LTO_cgraph_edge)
- input_edge (ib, nodes);
+ input_edge (ib, nodes, false);
+ else if (tag == LTO_cgraph_indirect_edge)
+ input_edge (ib, nodes, true);
else
{
node = input_node (file_data, ib, tag);