From f1703a2e2b3fefa60a70e08f30be5fb4a7fd8b4f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 29 Nov 2015 23:33:23 +0100 Subject: [PATCH] cgraph.c (cgraph_node::make_local): No name is unique during incremental linking. * cgraph.c (cgraph_node::make_local): No name is unique during incremental linking. * cgraph.h (can_be_discarded_p): Update comment; also common and WEAK in named sections can be discarded; when doing incremental link do not rely on resolution being the final one. * varasm.c (default_binds_local_p_3, decl_binds_to_current_def_p): When symbol can be discarded, do not rely on resolution info. * symtab.c (symtab_node::nonzero_address): Take into account that symbol can be discarded. * ipa-visibility.c (update_visibility_by_resolution_info): Handle definition correctly. (function_and_variable_visibility): Do not set unique_name when incrementally linking. From-SVN: r231050 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/cgraph.c | 5 +++-- gcc/cgraph.h | 18 +++++++++++++----- gcc/ipa-visibility.c | 37 +++++++++++++++++++------------------ gcc/symtab.c | 2 ++ gcc/varasm.c | 7 +++++-- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e49fd7af15c..3f6024ee3ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-11-29 Jan Hubicka + + * cgraph.c (cgraph_node::make_local): No name is unique during + incremental linking. + * cgraph.h (can_be_discarded_p): Update comment; also common and + WEAK in named sections can be discarded; when doing incremental + link do not rely on resolution being the final one. + * varasm.c (default_binds_local_p_3, decl_binds_to_current_def_p): + When symbol can be discarded, do not rely on resolution info. + * symtab.c (symtab_node::nonzero_address): Take into account that + symbol can be discarded. + * ipa-visibility.c (update_visibility_by_resolution_info): Handle + definition correctly. + (function_and_variable_visibility): Do not set unique_name when + incrementally linking. + 2015-11-29 Nathan Sidwell * config/nvptx/nvptx.md (const_0_operand, global_mem_operand, diff --git a/gcc/cgraph.c b/gcc/cgraph.c index b1228a2d5de..3ee1907c335 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2253,8 +2253,9 @@ cgraph_node::make_local (cgraph_node *node, void *) node->forced_by_abi = false; node->local.local = true; node->set_section (NULL); - node->unique_name = (node->resolution == LDPR_PREVAILING_DEF_IRONLY - || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP); + node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY + || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && !flag_incremental_link); node->resolution = LDPR_PREVAILING_DEF_IRONLY; gcc_assert (node->get_availability () == AVAIL_LOCAL); } diff --git a/gcc/cgraph.h b/gcc/cgraph.h index b6390995ab9..6cff4468cc0 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -319,15 +319,23 @@ public: /* Return true when there are references to the node. */ bool referred_to_p (bool include_self = true); - /* Return true if NODE can be discarded by linker from the binary. */ + /* Return true if symbol can be discarded by linker from the binary. + Assume that symbol is used (so there is no need to take into account + garbage collecting linkers) + + This can happen for comdats, commons and weaks when they are previaled + by other definition at static linking time. */ inline bool can_be_discarded_p (void) { return (DECL_EXTERNAL (decl) - || (get_comdat_group () - && resolution != LDPR_PREVAILING_DEF - && resolution != LDPR_PREVAILING_DEF_IRONLY - && resolution != LDPR_PREVAILING_DEF_IRONLY_EXP)); + || ((get_comdat_group () + || DECL_COMMON (decl) + || (DECL_SECTION_NAME (decl) && DECL_WEAK (decl))) + && ((resolution != LDPR_PREVAILING_DEF + && resolution != LDPR_PREVAILING_DEF_IRONLY_EXP) + || flag_incremental_link) + && resolution != LDPR_PREVAILING_DEF_IRONLY)); } /* Return true if NODE is local to a particular COMDAT group, and must not diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index 41ed4db6745..2eab214243e 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -413,10 +413,10 @@ update_visibility_by_resolution_info (symtab_node * node) DECL_WEAK (next->decl) = false; next->set_comdat_group (NULL); } - if (next->externally_visible - && !define) + if (!define) { - DECL_EXTERNAL (next->decl) = true; + if (next->externally_visible) + DECL_EXTERNAL (next->decl) = true; next->set_comdat_group (NULL); } } @@ -513,10 +513,10 @@ function_and_variable_visibility (bool whole_program) { gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl)); - node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY - || node->unique_name - || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) - && TREE_PUBLIC (node->decl)); + node->unique_name |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY + || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && TREE_PUBLIC (node->decl) + && !flag_incremental_link); node->resolution = LDPR_PREVAILING_DEF_IRONLY; if (node->same_comdat_group && TREE_PUBLIC (node->decl)) { @@ -532,10 +532,10 @@ function_and_variable_visibility (bool whole_program) if (!next->alias) next->set_section (NULL); next->make_decl_local (); - next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY - || next->unique_name - || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) - && TREE_PUBLIC (next->decl)); + next->unique_name |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY + || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && TREE_PUBLIC (next->decl) + && !flag_incremental_link); } /* cgraph_externally_visible_p has already checked all other nodes in the group and they will all be made local. We need to @@ -657,10 +657,11 @@ function_and_variable_visibility (bool whole_program) && !vnode->weakref) { gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl)); - vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY - || vnode->resolution + vnode->unique_name |= ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY + || vnode->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) - && TREE_PUBLIC (vnode->decl)); + && TREE_PUBLIC (vnode->decl) + && !flag_incremental_link); if (vnode->same_comdat_group && TREE_PUBLIC (vnode->decl)) { symtab_node *next = vnode; @@ -675,10 +676,10 @@ function_and_variable_visibility (bool whole_program) if (!next->alias) next->set_section (NULL); next->make_decl_local (); - next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY - || next->unique_name - || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) - && TREE_PUBLIC (next->decl)); + next->unique_name |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY + || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + && TREE_PUBLIC (next->decl) + && !flag_incremental_link); } vnode->dissolve_same_comdat_group_list (); } diff --git a/gcc/symtab.c b/gcc/symtab.c index 96771315628..c188710ea92 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -1713,6 +1713,7 @@ symtab_node::nonzero_address () return true; if (target->resolution != LDPR_UNKNOWN && target->resolution != LDPR_UNDEF + && !target->can_be_discarded_p () && flag_delete_null_pointer_checks) return true; return false; @@ -1751,6 +1752,7 @@ symtab_node::nonzero_address () /* As the last resort, check the resolution info. */ if (resolution != LDPR_UNKNOWN && resolution != LDPR_UNDEF + && !can_be_discarded_p () && flag_delete_null_pointer_checks) return true; return false; diff --git a/gcc/varasm.c b/gcc/varasm.c index a2adcdba092..c4c55e7cd06 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -6837,7 +6837,9 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, { if (node->in_other_partition) defined_locally = true; - if (resolution_to_local_definition_p (node->resolution)) + if (node->can_be_discarded_p ()) + ; + else if (resolution_to_local_definition_p (node->resolution)) defined_locally = resolved_locally = true; else if (resolution_local_p (node->resolution)) resolved_locally = true; @@ -6930,7 +6932,8 @@ decl_binds_to_current_def_p (const_tree decl) /* When resolution is available, just use it. */ if (symtab_node *node = symtab_node::get (decl)) { - if (node->resolution != LDPR_UNKNOWN) + if (node->resolution != LDPR_UNKNOWN + && !node->can_be_discarded_p ()) return resolution_to_local_definition_p (node->resolution); } -- 2.30.2