Commit 5f902d76 by Jan Hubicka Committed by Jan Hubicka

cgraphbuild.c (build_cgraph_edges, [...]): Build indrect edges too.


	* cgraphbuild.c (build_cgraph_edges, rebuild_cgraph_edges): Build
	indrect edges too.
	* cgraph.c (cgraph_create_indirect_edge): Take ecf_flags argument.
	(cgraph_clone_edge): Update.
	(cgraph_node_remove_callees): Remove indirect calls too.
	* cgraph.h (cgraph_indirect_call_info): Add ecf_flags.
	(cgraph_create_indirect_edge): Update prototype.
	* ipa-reference.c (has_proper_scope_for_analysis): Rename to
	is_proper_for_analysis.
	(add_new_function, visited_nodes, function_insertion_hook_holder,
	get_local_reference_vars_info, mark_address_taken, mark_address,
	mark_load, mark_store, check_asm_memory_clobber, check_call,
	scan_stmt_for_static_refs, scan_initializer_for_static_refs): Remove.
	(ipa_init): Do not initialize visited_nodes;
	function_insertion_hook_holder.
	(analyze_variable): Rewrite.
	(analyze_function): Rewrite.
	(copy_local_bitmap): Remove.
	(duplicate_node_dat): Do not duplicate local info.
	(generate_summary): Simplify to only walk cgraph.
	(write_node_summary_p, ipa_reference_write_summary,
	ipa_reference_read_summary): Remove.
	(propagate): Do not remove function insertion;
	generate summary.
	(pass_ipa_reference): NULLify summary handling fields.
	* lto-cgraph.c (lto_output_edge): Output ecf_flags.
	(input_edge): Input ecf_flags.
	* ipa-prop.c (ipa_note_parm_call): Expect edge to be around.
	(update_indirect_edges_after_inlining): Ignore edges with unknown
	param.

From-SVN: r159343
parent 87a0ebfd
2010-05-12 Jan Hubicka <jh@suse.cz>
* cgraphbuild.c (build_cgraph_edges, rebuild_cgraph_edges): Build
indrect edges too.
* cgraph.c (cgraph_create_indirect_edge): Take ecf_flags argument.
(cgraph_clone_edge): Update.
(cgraph_node_remove_callees): Remove indirect calls too.
* cgraph.h (cgraph_indirect_call_info): Add ecf_flags.
(cgraph_create_indirect_edge): Update prototype.
* ipa-reference.c (has_proper_scope_for_analysis): Rename to
is_proper_for_analysis.
(add_new_function, visited_nodes, function_insertion_hook_holder,
get_local_reference_vars_info, mark_address_taken, mark_address,
mark_load, mark_store, check_asm_memory_clobber, check_call,
scan_stmt_for_static_refs, scan_initializer_for_static_refs): Remove.
(ipa_init): Do not initialize visited_nodes;
function_insertion_hook_holder.
(analyze_variable): Rewrite.
(analyze_function): Rewrite.
(copy_local_bitmap): Remove.
(duplicate_node_dat): Do not duplicate local info.
(generate_summary): Simplify to only walk cgraph.
(write_node_summary_p, ipa_reference_write_summary,
ipa_reference_read_summary): Remove.
(propagate): Do not remove function insertion;
generate summary.
(pass_ipa_reference): NULLify summary handling fields.
* lto-cgraph.c (lto_output_edge): Output ecf_flags.
(input_edge): Input ecf_flags.
* ipa-prop.c (ipa_note_parm_call): Expect edge to be around.
(update_indirect_edges_after_inlining): Ignore edges with unknown
param.
2010-05-12 Sriraman Tallam <tmsriram@google.com>
* implicit-zee.c: New file.
......
......@@ -1036,6 +1036,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
struct cgraph_edge *
cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
int ecf_flags,
gcov_type count, int freq, int nest)
{
struct cgraph_edge *edge = cgraph_create_edge_1 (caller, NULL, call_stmt,
......@@ -1046,6 +1047,7 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
edge->indirect_info = GGC_NEW (struct cgraph_indirect_call_info);
edge->indirect_info->param_index = -1;
edge->indirect_info->ecf_flags = ecf_flags;
edge->next_callee = caller->indirect_calls;
if (caller->indirect_calls)
......@@ -1292,6 +1294,15 @@ cgraph_node_remove_callees (struct cgraph_node *node)
cgraph_edge_remove_callee (e);
cgraph_free_edge (e);
}
for (e = node->indirect_calls; e; e = f)
{
f = e->next_callee;
cgraph_call_edge_removal_hooks (e);
if (!e->indirect_unknown_callee)
cgraph_edge_remove_callee (e);
cgraph_free_edge (e);
}
node->indirect_calls = NULL;
node->callees = NULL;
if (node->call_site_hash)
{
......@@ -2009,7 +2020,9 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
}
else
{
new_edge = cgraph_create_indirect_edge (n, call_stmt, count, freq,
new_edge = cgraph_create_indirect_edge (n, call_stmt,
e->indirect_info->ecf_flags,
count, freq,
e->loop_nest + loop_nest);
new_edge->indirect_info->param_index = e->indirect_info->param_index;
}
......
......@@ -376,6 +376,8 @@ struct GTY(()) cgraph_indirect_call_info
{
/* Index of the parameter that is called. */
int param_index;
/* ECF flags determined from the caller. */
int ecf_flags;
};
struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
......@@ -519,7 +521,7 @@ void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *,
gimple, gcov_type, int, int);
struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple,
struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, int,
gcov_type, int, int);
struct cgraph_node * cgraph_get_node (tree);
struct cgraph_node *cgraph_node (tree);
......
......@@ -339,12 +339,21 @@ build_cgraph_edges (void)
gimple stmt = gsi_stmt (gsi);
tree decl;
if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
cgraph_create_edge (node, cgraph_node (decl), stmt,
bb->count,
compute_call_stmt_bb_frequency
(current_function_decl, bb),
bb->loop_depth);
if (is_gimple_call (stmt))
{
int freq = compute_call_stmt_bb_frequency (current_function_decl,
bb);
decl = gimple_call_fndecl (stmt);
if (decl)
cgraph_create_edge (node, cgraph_node (decl), stmt,
bb->count, freq,
bb->loop_depth);
else
cgraph_create_indirect_edge (node, stmt,
gimple_call_flags (stmt),
bb->count, freq,
bb->loop_depth);
}
walk_stmt_load_store_addr_ops (stmt, node, mark_load,
mark_store, mark_address);
if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
......@@ -443,12 +452,21 @@ rebuild_cgraph_edges (void)
gimple stmt = gsi_stmt (gsi);
tree decl;
if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
cgraph_create_edge (node, cgraph_node (decl), stmt,
bb->count,
compute_call_stmt_bb_frequency
(current_function_decl, bb),
bb->loop_depth);
if (is_gimple_call (stmt))
{
int freq = compute_call_stmt_bb_frequency (current_function_decl,
bb);
decl = gimple_call_fndecl (stmt);
if (decl)
cgraph_create_edge (node, cgraph_node (decl), stmt,
bb->count, freq,
bb->loop_depth);
else
cgraph_create_indirect_edge (node, stmt,
gimple_call_flags (stmt),
bb->count, freq,
bb->loop_depth);
}
walk_stmt_load_store_addr_ops (stmt, node, mark_load,
mark_store, mark_address);
......
......@@ -757,12 +757,8 @@ static void
ipa_note_param_call (struct cgraph_node *node, int formal_id, gimple stmt)
{
struct cgraph_edge *cs;
basic_block bb = gimple_bb (stmt);
int freq;
freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
cs = cgraph_create_indirect_edge (node, stmt, bb->count, freq,
bb->loop_depth);
cs = cgraph_edge (node, stmt);
cs->indirect_info->param_index = formal_id;
}
......@@ -1071,7 +1067,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
/* If we ever use indirect edges for anything other than indirect
inlining, we will need to skip those with negative param_indices. */
gcc_assert (ici->param_index >= 0);
if (ici->param_index == -1)
continue;
/* We must check range due to calls with variable number of arguments: */
if (ici->param_index >= ipa_get_cs_argument_count (top))
......
......@@ -282,6 +282,21 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
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);
if (edge->indirect_unknown_callee)
{
int flags = edge->indirect_info->ecf_flags;
bp_pack_value (bp, (flags & ECF_CONST) != 0, 1);
bp_pack_value (bp, (flags & ECF_PURE) != 0, 1);
bp_pack_value (bp, (flags & ECF_NORETURN) != 0, 1);
bp_pack_value (bp, (flags & ECF_MALLOC) != 0, 1);
bp_pack_value (bp, (flags & ECF_NOTHROW) != 0, 1);
bp_pack_value (bp, (flags & ECF_RETURNS_TWICE) != 0, 1);
/* Flags that should not appear on indirect calls. */
gcc_assert (!(flags & (ECF_LOOPING_CONST_OR_PURE
| ECF_MAY_BE_ALLOCA
| ECF_SIBCALL
| ECF_NOVOPS)));
}
lto_output_bitpack (ob->main_stream, bp);
bitpack_delete (bp);
}
......@@ -1060,6 +1075,7 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes,
cgraph_inline_failed_t inline_failed;
struct bitpack_d *bp;
enum ld_plugin_symbol_resolution caller_resolution;
int ecf_flags = 0;
caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
if (caller == NULL || caller->decl == NULL_TREE)
......@@ -1091,7 +1107,7 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes,
return;
if (indirect)
edge = cgraph_create_indirect_edge (caller, NULL, count, freq, nest);
edge = cgraph_create_indirect_edge (caller, NULL, 0, count, freq, nest);
else
edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
......@@ -1100,6 +1116,22 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes,
edge->inline_failed = inline_failed;
edge->call_stmt_cannot_inline_p = bp_unpack_value (bp, 1);
edge->can_throw_external = bp_unpack_value (bp, 1);
if (indirect)
{
if (bp_unpack_value (bp, 1))
ecf_flags |= ECF_CONST;
if (bp_unpack_value (bp, 1))
ecf_flags |= ECF_PURE;
if (bp_unpack_value (bp, 1))
ecf_flags |= ECF_NORETURN;
if (bp_unpack_value (bp, 1))
ecf_flags |= ECF_MALLOC;
if (bp_unpack_value (bp, 1))
ecf_flags |= ECF_NOTHROW;
if (bp_unpack_value (bp, 1))
ecf_flags |= ECF_RETURNS_TWICE;
edge->indirect_info->ecf_flags = ecf_flags;
}
bitpack_delete (bp);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment