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> 2013-08-08 Richard Earnshaw <rearnsha@arm.com>
PR target/57431 PR target/57431
......
...@@ -2537,55 +2537,75 @@ verify_cgraph_node (struct cgraph_node *node) ...@@ -2537,55 +2537,75 @@ verify_cgraph_node (struct cgraph_node *node)
{ {
if (this_cfun->cfg) 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 /* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */ enclosing basic-blocks in the call edges. */
FOR_EACH_BB_FN (this_block, this_cfun) FOR_EACH_BB_FN (this_block, this_cfun)
for (gsi = gsi_start_bb (this_block); {
!gsi_end_p (gsi); for (gsi = gsi_start_phis (this_block);
gsi_next (&gsi)) !gsi_end_p (gsi); gsi_next (&gsi))
{ pointer_set_insert (stmts, gsi_stmt (gsi));
gimple stmt = gsi_stmt (gsi); for (gsi = gsi_start_bb (this_block);
if (is_gimple_call (stmt)) !gsi_end_p (gsi);
{ gsi_next (&gsi))
struct cgraph_edge *e = cgraph_edge (node, stmt); {
tree decl = gimple_call_fndecl (stmt); gimple stmt = gsi_stmt (gsi);
if (e) pointer_set_insert (stmts, stmt);
{ if (is_gimple_call (stmt))
if (e->aux) {
{ struct cgraph_edge *e = cgraph_edge (node, stmt);
error ("shared call_stmt:"); tree decl = gimple_call_fndecl (stmt);
cgraph_debug_gimple_stmt (this_cfun, stmt); if (e)
error_found = true; {
} if (e->aux)
if (!e->indirect_unknown_callee) {
{ error ("shared call_stmt:");
if (verify_edge_corresponds_to_fndecl (e, decl)) cgraph_debug_gimple_stmt (this_cfun, stmt);
{ error_found = true;
error ("edge points to wrong declaration:"); }
debug_tree (e->callee->symbol.decl); if (!e->indirect_unknown_callee)
fprintf (stderr," Instead of:"); {
debug_tree (decl); if (verify_edge_corresponds_to_fndecl (e, decl))
error_found = true; {
} error ("edge points to wrong declaration:");
} debug_tree (e->callee->symbol.decl);
else if (decl) fprintf (stderr," Instead of:");
{ debug_tree (decl);
error ("an indirect edge with unknown callee " error_found = true;
"corresponding to a call_stmt with " }
"a known declaration:"); }
error_found = true; else if (decl)
cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); {
} error ("an indirect edge with unknown callee "
e->aux = (void *)1; "corresponding to a call_stmt with "
} "a known declaration:");
else if (decl) error_found = true;
{ cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
error ("missing callgraph edge for call stmt:"); }
cgraph_debug_gimple_stmt (this_cfun, stmt); e->aux = (void *)1;
error_found = true; }
} 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 else
/* No CFG available?! */ /* No CFG available?! */
......
...@@ -318,6 +318,9 @@ build_cgraph_edges (void) ...@@ -318,6 +318,9 @@ build_cgraph_edges (void)
gimple stmt = gsi_stmt (gsi); gimple stmt = gsi_stmt (gsi);
tree decl; tree decl;
if (is_gimple_debug (stmt))
continue;
if (is_gimple_call (stmt)) if (is_gimple_call (stmt))
{ {
int freq = compute_call_stmt_bb_frequency (current_function_decl, int freq = compute_call_stmt_bb_frequency (current_function_decl,
...@@ -537,7 +540,9 @@ make_pass_rebuild_cgraph_edges (gcc::context *ctxt) ...@@ -537,7 +540,9 @@ make_pass_rebuild_cgraph_edges (gcc::context *ctxt)
static unsigned int static unsigned int
remove_cgraph_callee_edges (void) 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; return 0;
} }
......
...@@ -876,7 +876,12 @@ cgraph_materialize_all_clones (void) ...@@ -876,7 +876,12 @@ cgraph_materialize_all_clones (void)
} }
FOR_EACH_FUNCTION (node) FOR_EACH_FUNCTION (node)
if (!node->symbol.analyzed && node->callees) 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) if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n"); fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
......
...@@ -1677,6 +1677,7 @@ expand_function (struct cgraph_node *node) ...@@ -1677,6 +1677,7 @@ expand_function (struct cgraph_node *node)
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
points to the dead function body. */ points to the dead function body. */
cgraph_node_remove_callees (node); cgraph_node_remove_callees (node);
ipa_remove_all_references (&node->symbol.ref_list);
} }
......
...@@ -414,6 +414,7 @@ inline_transform (struct cgraph_node *node) ...@@ -414,6 +414,7 @@ inline_transform (struct cgraph_node *node)
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
cgraph_redirect_edge_call_stmt_to_callee (e); cgraph_redirect_edge_call_stmt_to_callee (e);
ipa_remove_all_references (&node->symbol.ref_list);
timevar_push (TV_INTEGRATION); timevar_push (TV_INTEGRATION);
if (node->callees) if (node->callees)
......
...@@ -2011,6 +2011,7 @@ early_inliner (void) ...@@ -2011,6 +2011,7 @@ early_inliner (void)
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_cgraph_node (node); verify_cgraph_node (node);
#endif #endif
ipa_remove_all_references (&node->symbol.ref_list);
/* Even when not optimizing or not inlining inline always-inline /* Even when not optimizing or not inlining inline always-inline
functions. */ functions. */
......
...@@ -218,6 +218,7 @@ ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list) ...@@ -218,6 +218,7 @@ ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
{ {
struct ipa_ref *ref; struct ipa_ref *ref;
int i; int i;
for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++) for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++)
if (ref->use == IPA_REF_ALIAS) if (ref->use == IPA_REF_ALIAS)
return true; return true;
...@@ -234,7 +235,7 @@ ipa_find_reference (symtab_node referring_node, symtab_node referred_node, ...@@ -234,7 +235,7 @@ ipa_find_reference (symtab_node referring_node, symtab_node referred_node,
struct ipa_ref *r = NULL; struct ipa_ref *r = NULL;
int i; 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 if (r->referred == referred_node
&& (in_lto_p || r->stmt == stmt)) && (in_lto_p || r->stmt == stmt))
return r; return r;
...@@ -250,7 +251,20 @@ ipa_remove_stmt_references (symtab_node referring_node, gimple stmt) ...@@ -250,7 +251,20 @@ ipa_remove_stmt_references (symtab_node referring_node, gimple stmt)
struct ipa_ref *r = NULL; struct ipa_ref *r = NULL;
int i; 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) if (r->stmt == stmt)
ipa_remove_reference (r); 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 *); ...@@ -75,3 +75,4 @@ bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
bool ipa_ref_has_aliases_p (struct ipa_ref_list *); bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple); struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple);
void ipa_remove_stmt_references (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) ...@@ -1223,6 +1223,7 @@ split_function (struct split_point *split_point)
DECL_FUNCTION_CODE (node->symbol.decl) = (enum built_in_function) 0; DECL_FUNCTION_CODE (node->symbol.decl) = (enum built_in_function) 0;
} }
cgraph_node_remove_callees (cur_node); cgraph_node_remove_callees (cur_node);
ipa_remove_all_references (&cur_node->symbol.ref_list);
if (!split_part_return_p) if (!split_part_return_p)
TREE_THIS_VOLATILE (node->symbol.decl) = 1; TREE_THIS_VOLATILE (node->symbol.decl) = 1;
if (dump_file) 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