aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-05-19 03:01:12 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-05-19 01:01:12 +0000
commit7b3376a0da3e5de61c15899e4da1fc03ef7438d0 (patch)
treeba76d5a126b19a9883d7c963376b2cffd9f0d6a1 /gcc
parenta04d9035ec03996fd6f96a1ece21bc8d4c54cd40 (diff)
downloadgcc-7b3376a0da3e5de61c15899e4da1fc03ef7438d0.zip
gcc-7b3376a0da3e5de61c15899e4da1fc03ef7438d0.tar.gz
gcc-7b3376a0da3e5de61c15899e4da1fc03ef7438d0.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cgraph.h1
-rw-r--r--gcc/ipa.c5
-rw-r--r--gcc/symtab.c32
4 files changed, 43 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 759110d..dcbe6f658 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,17 @@
2014-05-17 Jan Hubicka <hubicka@ucw.cz>
+ * 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 <hubicka@ucw.cz>
+
* tree-pass.h (make_pass_ipa_comdats): New pass.
* timevar.def (TV_IPA_COMDATS): New timevar.
* passes.def (pass_ipa_comdats): Add.
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 8f13ecb..9dc6f01 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 ef54461..9c88fe4 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 f948e77..6b9b77a 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");