mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
9912dbe5c7
commit
edb983b2cb
|
|
@ -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>
|
2013-06-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
* config/arm/arm.c (MAX_INSN_PER_IT_BLOCK): New macro.
|
* config/arm/arm.c (MAX_INSN_PER_IT_BLOCK): New macro.
|
||||||
|
|
|
||||||
|
|
@ -1326,6 +1326,7 @@ cgraph_remove_node (struct cgraph_node *node)
|
||||||
/* Incremental inlining access removed nodes stored in the postorder list.
|
/* Incremental inlining access removed nodes stored in the postorder list.
|
||||||
*/
|
*/
|
||||||
node->symbol.force_output = false;
|
node->symbol.force_output = false;
|
||||||
|
node->symbol.forced_by_abi = false;
|
||||||
for (n = node->nested; n; n = n->next_nested)
|
for (n = node->nested; n; n = n->next_nested)
|
||||||
n->origin = NULL;
|
n->origin = NULL;
|
||||||
node->nested = NULL;
|
node->nested = NULL;
|
||||||
|
|
@ -1712,6 +1713,8 @@ cgraph_node_cannot_be_local_p_1 (struct cgraph_node *node,
|
||||||
{
|
{
|
||||||
return !(!node->symbol.force_output
|
return !(!node->symbol.force_output
|
||||||
&& ((DECL_COMDAT (node->symbol.decl)
|
&& ((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.same_comdat_group)
|
||||||
|| !node->symbol.externally_visible));
|
|| !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);
|
symtab_make_decl_local (node->symbol.decl);
|
||||||
|
|
||||||
node->symbol.externally_visible = false;
|
node->symbol.externally_visible = false;
|
||||||
|
node->symbol.forced_by_abi = false;
|
||||||
node->local.local = true;
|
node->local.local = true;
|
||||||
node->symbol.unique_name = (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
|
node->symbol.unique_name = (node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
|
||||||
|| node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
|
|| 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. */
|
/* Only COMDAT functions can be removed if externally visible. */
|
||||||
if (node->symbol.externally_visible
|
if (node->symbol.externally_visible
|
||||||
&& (!DECL_COMDAT (node->symbol.decl)
|
&& (!DECL_COMDAT (node->symbol.decl)
|
||||||
|
|| node->symbol.forced_by_abi
|
||||||
|| symtab_used_from_object_file_p ((symtab_node) node)))
|
|| symtab_used_from_object_file_p ((symtab_node) node)))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
10
gcc/cgraph.h
10
gcc/cgraph.h
|
|
@ -72,9 +72,13 @@ struct GTY(()) symtab_node_base
|
||||||
|
|
||||||
/* Set when function is visible by other units. */
|
/* Set when function is visible by other units. */
|
||||||
unsigned externally_visible : 1;
|
unsigned externally_visible : 1;
|
||||||
/* Needed variables might become dead by optimization. This flag
|
/* The symbol will be assumed to be used in an invisiable way (like
|
||||||
forces the variable to be output even if it appears dead otherwise. */
|
by an toplevel asm statement). */
|
||||||
unsigned force_output : 1;
|
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. */
|
/* True when the name is known to be unique and thus it does not need mangling. */
|
||||||
unsigned unique_name : 1;
|
unsigned unique_name : 1;
|
||||||
|
|
||||||
|
|
@ -775,7 +779,6 @@ void dump_varpool (FILE *);
|
||||||
void dump_varpool_node (FILE *, struct varpool_node *);
|
void dump_varpool_node (FILE *, struct varpool_node *);
|
||||||
|
|
||||||
void varpool_finalize_decl (tree);
|
void varpool_finalize_decl (tree);
|
||||||
bool decide_is_variable_needed (struct varpool_node *, tree);
|
|
||||||
enum availability cgraph_variable_initializer_availability (struct varpool_node *);
|
enum availability cgraph_variable_initializer_availability (struct varpool_node *);
|
||||||
void cgraph_make_node_local (struct cgraph_node *);
|
void cgraph_make_node_local (struct cgraph_node *);
|
||||||
bool cgraph_node_can_be_local_p (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 true;
|
||||||
return (!node->symbol.force_output && !node->symbol.used_from_other_partition
|
return (!node->symbol.force_output && !node->symbol.used_from_other_partition
|
||||||
&& ((DECL_COMDAT (node->symbol.decl)
|
&& ((DECL_COMDAT (node->symbol.decl)
|
||||||
|
&& !node->symbol.forced_by_abi
|
||||||
&& !symtab_used_from_object_file_p ((symtab_node) node))
|
&& !symtab_used_from_object_file_p ((symtab_node) node))
|
||||||
|| !node->symbol.externally_visible
|
|| !node->symbol.externally_visible
|
||||||
|| DECL_HAS_VALUE_EXPR_P (node->symbol.decl)));
|
|| DECL_HAS_VALUE_EXPR_P (node->symbol.decl)));
|
||||||
|
|
|
||||||
|
|
@ -216,36 +216,45 @@ static GTY(()) struct asm_node *asm_last_node;
|
||||||
/* Used for vtable lookup in thunk adjusting. */
|
/* Used for vtable lookup in thunk adjusting. */
|
||||||
static GTY (()) tree vtable_entry_type;
|
static GTY (()) tree vtable_entry_type;
|
||||||
|
|
||||||
/* Determine if function DECL is trivially needed and should stay in the
|
/* Determine if symbol DECL is needed. That is, visible to something
|
||||||
compilation unit. This is used at the symbol table construction time
|
either outside this translation unit, something magic in the system
|
||||||
and differs from later logic removing unnecessary functions that can
|
configury */
|
||||||
take into account results of analysis, whole program info etc. */
|
bool
|
||||||
|
decide_is_symbol_needed (symtab_node node)
|
||||||
static bool
|
|
||||||
cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
|
|
||||||
{
|
{
|
||||||
/* If the user told us it is used, then it must be so. */
|
tree decl = node->symbol.decl;
|
||||||
if (node->symbol.force_output)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Double check that no one output the function into assembly file
|
/* Double check that no one output the function into assembly file
|
||||||
early. */
|
early. */
|
||||||
gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
|
gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
|
||||||
|| !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
|
|| !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
|
||||||
|
|
||||||
|
if (!node->symbol.definition)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Keep constructors, destructors and virtual functions. */
|
/* Devirtualization may access these. */
|
||||||
if (DECL_STATIC_CONSTRUCTOR (decl)
|
if (DECL_VIRTUAL_P (decl) && optimize)
|
||||||
|| DECL_STATIC_DESTRUCTOR (decl)
|
return true;
|
||||||
|| (DECL_VIRTUAL_P (decl)
|
|
||||||
&& optimize && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl))))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Externally visible functions must be output. The exception is
|
if (DECL_EXTERNAL (decl))
|
||||||
COMDAT functions that must be output only when they are needed. */
|
return false;
|
||||||
|
|
||||||
if (TREE_PUBLIC (decl)
|
/* If the user told us it is used, then it must be so. */
|
||||||
&& !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
|
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 true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -447,7 +456,7 @@ cgraph_finalize_function (tree decl, bool nested)
|
||||||
ggc_collect ();
|
ggc_collect ();
|
||||||
|
|
||||||
if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
|
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)))
|
|| referred_to_p ((symtab_node)node)))
|
||||||
enqueue_node ((symtab_node)node);
|
enqueue_node ((symtab_node)node);
|
||||||
}
|
}
|
||||||
|
|
@ -801,7 +810,7 @@ varpool_finalize_decl (tree decl)
|
||||||
node->symbol.force_output = true;
|
node->symbol.force_output = true;
|
||||||
|
|
||||||
if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
|
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)))
|
|| referred_to_p ((symtab_node)node)))
|
||||||
enqueue_node ((symtab_node)node);
|
enqueue_node ((symtab_node)node);
|
||||||
if (cgraph_state >= CGRAPH_STATE_IPA_SSA)
|
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
|
/* Discover all functions and variables that are trivially needed, analyze
|
||||||
them as well as all functions and variables referred by them */
|
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
|
||||||
&& node != (symtab_node)first_analyzed_var; node = node->symbol.next)
|
&& 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);
|
enqueue_node (node);
|
||||||
if (!changed && cgraph_dump_file)
|
if (!changed && cgraph_dump_file)
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2013-06-03 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
* class.c (mark_type_abi_tags): New.
|
* class.c (mark_type_abi_tags): New.
|
||||||
|
|
|
||||||
|
|
@ -1703,9 +1703,10 @@ maybe_make_one_only (tree decl)
|
||||||
|
|
||||||
if (VAR_P (decl))
|
if (VAR_P (decl))
|
||||||
{
|
{
|
||||||
|
struct varpool_node *node = varpool_node_for_decl (decl);
|
||||||
DECL_COMDAT (decl) = 1;
|
DECL_COMDAT (decl) = 1;
|
||||||
/* Mark it needed so we don't forget to emit it. */
|
/* 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;
|
TREE_USED (decl) = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1813,7 +1814,22 @@ void
|
||||||
mark_needed (tree decl)
|
mark_needed (tree decl)
|
||||||
{
|
{
|
||||||
TREE_USED (decl) = 1;
|
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
|
/* DECL is either a FUNCTION_DECL or a VAR_DECL. This function
|
||||||
|
|
|
||||||
75
gcc/ipa.c
75
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. */
|
/* Return true when there is a reference to node and it is not vtable. */
|
||||||
static bool
|
static bool
|
||||||
cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
|
address_taken_from_non_vtable_p (symtab_node node)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct ipa_ref *ref;
|
struct ipa_ref *ref;
|
||||||
|
|
@ -537,6 +537,38 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
|
||||||
return false;
|
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,
|
/* COMDAT functions must be shared only if they have address taken,
|
||||||
otherwise we can produce our own private implementation with
|
otherwise we can produce our own private implementation with
|
||||||
-fwhole-program.
|
-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. */
|
but in C++ there is no way to compare their addresses for equality. */
|
||||||
|
|
||||||
static bool
|
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)
|
if (!comdat_can_be_unshared_p_1 (node))
|
||||||
&& !DECL_VIRTUAL_P (node->symbol.decl))
|
|
||||||
|| !node->symbol.definition)
|
|
||||||
return false;
|
return false;
|
||||||
if (node->symbol.same_comdat_group)
|
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
|
/* 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
|
be shared even if just one function in the comdat group has
|
||||||
address taken. */
|
address taken. */
|
||||||
for (next = cgraph (node->symbol.same_comdat_group);
|
for (next = node->symbol.same_comdat_group;
|
||||||
next != node; next = cgraph (next->symbol.same_comdat_group))
|
next != node; next = next->symbol.same_comdat_group)
|
||||||
if (cgraph_address_taken_from_non_vtable_p (next)
|
if (!comdat_can_be_unshared_p_1 (next))
|
||||||
&& !DECL_VIRTUAL_P (next->symbol.decl))
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +639,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
|
||||||
implementing same COMDAT) */
|
implementing same COMDAT) */
|
||||||
if ((in_lto_p || whole_program)
|
if ((in_lto_p || whole_program)
|
||||||
&& DECL_COMDAT (node->symbol.decl)
|
&& DECL_COMDAT (node->symbol.decl)
|
||||||
&& cgraph_comdat_can_be_unshared_p (node))
|
&& comdat_can_be_unshared_p ((symtab_node) node))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* When doing link time optimizations, hidden symbols become local. */
|
/* 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
|
is faster for dynamic linking. Also this match logic hidding vtables
|
||||||
from LTO symbol tables. */
|
from LTO symbol tables. */
|
||||||
if ((in_lto_p || flag_whole_program)
|
if ((in_lto_p || flag_whole_program)
|
||||||
&& !vnode->symbol.force_output
|
&& DECL_COMDAT (vnode->symbol.decl)
|
||||||
&& DECL_COMDAT (vnode->symbol.decl) && DECL_VIRTUAL_P (vnode->symbol.decl))
|
&& comdat_can_be_unshared_p ((symtab_node) vnode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* When doing link time optimizations, hidden symbols become local. */
|
/* 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.
|
/* 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
|
We may end up marking as node external nodes where this flag is meaningless
|
||||||
strip it. */
|
strip it. */
|
||||||
if (node->symbol.force_output
|
if (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition)
|
||||||
&& (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition))
|
{
|
||||||
node->symbol.force_output = 0;
|
node->symbol.force_output = 0;
|
||||||
|
node->symbol.forced_by_abi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* C++ FE on lack of COMDAT support create local COMDAT functions
|
/* C++ FE on lack of COMDAT support create local COMDAT functions
|
||||||
(that ought to be shared but can not due to object format
|
(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;
|
node->symbol.externally_visible = true;
|
||||||
}
|
}
|
||||||
else
|
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
|
if (!node->symbol.externally_visible && node->symbol.definition
|
||||||
&& !DECL_EXTERNAL (node->symbol.decl))
|
&& !DECL_EXTERNAL (node->symbol.decl))
|
||||||
{
|
{
|
||||||
|
|
@ -859,7 +893,10 @@ function_and_variable_visibility (bool whole_program)
|
||||||
if (varpool_externally_visible_p (vnode))
|
if (varpool_externally_visible_p (vnode))
|
||||||
vnode->symbol.externally_visible = true;
|
vnode->symbol.externally_visible = true;
|
||||||
else
|
else
|
||||||
vnode->symbol.externally_visible = false;
|
{
|
||||||
|
vnode->symbol.externally_visible = false;
|
||||||
|
vnode->symbol.forced_by_abi = false;
|
||||||
|
}
|
||||||
if (!vnode->symbol.externally_visible)
|
if (!vnode->symbol.externally_visible)
|
||||||
{
|
{
|
||||||
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
|
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2013-05-29 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* decl.c (java_mark_decl_local): Update for new symtab flags.
|
* decl.c (java_mark_decl_local): Update for new symtab flags.
|
||||||
|
|
|
||||||
|
|
@ -2814,10 +2814,10 @@ emit_register_classes_in_jcr_section (void)
|
||||||
TREE_CONSTANT (cdecl) = 1;
|
TREE_CONSTANT (cdecl) = 1;
|
||||||
DECL_ARTIFICIAL (cdecl) = 1;
|
DECL_ARTIFICIAL (cdecl) = 1;
|
||||||
DECL_IGNORED_P (cdecl) = 1;
|
DECL_IGNORED_P (cdecl) = 1;
|
||||||
|
DECL_PRESERVE_P (cdecl) = 1;
|
||||||
pushdecl_top_level (cdecl);
|
pushdecl_top_level (cdecl);
|
||||||
relayout_decl (cdecl);
|
relayout_decl (cdecl);
|
||||||
rest_of_decl_compilation (cdecl, 1, 0);
|
rest_of_decl_compilation (cdecl, 1, 0);
|
||||||
mark_decl_referenced (cdecl);
|
|
||||||
#else
|
#else
|
||||||
/* A target has defined TARGET_USE_JCR_SECTION,
|
/* A target has defined TARGET_USE_JCR_SECTION,
|
||||||
but doesn't have a JCR_SECTION_NAME. */
|
but doesn't have a JCR_SECTION_NAME. */
|
||||||
|
|
|
||||||
|
|
@ -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.can_change_signature, 1);
|
||||||
bp_pack_value (&bp, node->local.redefined_extern_inline, 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.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.unique_name, 1);
|
||||||
bp_pack_value (&bp, node->symbol.address_taken, 1);
|
bp_pack_value (&bp, node->symbol.address_taken, 1);
|
||||||
bp_pack_value (&bp, node->abstract_and_needed, 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 = bitpack_create (ob->main_stream);
|
||||||
bp_pack_value (&bp, node->symbol.externally_visible, 1);
|
bp_pack_value (&bp, node->symbol.externally_visible, 1);
|
||||||
bp_pack_value (&bp, node->symbol.force_output, 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.unique_name, 1);
|
||||||
bp_pack_value (&bp, node->symbol.definition, 1);
|
bp_pack_value (&bp, node->symbol.definition, 1);
|
||||||
alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
|
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);
|
count = ipa_ref_list_nreferences (&node->symbol.ref_list);
|
||||||
if (count)
|
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,
|
streamer_write_uhwi_stream (ob->main_stream,
|
||||||
lto_symtab_encoder_lookup (encoder, node));
|
lto_symtab_encoder_lookup (encoder, node));
|
||||||
for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list,
|
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.can_change_signature = bp_unpack_value (bp, 1);
|
||||||
node->local.redefined_extern_inline = 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.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.unique_name = bp_unpack_value (bp, 1);
|
||||||
node->symbol.address_taken = bp_unpack_value (bp, 1);
|
node->symbol.address_taken = bp_unpack_value (bp, 1);
|
||||||
node->abstract_and_needed = 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);
|
bp = streamer_read_bitpack (ib);
|
||||||
node->symbol.externally_visible = bp_unpack_value (&bp, 1);
|
node->symbol.externally_visible = bp_unpack_value (&bp, 1);
|
||||||
node->symbol.force_output = 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.unique_name = bp_unpack_value (&bp, 1);
|
||||||
node->symbol.definition = bp_unpack_value (&bp, 1);
|
node->symbol.definition = bp_unpack_value (&bp, 1);
|
||||||
node->symbol.alias = bp_unpack_value (&bp, 1);
|
node->symbol.alias = bp_unpack_value (&bp, 1);
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,8 @@ dump_symtab_base (FILE *f, symtab_node node)
|
||||||
fprintf (f, " used_from_other_partition");
|
fprintf (f, " used_from_other_partition");
|
||||||
if (node->symbol.force_output)
|
if (node->symbol.force_output)
|
||||||
fprintf (f, " force_output");
|
fprintf (f, " force_output");
|
||||||
|
if (node->symbol.forced_by_abi)
|
||||||
|
fprintf (f, " forced_by_abi");
|
||||||
if (node->symbol.resolution != LDPR_UNKNOWN)
|
if (node->symbol.resolution != LDPR_UNKNOWN)
|
||||||
fprintf (f, " %s",
|
fprintf (f, " %s",
|
||||||
ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]);
|
ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]);
|
||||||
|
|
|
||||||
|
|
@ -4681,6 +4681,13 @@ ipa_tm_mark_force_output_node (struct cgraph_node *node)
|
||||||
node->symbol.analyzed = true;
|
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. */
|
/* Callback data for ipa_tm_create_version_alias. */
|
||||||
struct create_version_alias_info
|
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
|
if (info->old_node->symbol.force_output
|
||||||
|| ipa_ref_list_first_referring (&info->old_node->symbol.ref_list))
|
|| ipa_ref_list_first_referring (&info->old_node->symbol.ref_list))
|
||||||
ipa_tm_mark_force_output_node (new_node);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4792,6 +4801,8 @@ ipa_tm_create_version (struct cgraph_node *old_node)
|
||||||
if (old_node->symbol.force_output
|
if (old_node->symbol.force_output
|
||||||
|| ipa_ref_list_first_referring (&old_node->symbol.ref_list))
|
|| ipa_ref_list_first_referring (&old_node->symbol.ref_list))
|
||||||
ipa_tm_mark_force_output_node (new_node);
|
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. */
|
/* Do the same thing, but for any aliases of the original node. */
|
||||||
{
|
{
|
||||||
|
|
|
||||||
27
gcc/varasm.c
27
gcc/varasm.c
|
|
@ -2244,33 +2244,6 @@ mark_referenced (tree id)
|
||||||
TREE_SYMBOL_REFERENCED (id) = 1;
|
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
|
/* Follow the IDENTIFIER_TRANSPARENT_ALIAS chain starting at *ALIAS
|
||||||
until we find an identifier that is not itself a transparent 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
|
Modify the alias passed to it by reference (and all aliases on the
|
||||||
|
|
|
||||||
|
|
@ -130,28 +130,6 @@ varpool_node_for_asm (tree asmname)
|
||||||
return NULL;
|
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
|
/* Return if DECL is constant and its initial value is known (so we can do
|
||||||
constant folding using DECL_INITIAL (decl)). */
|
constant folding using DECL_INITIAL (decl)). */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue