diff options
author | Martin Jambor <mjambor@suse.cz> | 2010-04-28 16:05:54 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2010-04-28 16:05:54 +0200 |
commit | e33c6cd6af8a30a4f0ec49c83f1ac32e44a07eac (patch) | |
tree | c1439fe1fd5f33266aa3c67ebd246e03bffb1684 /gcc/lto-cgraph.c | |
parent | 18abb35edfc9f88c783813982e568978c2cb51cc (diff) | |
download | gcc-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.c | 80 |
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); |