summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-11-29 23:33:23 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2015-11-29 22:33:23 +0000
commitf1703a2e2b3fefa60a70e08f30be5fb4a7fd8b4f (patch)
treeb119bcfa394a1eeb2b5f120d0165f4e631cf136b
parenta4850ce9b58d12158248dc7fbe1015646757c813 (diff)
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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/cgraph.c5
-rw-r--r--gcc/cgraph.h18
-rw-r--r--gcc/ipa-visibility.c37
-rw-r--r--gcc/symtab.c2
-rw-r--r--gcc/varasm.c7
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 <hubicka@ucw.cz>
+
+ * 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 <nathan@acm.org>
* 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);
}