aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-06-05 16:15:31 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-06-05 14:15:31 +0000
commitedb983b2cb3961d9a5fa45444ff0fbf16e3adc0a (patch)
treea3982caf99872c7045fe2746bb44f9b7a2a178ac /gcc/ipa.c
parent9912dbe5c7d8c715d6506380ef62a3377297f4b4 (diff)
downloadgcc-edb983b2cb3961d9a5fa45444ff0fbf16e3adc0a.zip
gcc-edb983b2cb3961d9a5fa45444ff0fbf16e3adc0a.tar.gz
gcc-edb983b2cb3961d9a5fa45444ff0fbf16e3adc0a.tar.bz2
class.c (emit_register_classes_in_jcr_section): Use DECL_PRESERVE_P instead of mark_decl_referenced.
* class.c (emit_register_classes_in_jcr_section): Use DECL_PRESERVE_P instead of mark_decl_referenced. * decl2.c (maybe_make_one_only): Use forced_by_abi instad of mark_decl_referenced. (mark_needed): Likewise. * cgraph.c (cgraph_remove_node): Clear forced_by_abi. (cgraph_node_cannot_be_local_p_1): Honnor symbol.forced_by_abi and symtab_used_from_object_file_p. (cgraph_make_node_local_1): Clear forced_by_abi. (cgraph_can_remove_if_no_direct_calls_and): Use forced_by_abi * cgraph.h (symtab_node_base): Add forced_by_abi. (decide_is_variable_needed): Remove. (varpool_can_remove_if_no_refs): Honnor symbol.forced_by_abi. * cgraphunit.c (cgraph_decide_is_function_needed): Rename to .. (decide_is_symbol_needed): ... this one; handle symbols in general; always analyze virtuals; honnor forced_by_abi. (cgraph_finalize_function): Update. (varpool_finalize_decl): Update. (symbol_defined_and_needed): Remove. (analyze_functions): Update. * lto-cgraph.c (lto_output_node, lto_output_varpool_node, output_refs, input_overwrite_node): Handle forced_by_abi. * ipa.c (cgraph_address_taken_from_non_vtable_p): Rename to ... (address_taken_from_non_vtable_p): ... this one. (comdat_can_be_unshared_p_1): New function. (cgraph_comdat_can_be_unshared_p): Rename to ... (comdat_can_be_unshared_p): ... this one; handle symbols in general. (varpool_externally_visible_p): Use comdat_can_be_unshared_p. (function_and_variable_visibility): Clear forced_by_abi as needed. * trans-mem.c (ipa_tm_mark_forced_by_abi_node): New functoin. (ipa_tm_create_version_alias, ipa_tm_create_version): Update. * varasm.c (mark_decl_referenced): Remove. * symtab.c (dump_symtab_base): Dump forced_by_abi. * varpool.c (decide_is_variable_needed): Remove. From-SVN: r199695
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r--gcc/ipa.c75
1 files changed, 56 insertions, 19 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 443d737..a73cbb1 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -519,7 +519,7 @@ ipa_discover_readonly_nonaddressable_vars (void)
/* Return true when there is a reference to node and it is not vtable. */
static bool
-cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
+address_taken_from_non_vtable_p (symtab_node node)
{
int i;
struct ipa_ref *ref;
@@ -537,6 +537,38 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
return false;
}
+/* A helper for comdat_can_be_unshared_p. */
+
+static bool
+comdat_can_be_unshared_p_1 (symtab_node node)
+{
+ /* When address is taken, we don't know if equality comparison won't
+ break eventaully. Exception are virutal functions and vtables, where
+ this is not possible by language standard. */
+ if (!DECL_VIRTUAL_P (node->symbol.decl)
+ && address_taken_from_non_vtable_p (node))
+ return false;
+
+ /* If the symbol is used in some weird way, better to not touch it. */
+ if (node->symbol.force_output)
+ return false;
+
+ /* Explicit instantiations needs to be output when possibly
+ used externally. */
+ if (node->symbol.forced_by_abi
+ && TREE_PUBLIC (node->symbol.decl)
+ && (node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
+ && !flag_whole_program))
+ return false;
+
+ /* Non-readonly and volatile variables can not be duplicated. */
+ if (is_a <varpool_node> (node)
+ && (!TREE_READONLY (node->symbol.decl)
+ || TREE_THIS_VOLATILE (node->symbol.decl)))
+ return false;
+ return true;
+}
+
/* COMDAT functions must be shared only if they have address taken,
otherwise we can produce our own private implementation with
-fwhole-program.
@@ -547,24 +579,21 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
but in C++ there is no way to compare their addresses for equality. */
static bool
-cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
+comdat_can_be_unshared_p (symtab_node node)
{
- if ((cgraph_address_taken_from_non_vtable_p (node)
- && !DECL_VIRTUAL_P (node->symbol.decl))
- || !node->symbol.definition)
+ if (!comdat_can_be_unshared_p_1 (node))
return false;
if (node->symbol.same_comdat_group)
{
- struct cgraph_node *next;
+ symtab_node next;
/* If more than one function is in the same COMDAT group, it must
be shared even if just one function in the comdat group has
address taken. */
- for (next = cgraph (node->symbol.same_comdat_group);
- next != node; next = cgraph (next->symbol.same_comdat_group))
- if (cgraph_address_taken_from_non_vtable_p (next)
- && !DECL_VIRTUAL_P (next->symbol.decl))
- return false;
+ for (next = node->symbol.same_comdat_group;
+ next != node; next = next->symbol.same_comdat_group)
+ if (!comdat_can_be_unshared_p_1 (next))
+ return false;
}
return true;
}
@@ -610,7 +639,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
implementing same COMDAT) */
if ((in_lto_p || whole_program)
&& DECL_COMDAT (node->symbol.decl)
- && cgraph_comdat_can_be_unshared_p (node))
+ && comdat_can_be_unshared_p ((symtab_node) node))
return false;
/* When doing link time optimizations, hidden symbols become local. */
@@ -680,8 +709,8 @@ varpool_externally_visible_p (struct varpool_node *vnode)
is faster for dynamic linking. Also this match logic hidding vtables
from LTO symbol tables. */
if ((in_lto_p || flag_whole_program)
- && !vnode->symbol.force_output
- && DECL_COMDAT (vnode->symbol.decl) && DECL_VIRTUAL_P (vnode->symbol.decl))
+ && DECL_COMDAT (vnode->symbol.decl)
+ && comdat_can_be_unshared_p ((symtab_node) vnode))
return false;
/* When doing link time optimizations, hidden symbols become local. */
@@ -743,9 +772,11 @@ function_and_variable_visibility (bool whole_program)
/* Frontends and alias code marks nodes as needed before parsing is finished.
We may end up marking as node external nodes where this flag is meaningless
strip it. */
- if (node->symbol.force_output
- && (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition))
- node->symbol.force_output = 0;
+ if (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition)
+ {
+ node->symbol.force_output = 0;
+ node->symbol.forced_by_abi = 0;
+ }
/* C++ FE on lack of COMDAT support create local COMDAT functions
(that ought to be shared but can not due to object format
@@ -780,7 +811,10 @@ function_and_variable_visibility (bool whole_program)
node->symbol.externally_visible = true;
}
else
- node->symbol.externally_visible = false;
+ {
+ node->symbol.externally_visible = false;
+ node->symbol.forced_by_abi = false;
+ }
if (!node->symbol.externally_visible && node->symbol.definition
&& !DECL_EXTERNAL (node->symbol.decl))
{
@@ -859,7 +893,10 @@ function_and_variable_visibility (bool whole_program)
if (varpool_externally_visible_p (vnode))
vnode->symbol.externally_visible = true;
else
- vnode->symbol.externally_visible = false;
+ {
+ vnode->symbol.externally_visible = false;
+ vnode->symbol.forced_by_abi = false;
+ }
if (!vnode->symbol.externally_visible)
{
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));