From 28307164dfed294855bf3d55bed357de560f083b Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 21 Jan 2020 16:33:43 +0100 Subject: [PATCH] Fix updating of call_stmt_site_hash This patch fixes ICE causes by call stmt site hash going out of sync. For speculative edges it is assumed to contain a direct call so if we are removing it hashtable needs to be updated. I realize that the code is ugly but I will leave cleanup for next stage1. Bootstrapped/regtested x86_64-linux. This patch makes it possible to build Firefox again. PR lto/93318 * cgraph.c (cgraph_edge::resolve_speculation, cgraph_edge::redirect_call_stmt_to_callee): Fix update of call_stmt_site_hash. --- gcc/ChangeLog | 7 +++++++ gcc/cgraph.c | 32 ++++++++++++++++++++++++++++++-- gcc/ipa.c | 9 ++++++--- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48c423a3b09..1e596773ba0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-01-18 Jan Hubicka + + PR lto/93318 + * cgraph.c (cgraph_edge::resolve_speculation, + cgraph_edge::redirect_call_stmt_to_callee): Fix update of + call_stmt_site_hash. + 2020-01-21 Martin Liska * config/rs6000/rs6000.c (common_mode_defined): Remove diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 187f6ed30ba..f7ebcc917d1 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1248,7 +1248,22 @@ cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl) else e2->callee->remove_symbol_and_inline_clones (); if (edge->caller->call_site_hash) - cgraph_update_edge_in_call_site_hash (edge); + { + /* We always maintain direct edge in the call site hash, if one + exists. */ + if (!edge->num_speculative_call_targets_p ()) + cgraph_update_edge_in_call_site_hash (edge); + else + { + cgraph_edge *e; + for (e = edge->caller->callees; + e->call_stmt != edge->call_stmt + || e->lto_stmt_uid != edge->lto_stmt_uid; + e = e->next_callee) + ; + cgraph_update_edge_in_call_site_hash (e); + } + } return edge; } @@ -1414,7 +1429,20 @@ cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e) /* Indirect edges are not both in the call site hash. get it updated. */ if (e->caller->call_site_hash) - cgraph_update_edge_in_call_site_hash (e2); + { + if (!e2->num_speculative_call_targets_p ()) + cgraph_update_edge_in_call_site_hash (e2); + else + { + cgraph_edge *e; + for (e = e2->caller->callees; + e->call_stmt != e2->call_stmt + || e->lto_stmt_uid != e2->lto_stmt_uid; + e = e->next_callee) + ; + cgraph_update_edge_in_call_site_hash (e); + } + } pop_cfun (); /* Continue redirecting E to proper target. */ } diff --git a/gcc/ipa.c b/gcc/ipa.c index e2635a71789..55481931668 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -391,17 +391,20 @@ symbol_table::remove_unreachable_nodes (FILE *file) n->used_as_abstract_origin = true; } } - /* If any symbol in a comdat group is reachable, force - all externally visible symbols in the same comdat + /* If any non-external and non-local symbol in a comdat group is + reachable, force all externally visible symbols in the same comdat group to be reachable as well. Comdat-local symbols can be discarded if all uses were inlined. */ - if (node->same_comdat_group) + if (node->same_comdat_group + && node->externally_visible + && !DECL_EXTERNAL (node->decl)) { symtab_node *next; for (next = node->same_comdat_group; next != node; next = next->same_comdat_group) if (!next->comdat_local_p () + && !DECL_EXTERNAL (next->decl) && !reachable.add (next)) enqueue_node (next, &first, &reachable); } -- 2.30.2