aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-10-06 19:24:40 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-10-06 17:24:40 +0000
commit0e9ea52bfcd9b8ab3994329154c48f19be7c0086 (patch)
tree277aa8d7e077ad8b81ad5af7f560f2d06a6e7ad8 /gcc/ipa.c
parent8cfaf4c938c34b48f7102b539d6db44851bf3ac4 (diff)
downloadgcc-0e9ea52bfcd9b8ab3994329154c48f19be7c0086.zip
gcc-0e9ea52bfcd9b8ab3994329154c48f19be7c0086.tar.gz
gcc-0e9ea52bfcd9b8ab3994329154c48f19be7c0086.tar.bz2
ipa.c (cgraph_remove_unreachable_nodes): External references can always be removed.
* ipa.c (cgraph_remove_unreachable_nodes): External references can always be removed. (cgraph_externally_visible_p): We can not bring local comdats that are known to linker; fix handling of internal visibility. (function_and_variable_visibility): Likewise. From-SVN: r165057
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r--gcc/ipa.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 9670a9c..4fbc3b7 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -238,14 +238,19 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
#endif
varpool_reset_queue ();
for (node = cgraph_nodes; node; node = node->next)
- if ((!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
- /* Keep around virtual functions for possible devirtualization. */
- || (!before_inlining_p
- && !node->global.inlined_to
- && DECL_VIRTUAL_P (node->decl)
- && (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))))
- && ((!DECL_EXTERNAL (node->decl))
- || before_inlining_p))
+ if (!node->analyzed)
+ {
+ gcc_assert (!node->aux);
+ node->reachable = false;
+ }
+ else if ((!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
+ /* Keep around virtual functions for possible devirtualization. */
+ || (!before_inlining_p
+ && !node->global.inlined_to
+ && DECL_VIRTUAL_P (node->decl)
+ && (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))))
+ && ((!DECL_EXTERNAL (node->decl))
+ || before_inlining_p))
{
gcc_assert (!node->global.inlined_to);
enqueue_cgraph_node (node, &first);
@@ -592,8 +597,13 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool
if (aliased)
return true;
+ /* If linker counts on us, we must preserve the function. */
+ if (cgraph_used_from_object_file_p (node))
+ return true;
/* When doing link time optimizations, hidden symbols become local. */
- if (in_lto_p && DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
+ if (in_lto_p
+ && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
+ || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object
file. In that case we don't set used_from_other_object_file. */
&& node->analyzed)
@@ -621,8 +631,6 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool
return true;
}
}
- if (cgraph_used_from_object_file_p (node))
- return true;
if (DECL_PRESERVE_P (node->decl))
return true;
if (MAIN_NAME_P (DECL_NAME (node->decl)))
@@ -794,7 +802,8 @@ function_and_variable_visibility (bool whole_program)
/* When doing linktime optimizations, all hidden symbols will
become local. */
&& (!in_lto_p
- || DECL_VISIBILITY (vnode->decl) != VISIBILITY_HIDDEN
+ || (DECL_VISIBILITY (vnode->decl) != VISIBILITY_HIDDEN
+ && DECL_VISIBILITY (vnode->decl) != VISIBILITY_INTERNAL)
/* We can get prevailing decision in other object file.
In this case we do not sed used_from_object_file. */
|| !vnode->finalized))