diff options
author | Jan Hubicka <jh@suse.cz> | 2013-06-05 16:15:31 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-06-05 14:15:31 +0000 |
commit | edb983b2cb3961d9a5fa45444ff0fbf16e3adc0a (patch) | |
tree | a3982caf99872c7045fe2746bb44f9b7a2a178ac /gcc/ipa.c | |
parent | 9912dbe5c7d8c715d6506380ef62a3377297f4b4 (diff) | |
download | gcc-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.c | 75 |
1 files changed, 56 insertions, 19 deletions
@@ -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)); |