ipa.c (cgraph_externally_visible_p): Handle externally visible and preserve flags before trying to guess on visibility.

* ipa.c (cgraph_externally_visible_p): Handle externally visible and
	preserve flags before trying to guess on visibility.
	(varpool_externally_visible_p): New function.
	(function_and_variable_visibility): Use it.

From-SVN: r165669
This commit is contained in:
Jan Hubicka 2010-10-19 02:12:07 +02:00 committed by Jan Hubicka
parent 2a613cffb1
commit 93a3eea4ca
2 changed files with 71 additions and 24 deletions

View File

@ -1,3 +1,10 @@
2010-10-18 Jan Hubicka <jh@suse.cz>
* ipa.c (cgraph_externally_visible_p): Handle externally visible and
preserve flags before trying to guess on visibility.
(varpool_externally_visible_p): New function.
(function_and_variable_visibility): Use it.
2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented parsing @synthesize and @dynamic for Objective-C.

View File

@ -607,6 +607,11 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool
/* If linker counts on us, we must preserve the function. */
if (cgraph_used_from_object_file_p (node))
return true;
if (DECL_PRESERVE_P (node->decl))
return true;
if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl)))
return true;
/* When doing link time optimizations, hidden symbols become local. */
if (in_lto_p
&& (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
@ -638,11 +643,64 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool
return true;
}
}
if (DECL_PRESERVE_P (node->decl))
return true;
if (MAIN_NAME_P (DECL_NAME (node->decl)))
return true;
if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl)))
return false;
}
/* Return true when variable VNODE should be considered externally visible. */
static bool
varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
{
if (!DECL_COMDAT (vnode->decl) && !TREE_PUBLIC (vnode->decl))
return false;
/* Do not even try to be smart about aliased nodes. Until we properly
represent everything by same body alias, these are just evil. */
if (aliased)
return true;
/* If linker counts on us, we must preserve the function. */
if (varpool_used_from_object_file_p (vnode))
return true;
if (DECL_PRESERVE_P (vnode->decl))
return true;
if (lookup_attribute ("externally_visible",
DECL_ATTRIBUTES (vnode->decl)))
return true;
/* See if we have linker information about symbol not being used or
if we need to make guess based on the declaration.
Even if the linker clams the symbol is unused, never bring internal
symbols that are declared by user as used or externally visible.
This is needed for i.e. references from asm statements. */
if (varpool_used_from_object_file_p (vnode))
return true;
/* When doing link time optimizations, hidden symbols become local. */
if (in_lto_p
&& (DECL_VISIBILITY (vnode->decl) == VISIBILITY_HIDDEN
|| DECL_VISIBILITY (vnode->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. */
&& vnode->finalized)
;
else if (!flag_whole_program)
return true;
/* Do not attempt to privatize COMDATS by default.
This would break linking with C++ libraries sharing
inline definitions.
FIXME: We can do so for readonly vars with no address taken and
possibly also for vtables since no direct pointer comparsion is done.
It might be interesting to do so to reduce linking overhead. */
if (DECL_COMDAT (vnode->decl) || DECL_WEAK (vnode->decl))
return true;
return false;
}
@ -798,27 +856,9 @@ function_and_variable_visibility (bool whole_program)
if (!vnode->finalized)
continue;
if (vnode->needed
&& (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
&& (((!whole_program
/* We can privatize comdat readonly variables whose address is
not taken, but doing so is not going to bring us
optimization oppurtunities until we start reordering
datastructures. */
|| DECL_COMDAT (vnode->decl)
|| DECL_WEAK (vnode->decl))
/* When doing linktime optimizations, all hidden symbols will
become local. */
&& (!in_lto_p
|| (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))
|| DECL_PRESERVE_P (vnode->decl)
|| varpool_used_from_object_file_p (vnode)
|| pointer_set_contains (aliased_vnodes, vnode)
|| lookup_attribute ("externally_visible",
DECL_ATTRIBUTES (vnode->decl))))
&& varpool_externally_visible_p
(vnode,
pointer_set_contains (aliased_vnodes, vnode)))
vnode->externally_visible = true;
else
vnode->externally_visible = false;