From: Martin Liska Date: Sun, 1 Mar 2015 20:23:21 +0000 (+0100) Subject: re PR ipa/65245 (internal compiler error: in address_matters_p, at symtab.c:1908) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b6cddc7fb673b0712f03dfb3b7c1f7df81a139c6;p=gcc.git re PR ipa/65245 (internal compiler error: in address_matters_p, at symtab.c:1908) 2015-02-28 Martin Liska Jan Hubicka PR ipa/65245 * ipa-icf-gimple.c (func_checker::compare_function_decl): Remove. (func_checker::compare_variable_decl): Skip symtab vars. (func_checker::compare_cst_or_decl): Update. * ipa-icf.c (sem_function::parse): Do not consider aliases. (sem_function::compare_cgraph_references): Add ADDRESS parameter; use correct symtab predicates. (sem_function::equals_wpa): Update uses of compare_cgraph_references. (sem_variable::parse): Update comment. (sem_item_optimizer::build_graph): Consider ultimate aliases for references. * gcc.dg/ipa/ipa-icf-34.c: New test. Co-Authored-By: Jan Hubicka From-SVN: r221090 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b47008e9750..ef9292f0f81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-02-28 Martin Liska + Jan Hubicka + + PR ipa/65245 + * ipa-icf-gimple.c (func_checker::compare_function_decl): + Remove. + (func_checker::compare_variable_decl): Skip symtab vars. + (func_checker::compare_cst_or_decl): Update. + * ipa-icf.c (sem_function::parse): Do not consider aliases. + (sem_function::compare_cgraph_references): Add ADDRESS parameter; + use correct symtab predicates. + (sem_function::equals_wpa): Update uses of compare_cgraph_references. + (sem_variable::parse): Update comment. + (sem_item_optimizer::build_graph): Consider ultimate aliases + for references. + 2015-02-28 Jan Hubicka * ipa-icf-gimple.c (func_checker::compare_operand): Fix handling diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c index 18631730b69..7cc58d461e2 100644 --- a/gcc/ipa-icf-gimple.c +++ b/gcc/ipa-icf-gimple.c @@ -312,10 +312,9 @@ func_checker::compare_cst_or_decl (tree t1, tree t2) return return_with_debug (ret); } case FUNCTION_DECL: - { - ret = compare_function_decl (t1, t2); - return return_with_debug (ret); - } + /* All function decls are in the symbol table and known to match + before we start comparing bodies. */ + return true; case VAR_DECL: return return_with_debug (compare_variable_decl (t1, t2)); case FIELD_DECL: @@ -537,39 +536,6 @@ func_checker::compare_tree_list_operand (tree t1, tree t2) return true; } -/* Verifies that trees T1 and T2, representing function declarations - are equivalent from perspective of ICF. */ - -bool -func_checker::compare_function_decl (tree t1, tree t2) -{ - bool ret = false; - - if (t1 == t2) - return true; - - symtab_node *n1 = symtab_node::get (t1); - symtab_node *n2 = symtab_node::get (t2); - - if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL) - { - ret = m_ignored_source_nodes->contains (n1) - && m_ignored_target_nodes->contains (n2); - - if (ret) - return true; - } - - /* If function decl is WEAKREF, we compare targets. */ - cgraph_node *f1 = cgraph_node::get (t1); - cgraph_node *f2 = cgraph_node::get (t2); - - if(f1 && f2 && f1->weakref && f2->weakref) - ret = f1->alias_target == f2->alias_target; - - return ret; -} - /* Verifies that trees T1 and T2 do correspond. */ bool @@ -590,20 +556,10 @@ func_checker::compare_variable_decl (tree t1, tree t2) && DECL_ASSEMBLER_NAME (t1) != DECL_ASSEMBLER_NAME (t2)) return return_false_with_msg ("HARD REGISTERS are different"); - if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1))) - { - symtab_node *n1 = symtab_node::get (t1); - symtab_node *n2 = symtab_node::get (t2); - - if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL) - { - ret = m_ignored_source_nodes->contains (n1) - && m_ignored_target_nodes->contains (n2); - - if (ret) - return true; - } - } + /* Symbol table variables are known to match before we start comparing + bodies. */ + if (decl_in_symtab_p (t1)) + return decl_in_symtab_p (t2); ret = compare_decl (t1, t2); return return_with_debug (ret); diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 70a2883d412..0de69a83fb5 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -335,17 +335,26 @@ sem_function::get_hash (void) /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs point to a same function. Comparison can be skipped if IGNORED_NODES - contains these nodes. */ + contains these nodes. ADDRESS indicate if address is taken. */ bool -sem_function::compare_cgraph_references (hash_map - &ignored_nodes, - symtab_node *n1, symtab_node *n2) +sem_function::compare_cgraph_references ( + hash_map &ignored_nodes, + symtab_node *n1, symtab_node *n2, bool address) { - if (n1 == n2 || (ignored_nodes.get (n1) && ignored_nodes.get (n2))) + enum availability avail1, avail2; + + if (address && n1->equal_address_to (n2) == 1) + return true; + if (!address && n1->semantically_equivalent_p (n2)) return true; - /* TODO: add more precise comparison for weakrefs, etc. */ + n1 = n1->ultimate_alias_target (&avail1); + n2 = n2->ultimate_alias_target (&avail2); + + if (avail1 >= AVAIL_INTERPOSABLE && ignored_nodes.get (n1) + && avail2 >= AVAIL_INTERPOSABLE && ignored_nodes.get (n2)) + return true; return return_false_with_msg ("different references"); } @@ -412,7 +421,9 @@ sem_function::equals_wpa (sem_item *item, { item->node->iterate_reference (i, ref2); - if (!compare_cgraph_references (ignored_nodes, ref->referred, ref2->referred)) + if (!compare_cgraph_references (ignored_nodes, ref->referred, + ref2->referred, + ref->address_matters_p ())) return false; } @@ -421,7 +432,8 @@ sem_function::equals_wpa (sem_item *item, while (e1 && e2) { - if (!compare_cgraph_references (ignored_nodes, e1->callee, e2->callee)) + if (!compare_cgraph_references (ignored_nodes, e1->callee, + e2->callee, false)) return false; e1 = e1->next_callee; @@ -1117,7 +1129,7 @@ sem_function::parse (cgraph_node *node, bitmap_obstack *stack) tree fndecl = node->decl; function *func = DECL_STRUCT_FUNCTION (fndecl); - /* TODO: add support for thunks and aliases. */ + /* TODO: add support for thunks. */ if (!func || !node->has_gimple_body_p ()) return NULL; @@ -1429,6 +1441,9 @@ sem_variable::parse (varpool_node *node, bitmap_obstack *stack) { tree decl = node->decl; + if (node->alias) + return NULL; + bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl); if (!readonly) return NULL; @@ -2086,7 +2101,8 @@ sem_item_optimizer::build_graph (void) cgraph_edge *e = cnode->callees; while (e) { - sem_item **slot = m_symtab_node_map.get (e->callee); + sem_item **slot = m_symtab_node_map.get + (e->callee->ultimate_alias_target ()); if (slot) item->add_reference (*slot); @@ -2097,7 +2113,8 @@ sem_item_optimizer::build_graph (void) ipa_ref *ref = NULL; for (unsigned i = 0; item->node->iterate_reference (i, ref); i++) { - sem_item **slot = m_symtab_node_map.get (ref->referred); + sem_item **slot = m_symtab_node_map.get + (ref->referred->ultimate_alias_target ()); if (slot) item->add_reference (*slot); } diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h index 077267ce087..bf01cf09f21 100644 --- a/gcc/ipa-icf.h +++ b/gcc/ipa-icf.h @@ -353,10 +353,11 @@ private: /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs point to a same function. Comparison can be skipped if IGNORED_NODES - contains these nodes. */ + contains these nodes. ADDRESS indicate if address is taken. */ bool compare_cgraph_references (hash_map &ignored_nodes, - symtab_node *n1, symtab_node *n2); + symtab_node *n1, symtab_node *n2, + bool address); /* Processes function equality comparison. */ bool equals_private (sem_item *item, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d8f5180059c..e397689d287 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-02-28 Martin Liska + Jan Hubicka + + PR ipa/65245 + * gcc.dg/ipa/ipa-icf-34.c: New test. + 2015-03-01 Oleg Endo PR target/61142 diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c new file mode 100644 index 00000000000..698044ae22d --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf" } */ + +static int do_work(void) +{ + return 0; +} + +static int foo() __attribute__((alias("do_work"))); +static int bar() __attribute__((alias("do_work"))); + +static int a() +{ + return foo(); +} + +static int b() +{ + return bar(); +} + +int main() +{ + return a() + b(); +} + +/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf" } } */ +/* { dg-final { cleanup-ipa-dump "icf" } } */