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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 32 | ||||
-rw-r--r-- | gcc/cgraph.c | 5 | ||||
-rw-r--r-- | gcc/cgraph.h | 10 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 70 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 20 | ||||
-rw-r--r-- | gcc/ipa.c | 75 | ||||
-rw-r--r-- | gcc/java/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/java/class.c | 2 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 6 | ||||
-rw-r--r-- | gcc/symtab.c | 2 | ||||
-rw-r--r-- | gcc/trans-mem.c | 11 | ||||
-rw-r--r-- | gcc/varasm.c | 27 | ||||
-rw-r--r-- | gcc/varpool.c | 22 |
14 files changed, 180 insertions, 113 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 391a529..154f0f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2013-06-05 Jan Hubicka <jh@suse.cz> + + * 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. + 2013-06-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * config/arm/arm.c (MAX_INSN_PER_IT_BLOCK): New macro. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 445282a..7bcff20 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1326,6 +1326,7 @@ cgraph_remove_node (struct cgraph_node *node) /* Incremental inlining access removed nodes stored in the postorder list. */ node->symbol.force_output = false; + node->symbol.forced_by_abi = false; for (n = node->nested; n; n = n->next_nested) n->origin = NULL; node->nested = NULL; @@ -1712,6 +1713,8 @@ cgraph_node_cannot_be_local_p_1 (struct cgraph_node *node, { return !(!node->symbol.force_output && ((DECL_COMDAT (node->symbol.decl) + && !node->symbol.forced_by_abi + && !symtab_used_from_object_file_p ((symtab_node) node) && !node->symbol.same_comdat_group) || !node->symbol.externally_visible)); } @@ -1804,6 +1807,7 @@ cgraph_make_node_local_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) symtab_make_decl_local (node->symbol.decl); node->symbol.externally_visible = false; + node->symbol.forced_by_abi = false; node->local.local = true; node->symbol.unique_name = (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP); @@ -2085,6 +2089,7 @@ cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node) /* Only COMDAT functions can be removed if externally visible. */ if (node->symbol.externally_visible && (!DECL_COMDAT (node->symbol.decl) + || node->symbol.forced_by_abi || symtab_used_from_object_file_p ((symtab_node) node))) return false; return true; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 276e568..dda4402 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -72,9 +72,13 @@ struct GTY(()) symtab_node_base /* Set when function is visible by other units. */ unsigned externally_visible : 1; - /* Needed variables might become dead by optimization. This flag - forces the variable to be output even if it appears dead otherwise. */ + /* The symbol will be assumed to be used in an invisiable way (like + by an toplevel asm statement). */ unsigned force_output : 1; + /* Like FORCE_OUTPUT, but in the case it is ABI requiring the symbol to be + exported. Unlike FORCE_OUTPUT this flag gets cleared to symbols promoted + to static and it does not inhibit optimization. */ + unsigned forced_by_abi : 1; /* True when the name is known to be unique and thus it does not need mangling. */ unsigned unique_name : 1; @@ -775,7 +779,6 @@ void dump_varpool (FILE *); void dump_varpool_node (FILE *, struct varpool_node *); void varpool_finalize_decl (tree); -bool decide_is_variable_needed (struct varpool_node *, tree); enum availability cgraph_variable_initializer_availability (struct varpool_node *); void cgraph_make_node_local (struct cgraph_node *); bool cgraph_node_can_be_local_p (struct cgraph_node *); @@ -1216,6 +1219,7 @@ varpool_can_remove_if_no_refs (struct varpool_node *node) return true; return (!node->symbol.force_output && !node->symbol.used_from_other_partition && ((DECL_COMDAT (node->symbol.decl) + && !node->symbol.forced_by_abi && !symtab_used_from_object_file_p ((symtab_node) node)) || !node->symbol.externally_visible || DECL_HAS_VALUE_EXPR_P (node->symbol.decl))); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 9a4d0df..044bdf7 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -216,36 +216,45 @@ static GTY(()) struct asm_node *asm_last_node; /* Used for vtable lookup in thunk adjusting. */ static GTY (()) tree vtable_entry_type; -/* Determine if function DECL is trivially needed and should stay in the - compilation unit. This is used at the symbol table construction time - and differs from later logic removing unnecessary functions that can - take into account results of analysis, whole program info etc. */ - -static bool -cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl) +/* Determine if symbol DECL is needed. That is, visible to something + either outside this translation unit, something magic in the system + configury */ +bool +decide_is_symbol_needed (symtab_node node) { - /* If the user told us it is used, then it must be so. */ - if (node->symbol.force_output) - return true; + tree decl = node->symbol.decl; /* Double check that no one output the function into assembly file early. */ gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl) || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))); + if (!node->symbol.definition) + return false; - /* Keep constructors, destructors and virtual functions. */ - if (DECL_STATIC_CONSTRUCTOR (decl) - || DECL_STATIC_DESTRUCTOR (decl) - || (DECL_VIRTUAL_P (decl) - && optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl)))) - return true; + /* Devirtualization may access these. */ + if (DECL_VIRTUAL_P (decl) && optimize) + return true; - /* Externally visible functions must be output. The exception is - COMDAT functions that must be output only when they are needed. */ + if (DECL_EXTERNAL (decl)) + return false; - if (TREE_PUBLIC (decl) - && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) + /* If the user told us it is used, then it must be so. */ + if (node->symbol.force_output) + return true; + + /* ABI forced symbols are needed when they are external. */ + if (node->symbol.forced_by_abi && TREE_PUBLIC (decl)) + return true; + + /* Keep constructors, destructors and virtual functions. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))) + return true; + + /* Externally visible variables must be output. The exception is + COMDAT variables that must be output only when they are needed. */ + if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) return true; return false; @@ -447,7 +456,7 @@ cgraph_finalize_function (tree decl, bool nested) ggc_collect (); if (cgraph_state == CGRAPH_STATE_CONSTRUCTION - && (cgraph_decide_is_function_needed (node, decl) + && (decide_is_symbol_needed ((symtab_node) node) || referred_to_p ((symtab_node)node))) enqueue_node ((symtab_node)node); } @@ -801,7 +810,7 @@ varpool_finalize_decl (tree decl) node->symbol.force_output = true; if (cgraph_state == CGRAPH_STATE_CONSTRUCTION - && (decide_is_variable_needed (node, decl) + && (decide_is_symbol_needed ((symtab_node) node) || referred_to_p ((symtab_node)node))) enqueue_node ((symtab_node)node); if (cgraph_state >= CGRAPH_STATE_IPA_SSA) @@ -813,21 +822,6 @@ varpool_finalize_decl (tree decl) } -/* Determine if a symbol NODE is finalized and needed. */ - -inline static bool -symbol_defined_and_needed (symtab_node node) -{ - if (cgraph_node *cnode = dyn_cast <cgraph_node> (node)) - return cnode->symbol.definition - && cgraph_decide_is_function_needed (cnode, cnode->symbol.decl); - if (varpool_node *vnode = dyn_cast <varpool_node> (node)) - return vnode->symbol.definition - && !DECL_EXTERNAL (vnode->symbol.decl) - && decide_is_variable_needed (vnode, vnode->symbol.decl); - return false; -} - /* Discover all functions and variables that are trivially needed, analyze them as well as all functions and variables referred by them */ @@ -869,7 +863,7 @@ analyze_functions (void) node != (symtab_node)first_analyzed && node != (symtab_node)first_analyzed_var; node = node->symbol.next) { - if (symbol_defined_and_needed (node)) + if (decide_is_symbol_needed (node)) { enqueue_node (node); if (!changed && cgraph_dump_file) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cb721ec..4698a18 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-06-03 Jan Hubicka <jh@suse.cz> + + * decl2.c (maybe_make_one_only): Use forced_by_abi instad of + mark_decl_referenced. + (mark_needed): Likewise. + 2013-06-03 Jason Merrill <jason@redhat.com> * class.c (mark_type_abi_tags): New. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5e7dbcd..373f883 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1703,9 +1703,10 @@ maybe_make_one_only (tree decl) if (VAR_P (decl)) { + struct varpool_node *node = varpool_node_for_decl (decl); DECL_COMDAT (decl) = 1; /* Mark it needed so we don't forget to emit it. */ - mark_decl_referenced (decl); + node->symbol.forced_by_abi = true; TREE_USED (decl) = 1; } } @@ -1813,7 +1814,22 @@ void mark_needed (tree decl) { TREE_USED (decl) = 1; - mark_decl_referenced (decl); + if (TREE_CODE (decl) == FUNCTION_DECL) + { + /* Extern inline functions don't become needed when referenced. + If we know a method will be emitted in other TU and no new + functions can be marked reachable, just use the external + definition. */ + struct cgraph_node *node = cgraph_get_create_node (decl); + node->symbol.forced_by_abi = true; + } + else if (TREE_CODE (decl) == VAR_DECL) + { + struct varpool_node *node = varpool_node_for_decl (decl); + /* C++ frontend use mark_decl_references to force COMDAT variables + to be output that might appear dead otherwise. */ + node->symbol.forced_by_abi = true; + } } /* DECL is either a FUNCTION_DECL or a VAR_DECL. This function @@ -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)); diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 82cc49f..9cc34c5 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2013-06-05 Jan Hubicka <jh@suse.cz> + + * class.c (emit_register_classes_in_jcr_section): Use DECL_PRESERVE_P + instead of mark_decl_referenced. + 2013-05-29 Jan Hubicka <jh@suse.cz> * decl.c (java_mark_decl_local): Update for new symtab flags. diff --git a/gcc/java/class.c b/gcc/java/class.c index 30679f7..cb67896 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -2814,10 +2814,10 @@ emit_register_classes_in_jcr_section (void) TREE_CONSTANT (cdecl) = 1; DECL_ARTIFICIAL (cdecl) = 1; DECL_IGNORED_P (cdecl) = 1; + DECL_PRESERVE_P (cdecl) = 1; pushdecl_top_level (cdecl); relayout_decl (cdecl); rest_of_decl_compilation (cdecl, 1, 0); - mark_decl_referenced (cdecl); #else /* A target has defined TARGET_USE_JCR_SECTION, but doesn't have a JCR_SECTION_NAME. */ diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 065d848..bc9e5cd 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -469,6 +469,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_value (&bp, node->local.can_change_signature, 1); bp_pack_value (&bp, node->local.redefined_extern_inline, 1); bp_pack_value (&bp, node->symbol.force_output, 1); + bp_pack_value (&bp, node->symbol.forced_by_abi, 1); bp_pack_value (&bp, node->symbol.unique_name, 1); bp_pack_value (&bp, node->symbol.address_taken, 1); bp_pack_value (&bp, node->abstract_and_needed, 1); @@ -527,6 +528,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node bp = bitpack_create (ob->main_stream); bp_pack_value (&bp, node->symbol.externally_visible, 1); bp_pack_value (&bp, node->symbol.force_output, 1); + bp_pack_value (&bp, node->symbol.forced_by_abi, 1); bp_pack_value (&bp, node->symbol.unique_name, 1); bp_pack_value (&bp, node->symbol.definition, 1); alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)); @@ -672,7 +674,7 @@ output_refs (lto_symtab_encoder_t encoder) count = ipa_ref_list_nreferences (&node->symbol.ref_list); if (count) { - streamer_write_uhwi_stream (ob->main_stream, count); + streamer_write_gcov_count_stream (ob->main_stream, count); streamer_write_uhwi_stream (ob->main_stream, lto_symtab_encoder_lookup (encoder, node)); for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, @@ -881,6 +883,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data, node->local.can_change_signature = bp_unpack_value (bp, 1); node->local.redefined_extern_inline = bp_unpack_value (bp, 1); node->symbol.force_output = bp_unpack_value (bp, 1); + node->symbol.forced_by_abi = bp_unpack_value (bp, 1); node->symbol.unique_name = bp_unpack_value (bp, 1); node->symbol.address_taken = bp_unpack_value (bp, 1); node->abstract_and_needed = bp_unpack_value (bp, 1); @@ -1039,6 +1042,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, bp = streamer_read_bitpack (ib); node->symbol.externally_visible = bp_unpack_value (&bp, 1); node->symbol.force_output = bp_unpack_value (&bp, 1); + node->symbol.forced_by_abi = bp_unpack_value (&bp, 1); node->symbol.unique_name = bp_unpack_value (&bp, 1); node->symbol.definition = bp_unpack_value (&bp, 1); node->symbol.alias = bp_unpack_value (&bp, 1); diff --git a/gcc/symtab.c b/gcc/symtab.c index 02d3da1..f035541 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -496,6 +496,8 @@ dump_symtab_base (FILE *f, symtab_node node) fprintf (f, " used_from_other_partition"); if (node->symbol.force_output) fprintf (f, " force_output"); + if (node->symbol.forced_by_abi) + fprintf (f, " forced_by_abi"); if (node->symbol.resolution != LDPR_UNKNOWN) fprintf (f, " %s", ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]); diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 03aba75..6289ea4 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -4681,6 +4681,13 @@ ipa_tm_mark_force_output_node (struct cgraph_node *node) node->symbol.analyzed = true; } +static inline void +ipa_tm_mark_forced_by_abi_node (struct cgraph_node *node) +{ + node->symbol.forced_by_abi = true; + node->symbol.analyzed = true; +} + /* Callback data for ipa_tm_create_version_alias. */ struct create_version_alias_info { @@ -4737,6 +4744,8 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data) if (info->old_node->symbol.force_output || ipa_ref_list_first_referring (&info->old_node->symbol.ref_list)) ipa_tm_mark_force_output_node (new_node); + if (info->old_node->symbol.forced_by_abi) + ipa_tm_mark_forced_by_abi_node (new_node); return false; } @@ -4792,6 +4801,8 @@ ipa_tm_create_version (struct cgraph_node *old_node) if (old_node->symbol.force_output || ipa_ref_list_first_referring (&old_node->symbol.ref_list)) ipa_tm_mark_force_output_node (new_node); + if (old_node->symbol.forced_by_abi) + ipa_tm_mark_forced_by_abi_node (new_node); /* Do the same thing, but for any aliases of the original node. */ { diff --git a/gcc/varasm.c b/gcc/varasm.c index c088ebf..4c4178f 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2244,33 +2244,6 @@ mark_referenced (tree id) TREE_SYMBOL_REFERENCED (id) = 1; } -/* Set the symbol_referenced flag for DECL and notify callgraph. */ -void -mark_decl_referenced (tree decl) -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* Extern inline functions don't become needed when referenced. - If we know a method will be emitted in other TU and no new - functions can be marked reachable, just use the external - definition. */ - struct cgraph_node *node = cgraph_get_create_node (decl); - if (!DECL_EXTERNAL (decl) - && !node->symbol.definition) - cgraph_mark_force_output_node (node); - } - else if (TREE_CODE (decl) == VAR_DECL) - { - struct varpool_node *node = varpool_node_for_decl (decl); - /* C++ frontend use mark_decl_references to force COMDAT variables - to be output that might appear dead otherwise. */ - node->symbol.force_output = true; - } - /* else do nothing - we can get various sorts of CST nodes here, - which do not need to be marked. */ -} - - /* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at *ALIAS until we find an identifier that is not itself a transparent alias. Modify the alias passed to it by reference (and all aliases on the diff --git a/gcc/varpool.c b/gcc/varpool.c index 7915a95..a3e9325 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -130,28 +130,6 @@ varpool_node_for_asm (tree asmname) return NULL; } -/* Determine if variable DECL is needed. That is, visible to something - either outside this translation unit, something magic in the system - configury */ -bool -decide_is_variable_needed (struct varpool_node *node, tree decl) -{ - if (DECL_EXTERNAL (decl)) - return false; - - /* If the user told us it is used, then it must be so. */ - if (node->symbol.force_output) - return true; - - /* Externally visible variables must be output. The exception is - COMDAT variables that must be output only when they are needed. */ - if (TREE_PUBLIC (decl) - && !DECL_COMDAT (decl)) - return true; - - return false; -} - /* Return if DECL is constant and its initial value is known (so we can do constant folding using DECL_INITIAL (decl)). */ |