From: hubicka Date: Thu, 8 Aug 2013 14:15:15 +0000 (+0000) Subject: * cgraphbuild.c (build_cgraph_edges): Do not walk into debugs. X-Git-Tag: upstream/4.9.2~4844 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9df17e791314bc9ed3b603098ab5b775bf8297a4;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201601 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e55b5db..349981c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-08-08 Jan Hubicka + + * 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 PR target/57431 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index bb7016f..d217b4a 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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?! */ diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index a7872de..333deed 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -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; } diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 21ef1f5..464c524 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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 diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 1472483..3cd2b41 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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); } diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 5e666ae..54b113a 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -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) diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 96cbc9a..8c5b430 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -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. */ diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c index a6ffdf3..d2c6002 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -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; +} diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h index c25e4e4..0b37a14 100644 --- a/gcc/ipa-ref.h +++ b/gcc/ipa-ref.h @@ -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); diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index c83c4d0..faf7c84 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -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)