From: Jan Hubicka Date: Mon, 19 May 2014 01:01:12 +0000 (+0200) Subject: ipa.c (symtab_remove_unreachable_nodes): Remove symbol from comdat group if its body... X-Git-Tag: releases/gcc-5.1.0~7476 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7b3376a0da3e5de61c15899e4da1fc03ef7438d0;p=thirdparty%2Fgcc.git ipa.c (symtab_remove_unreachable_nodes): Remove symbol from comdat group if its body was eliminated. * ipa.c (symtab_remove_unreachable_nodes): Remove symbol from comdat group if its body was eliminated. (comdat_can_be_unshared_p_1): Static symbols can always be privatized. * symtab.c (symtab_remove_from_same_comdat_group): Break out from ... (symtab_unregister_node): ... this one. (verify_symtab_base): More strict checking of comdats. * cgraph.h (symtab_remove_from_same_comdat_group): Declare. From-SVN: r210598 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 759110d21e29..dcbe6f658de3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2014-05-17 Jan Hubicka + + * ipa.c (symtab_remove_unreachable_nodes): Remove + symbol from comdat group if its body was eliminated. + (comdat_can_be_unshared_p_1): Static symbols can always + be privatized. + * symtab.c (symtab_remove_from_same_comdat_group): Break out + from ... + (symtab_unregister_node): ... this one. + (verify_symtab_base): More strict checking of comdats. + * cgraph.h (symtab_remove_from_same_comdat_group): Declare. + 2014-05-17 Jan Hubicka * tree-pass.h (make_pass_ipa_comdats): New pass. diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 8f13ecbe11ce..9dc6f0186f18 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -725,6 +725,7 @@ enum symbol_partitioning_class /* In symtab.c */ void symtab_register_node (symtab_node *); void symtab_unregister_node (symtab_node *); +void symtab_remove_from_same_comdat_group (symtab_node *); void symtab_remove_node (symtab_node *); symtab_node *symtab_get_node (const_tree); symtab_node *symtab_node_for_asm (const_tree asmname); diff --git a/gcc/ipa.c b/gcc/ipa.c index ef544615a4a9..9c88fe4dbbad 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -517,6 +517,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) if (!node->in_other_partition) node->local.local = false; cgraph_node_remove_callees (node); + symtab_remove_from_same_comdat_group (node); ipa_remove_all_references (&node->ref_list); changed = true; } @@ -572,6 +573,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) vnode->analyzed = false; vnode->aux = NULL; + symtab_remove_from_same_comdat_group (vnode); + /* Keep body if it may be useful for constant folding. */ if ((init = ctor_for_folding (vnode->decl)) == error_mark_node) varpool_remove_initializer (vnode); @@ -776,6 +779,8 @@ address_taken_from_non_vtable_p (symtab_node *node) static bool comdat_can_be_unshared_p_1 (symtab_node *node) { + if (!node->externally_visible) + return true; /* When address is taken, we don't know if equality comparison won't break eventually. Exception are virutal functions, C++ constructors/destructors and vtables, where this is not possible by diff --git a/gcc/symtab.c b/gcc/symtab.c index f948e7742597..6b9b77abdfc8 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -323,16 +323,11 @@ symtab_insert_node_to_hashtable (symtab_node *node) *slot = node; } -/* Remove node from symbol table. This function is not used directly, but via - cgraph/varpool node removal routines. */ +/* Remove NODE from same comdat group. */ void -symtab_unregister_node (symtab_node *node) +symtab_remove_from_same_comdat_group (symtab_node *node) { - void **slot; - ipa_remove_all_references (&node->ref_list); - ipa_remove_all_referring (&node->ref_list); - if (node->same_comdat_group) { symtab_node *prev; @@ -346,6 +341,19 @@ symtab_unregister_node (symtab_node *node) prev->same_comdat_group = node->same_comdat_group; node->same_comdat_group = NULL; } +} + +/* Remove node from symbol table. This function is not used directly, but via + cgraph/varpool node removal routines. */ + +void +symtab_unregister_node (symtab_node *node) +{ + void **slot; + ipa_remove_all_references (&node->ref_list); + ipa_remove_all_referring (&node->ref_list); + + symtab_remove_from_same_comdat_group (node); if (node->previous) node->previous->next = node->next; @@ -829,6 +837,16 @@ verify_symtab_base (symtab_node *node) error ("non-DECL_ONE_ONLY node in a same_comdat_group list"); error_found = true; } + if (DECL_COMDAT_GROUP (n->decl) != DECL_COMDAT_GROUP (node->same_comdat_group->decl)) + { + error ("same_comdat_group list across different groups"); + error_found = true; + } + if (!n->definition) + { + error ("Node has same_comdat_group but it is not a definition"); + error_found = true; + } if (n->type != node->type) { error ("mixing different types of symbol in same comdat groups is not supported");