Commit 71cafea9 by Jan Hubicka Committed by Jan Hubicka

cgraphbuild.c (build_cgraph_edges): Do not walk into debugs.


	* cgraphbuild.c (build_cgraph_edges): Do not walk into debugs.
	(make_pass_rebuild_cgraph_edges): Also clear references.
	* cgraph.c (verify_cgraph_node): Add basic ipa-ref verifier.
	* ipa-inline-transform.c (inline_transform): Remove all references
	after inlining.
	* cgraphunit.c (expand_function): Remove all references after expansion.
	* ipa-ref.c (ipa_ref_has_aliases_p): Fix formatting.
	(ipa_find_reference): Rewrite to iterator.
	(remove_stmt_references): Likewise.
	(ipa_clear_stmts_in_references): New function.
	* ipa-ref.h (ipa_clear_stmts_in_references): Declare.
	* cgraphclones.c (cgraph_materialize_all_clones): Remove or clear references.
	* ipa-split.c (split_function): Remove references in split function.

From-SVN: r201601
parent 27d2e612
2013-08-08 Jan Hubicka <jh@suse.cz>
* cgraphbuild.c (build_cgraph_edges): Do not walk into debugs.
(make_pass_rebuild_cgraph_edges): Also clear references.
* cgraph.c (verify_cgraph_node): Add basic ipa-ref verifier.
* ipa-inline-transform.c (inline_transform): Remove all references
after inlining.
* cgraphunit.c (expand_function): Remove all references after expansion.
* ipa-ref.c (ipa_ref_has_aliases_p): Fix formatting.
(ipa_find_reference): Rewrite to iterator.
(remove_stmt_references): Likewise.
(ipa_clear_stmts_in_references): New function.
* ipa-ref.h (ipa_clear_stmts_in_references): Declare.
* cgraphclones.c (cgraph_materialize_all_clones): Remove or clear references.
* ipa-split.c (split_function): Remove references in split function.
2013-08-08 Richard Earnshaw <rearnsha@arm.com>
PR target/57431
......
......@@ -2537,55 +2537,75 @@ verify_cgraph_node (struct cgraph_node *node)
{
if (this_cfun->cfg)
{
pointer_set_t *stmts = pointer_set_create ();
int i;
struct ipa_ref *ref;
/* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */
FOR_EACH_BB_FN (this_block, this_cfun)
for (gsi = gsi_start_bb (this_block);
!gsi_end_p (gsi);
gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
if (is_gimple_call (stmt))
{
struct cgraph_edge *e = cgraph_edge (node, stmt);
tree decl = gimple_call_fndecl (stmt);
if (e)
{
if (e->aux)
{
error ("shared call_stmt:");
cgraph_debug_gimple_stmt (this_cfun, stmt);
error_found = true;
}
if (!e->indirect_unknown_callee)
{
if (verify_edge_corresponds_to_fndecl (e, decl))
{
error ("edge points to wrong declaration:");
debug_tree (e->callee->symbol.decl);
fprintf (stderr," Instead of:");
debug_tree (decl);
error_found = true;
}
}
else if (decl)
{
error ("an indirect edge with unknown callee "
"corresponding to a call_stmt with "
"a known declaration:");
error_found = true;
cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
}
e->aux = (void *)1;
}
else if (decl)
{
error ("missing callgraph edge for call stmt:");
cgraph_debug_gimple_stmt (this_cfun, stmt);
error_found = true;
}
}
{
for (gsi = gsi_start_phis (this_block);
!gsi_end_p (gsi); gsi_next (&gsi))
pointer_set_insert (stmts, gsi_stmt (gsi));
for (gsi = gsi_start_bb (this_block);
!gsi_end_p (gsi);
gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
pointer_set_insert (stmts, stmt);
if (is_gimple_call (stmt))
{
struct cgraph_edge *e = cgraph_edge (node, stmt);
tree decl = gimple_call_fndecl (stmt);
if (e)
{
if (e->aux)
{
error ("shared call_stmt:");
cgraph_debug_gimple_stmt (this_cfun, stmt);
error_found = true;
}
if (!e->indirect_unknown_callee)
{
if (verify_edge_corresponds_to_fndecl (e, decl))
{
error ("edge points to wrong declaration:");
debug_tree (e->callee->symbol.decl);
fprintf (stderr," Instead of:");
debug_tree (decl);
error_found = true;
}
}
else if (decl)
{
error ("an indirect edge with unknown callee "
"corresponding to a call_stmt with "
"a known declaration:");
error_found = true;
cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
}
e->aux = (void *)1;
}
else if (decl)
{
error ("missing callgraph edge for call stmt:");
cgraph_debug_gimple_stmt (this_cfun, stmt);
error_found = true;
}
}
}
}
for (i = 0;
ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref);
i++)
if (ref->stmt && !pointer_set_contains (stmts, ref->stmt))
{
error ("reference to dead statement");
cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
error_found = true;
}
pointer_set_destroy (stmts);
}
else
/* No CFG available?! */
......
......@@ -318,6 +318,9 @@ build_cgraph_edges (void)
gimple stmt = gsi_stmt (gsi);
tree decl;
if (is_gimple_debug (stmt))
continue;
if (is_gimple_call (stmt))
{
int freq = compute_call_stmt_bb_frequency (current_function_decl,
......@@ -537,7 +540,9 @@ make_pass_rebuild_cgraph_edges (gcc::context *ctxt)
static unsigned int
remove_cgraph_callee_edges (void)
{
cgraph_node_remove_callees (cgraph_get_node (current_function_decl));
struct cgraph_node *node = cgraph_get_node (current_function_decl);
cgraph_node_remove_callees (node);
ipa_remove_all_references (&node->symbol.ref_list);
return 0;
}
......
......@@ -876,7 +876,12 @@ cgraph_materialize_all_clones (void)
}
FOR_EACH_FUNCTION (node)
if (!node->symbol.analyzed && node->callees)
cgraph_node_remove_callees (node);
{
cgraph_node_remove_callees (node);
ipa_remove_all_references (&node->symbol.ref_list);
}
else
ipa_clear_stmts_in_references ((symtab_node)node);
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
#ifdef ENABLE_CHECKING
......
......@@ -1677,6 +1677,7 @@ expand_function (struct cgraph_node *node)
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
points to the dead function body. */
cgraph_node_remove_callees (node);
ipa_remove_all_references (&node->symbol.ref_list);
}
......
......@@ -414,6 +414,7 @@ inline_transform (struct cgraph_node *node)
for (e = node->callees; e; e = e->next_callee)
cgraph_redirect_edge_call_stmt_to_callee (e);
ipa_remove_all_references (&node->symbol.ref_list);
timevar_push (TV_INTEGRATION);
if (node->callees)
......
......@@ -2011,6 +2011,7 @@ early_inliner (void)
#ifdef ENABLE_CHECKING
verify_cgraph_node (node);
#endif
ipa_remove_all_references (&node->symbol.ref_list);
/* Even when not optimizing or not inlining inline always-inline
functions. */
......
......@@ -218,6 +218,7 @@ ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
{
struct ipa_ref *ref;
int i;
for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
return true;
......@@ -234,7 +235,7 @@ ipa_find_reference (symtab_node referring_node, symtab_node referred_node,
struct ipa_ref *r = NULL;
int i;
FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r)
for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
if (r->referred == referred_node
&& (in_lto_p || r->stmt == stmt))
return r;
......@@ -250,7 +251,20 @@ ipa_remove_stmt_references (symtab_node referring_node, gimple stmt)
struct ipa_ref *r = NULL;
int i;
FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r)
for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
if (r->stmt == stmt)
ipa_remove_reference (r);
}
/* Remove all stmt references in non-speculative references.
Those are not maintained during inlining & clonning. */
void
ipa_clear_stmts_in_references (symtab_node referring_node)
{
struct ipa_ref *r = NULL;
int i;
for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
r->stmt = NULL;
}
......@@ -75,3 +75,4 @@ bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple);
void ipa_remove_stmt_references (symtab_node, gimple);
void ipa_clear_stmts_in_references (symtab_node);
......@@ -1223,6 +1223,7 @@ split_function (struct split_point *split_point)
DECL_FUNCTION_CODE (node->symbol.decl) = (enum built_in_function) 0;
}
cgraph_node_remove_callees (cur_node);
ipa_remove_all_references (&cur_node->symbol.ref_list);
if (!split_part_return_p)
TREE_THIS_VOLATILE (node->symbol.decl) = 1;
if (dump_file)
......
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