Commit edb983b2 by Jan Hubicka Committed by Jan Hubicka

class.c (emit_register_classes_in_jcr_section): Use DECL_PRESERVE_P instead of…

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
parent 9912dbe5
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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -72,9 +72,13 @@ struct GTY(()) symtab_node_base ...@@ -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 *); ...@@ -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) ...@@ -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; ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)
......
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) ...@@ -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 ...@@ -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
......
...@@ -519,7 +519,7 @@ ipa_discover_readonly_nonaddressable_vars (void) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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));
......
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) ...@@ -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, ...@@ -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 ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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. */
{ {
......
...@@ -2244,33 +2244,6 @@ mark_referenced (tree id) ...@@ -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) ...@@ -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)). */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment