mirror of git://gcc.gnu.org/git/gcc.git
cgraph.h (symtab_node_base): Add definition, alias and analyzed flags...
* cgraph.h (symtab_node_base): Add definition, alias and analyzed flags; reorder rest of fields in more consistent way. (varpool_node): Remove analyzed, finalized and alias. (cgraph_ndoe): Likewise. (symtab_alias_ultimate_target): New function. (cgraph_function_node): Move offline. (cgraph_reset_node): Declare. (cgraph_comdat_can_be_unshared_p): Remove. (varpool_remove_initializer): Declare. (varpool_first_defined_variable, varpool_next_defined_variable cgraph_first_defined_function, cgraph_next_defined_function): Update. (cgraph_function_with_gimple_body_p): Update. (varpool_all_refs_explicit_p): Update. (symtab_alias_target): New function. (cgraph_alias_aliased_node, varpool_alias_aliased_node): Rename to ... (cgraph_alias_target, varpool_alias_target): .. this one; simplify. (cgraph_function_or_thunk_node): Simplify using symtab_alias_ultimate_target. (varpool_variable_node): Likewise. * cgraph.c (cgraph_create_function_alias): Update. (cgraph_add_thunk): Update. (cgraph_remove_node): Update. (dump_cgraph_node): Do not dump removed flags. (cgraph_function_body_availability): Update. (cgraph_propagate_frequency): Update. (verify_cgraph_node): Check sanity of local flag. (cgraph_function_node): Move here from cgraph.h; revamp for cgraph_function_or_thunk_node. * lto-symtab.c (lto_varpool_replace_node): Update. (lto_symtab_resolve_can_prevail_p): Update. (lto_symtab_merge_cgraph_nodes): Update. * ipa-cp.c (determine_versionability, initialize_node_lattices, propagate_constants_accross_call, devirtualization_time_bonus, ipcp_propagate_stage): Update. * tree-emutls.c (create_emultls_var, ipa_lower_emutls): Update. * ipa-inline-transform.c (clone_inlined_nodes, preserve_function_body_p): Update. * ipa-reference.c (propagate): Update. (write_node_summary_p): Update. * toplev.c (wrapup_global_declaration_2): Update. * cgraphunit.c (cgraph_analyze_function): Rename to ... (analyze_function) ... this one. (cgraph_process_new_functions): Update. (cgraph_reset_node): Export. (cgraph_finalize_function): Update. (cgraph_add_new_function): Update. (process_function_and_variable_attributes): Update. (varpool_finalize_decl): Update. (symbol_finalized): Remove. (symbol_finalized_and_needed): Rename to ... (symbol_defined_and_needed): ... update. (cgraph_analyze_functions): Update. (handle_alias_pairs): Update. (mark_functions_to_output): Update. (assemble_thunk): Update. (output_in_order): Update. (output_weakrefs): Update. (finalize_compilation_unit): Update. * lto-cgraph.c (reachable_from_other_partition_p, lto_output_node, lto_output_varpool_node, compute_ltrans_boundary, input_overwrite_node, input_node, input_varpool_node): Update. * dbxout.c (dbxout_expand_expr): Update. * cgraphclones.c (cgraph_clone_node): Update. (cgraph_copy_node_for_versioning): Update. (cgraph_materialize_clone): Update. (cgraph_materialize_all_clones): Update. * ipa-pure-const.c (analyze_function, pure_const_write_summary, propagate_pure_const, propagate_nothrow): Update. * lto-streamer-out.c (lto_output, write_symbol): Update. * ipa-utils.c (ipa_reverse_postorder): Update. * ipa-inline.c (can_inline_edge_p): Update. (update_caller_keys, ipa_inline): Update. * dwarf2out.c (reference_to_unused, premark_types_used_by_global_vars_helper): Update. * tree-eh.c (tree_could_trap_p): Update. * ipa-split.c (consider_split, execute_split_functions): Update. * ipa.c (cgraph_non_local_node_p_1, cgraph_local_node_p, has_addr_references_p): Update; move ahead in file for better readability. (process_references): Simplify. (symtab_remove_unreachable_nodes): Update; cleanup way function/var bodies are removed. (cgraph_comdat_can_be_unshared_p): Make static. (cgraph_externally_visible_p): Update. (varpool_externally_visible_p): Update. (function_and_variable_visibility): Update. * trans-mem.c (get_cg_data, ipa_tm_mayenterirr_function, ipa_tm_mark_force_output_node): Update. * ipa-inline-analysis.c (dump_inline_summary, initialize_inline_failed, estimate_edge_devirt_benefit, inline_generate_summary, inline_write_summary): Update. * gimple-fold.c (can_refer_decl_in_current_unit_p): Update. * ipa-prop.c (ipa_compute_jump_functions): Update. (ipa_print_node_params, ipa_prop_read_section, ipa_update_after_lto_read, read_replacements_section): Update. * varasm.c (mark_decl_referenced): Update. (assemble_alias, dump_tm_clone_pairs): Update. * tree-inline.c (copy_bb): Update. (estimate_num_insns, optimize_inline_calls, tree_function_versioning): Update. * symtab.c (dump_symtab_base): Print new flags. (verify_symtab_base): Verify new flags. (symtab_alias_ultimate_target): New function. * tree-ssa-structalias.c (get_constraint_for_ssa_var, create_variable_info_for, associate_varinfo_to_alias, ipa_pta_execute): Update. * passes.c (ipa_write_summaries, ipa_write_optimization_summaries): Update. * i386.c (ix86_get_function_versions_dispatcher, ix86_generate_version_dispatcher_body): Update. (fold_builtin_cpu): Use varpool_add_new_variable. * varpool.c (varpool_remove_initializer): Break out from ... (varpool_remove_node): ... this one. (dump_varpool_node, varpool_node_for_asm, cgraph_variable_initializer_availability, varpool_analyze_node, varpool_assemble_decl, varpool_remove_unreferenced_decls, varpool_finalize_named_section_flags, varpool_create_variable_alias): Update * decl.c (java_mark_decl_local): Update for new symtab flags. * tree.c (cp_fix_function_decl_p): Update for new symtab flags. * decl2.c )var_finalized_p, cp_write_global_declarations): Likewise. * lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab flags. * lto-partition.c (get_symbol_class, lto_balanced_map): Likewise. From-SVN: r199422
This commit is contained in:
parent
182802adcc
commit
e70670cf4d
117
gcc/ChangeLog
117
gcc/ChangeLog
|
|
@ -1,3 +1,120 @@
|
|||
2013-05-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraph.h (symtab_node_base): Add definition, alias and analyzed
|
||||
flags; reorder rest of fields in more consistent way.
|
||||
(varpool_node): Remove analyzed, finalized and alias.
|
||||
(cgraph_ndoe): Likewise.
|
||||
(symtab_alias_ultimate_target): New function.
|
||||
(cgraph_function_node): Move offline.
|
||||
(cgraph_reset_node): Declare.
|
||||
(cgraph_comdat_can_be_unshared_p): Remove.
|
||||
(varpool_remove_initializer): Declare.
|
||||
(varpool_first_defined_variable, varpool_next_defined_variable
|
||||
cgraph_first_defined_function, cgraph_next_defined_function): Update.
|
||||
(cgraph_function_with_gimple_body_p): Update.
|
||||
(varpool_all_refs_explicit_p): Update.
|
||||
(symtab_alias_target): New function.
|
||||
(cgraph_alias_aliased_node, varpool_alias_aliased_node): Rename to ...
|
||||
(cgraph_alias_target, varpool_alias_target): .. this one; simplify.
|
||||
(cgraph_function_or_thunk_node): Simplify using symtab_alias_ultimate_target.
|
||||
(varpool_variable_node): Likewise.
|
||||
* cgraph.c (cgraph_create_function_alias): Update.
|
||||
(cgraph_add_thunk): Update.
|
||||
(cgraph_remove_node): Update.
|
||||
(dump_cgraph_node): Do not dump removed flags.
|
||||
(cgraph_function_body_availability): Update.
|
||||
(cgraph_propagate_frequency): Update.
|
||||
(verify_cgraph_node): Check sanity of local flag.
|
||||
(cgraph_function_node): Move here from cgraph.h; revamp for
|
||||
cgraph_function_or_thunk_node.
|
||||
* lto-symtab.c (lto_varpool_replace_node): Update.
|
||||
(lto_symtab_resolve_can_prevail_p): Update.
|
||||
(lto_symtab_merge_cgraph_nodes): Update.
|
||||
* ipa-cp.c (determine_versionability, initialize_node_lattices,
|
||||
propagate_constants_accross_call, devirtualization_time_bonus,
|
||||
ipcp_propagate_stage): Update.
|
||||
* tree-emutls.c (create_emultls_var, ipa_lower_emutls): Update.
|
||||
* ipa-inline-transform.c (clone_inlined_nodes, preserve_function_body_p): Update.
|
||||
* ipa-reference.c (propagate): Update.
|
||||
(write_node_summary_p): Update.
|
||||
* toplev.c (wrapup_global_declaration_2): Update.
|
||||
* cgraphunit.c (cgraph_analyze_function): Rename to ...
|
||||
(analyze_function) ... this one.
|
||||
(cgraph_process_new_functions): Update.
|
||||
(cgraph_reset_node): Export.
|
||||
(cgraph_finalize_function): Update.
|
||||
(cgraph_add_new_function): Update.
|
||||
(process_function_and_variable_attributes): Update.
|
||||
(varpool_finalize_decl): Update.
|
||||
(symbol_finalized): Remove.
|
||||
(symbol_finalized_and_needed): Rename to ...
|
||||
(symbol_defined_and_needed): ... update.
|
||||
(cgraph_analyze_functions): Update.
|
||||
(handle_alias_pairs): Update.
|
||||
(mark_functions_to_output): Update.
|
||||
(assemble_thunk): Update.
|
||||
(output_in_order): Update.
|
||||
(output_weakrefs): Update.
|
||||
(finalize_compilation_unit): Update.
|
||||
* lto-cgraph.c (reachable_from_other_partition_p, lto_output_node,
|
||||
lto_output_varpool_node, compute_ltrans_boundary, input_overwrite_node,
|
||||
input_node, input_varpool_node): Update.
|
||||
* dbxout.c (dbxout_expand_expr): Update.
|
||||
* cgraphclones.c (cgraph_clone_node): Update.
|
||||
(cgraph_copy_node_for_versioning): Update.
|
||||
(cgraph_materialize_clone): Update.
|
||||
(cgraph_materialize_all_clones): Update.
|
||||
* ipa-pure-const.c (analyze_function, pure_const_write_summary,
|
||||
propagate_pure_const, propagate_nothrow): Update.
|
||||
* lto-streamer-out.c (lto_output, write_symbol): Update.
|
||||
* ipa-utils.c (ipa_reverse_postorder): Update.
|
||||
* ipa-inline.c (can_inline_edge_p): Update.
|
||||
(update_caller_keys, ipa_inline): Update.
|
||||
* dwarf2out.c (reference_to_unused,
|
||||
premark_types_used_by_global_vars_helper): Update.
|
||||
* tree-eh.c (tree_could_trap_p): Update.
|
||||
* ipa-split.c (consider_split, execute_split_functions): Update.
|
||||
* ipa.c (cgraph_non_local_node_p_1, cgraph_local_node_p,
|
||||
has_addr_references_p): Update;
|
||||
move ahead in file for better readability.
|
||||
(process_references): Simplify.
|
||||
(symtab_remove_unreachable_nodes): Update; cleanup way function/var
|
||||
bodies are removed.
|
||||
(cgraph_comdat_can_be_unshared_p): Make static.
|
||||
(cgraph_externally_visible_p): Update.
|
||||
(varpool_externally_visible_p): Update.
|
||||
(function_and_variable_visibility): Update.
|
||||
* trans-mem.c (get_cg_data, ipa_tm_mayenterirr_function,
|
||||
ipa_tm_mark_force_output_node): Update.
|
||||
* ipa-inline-analysis.c (dump_inline_summary, initialize_inline_failed,
|
||||
estimate_edge_devirt_benefit, inline_generate_summary,
|
||||
inline_write_summary): Update.
|
||||
* gimple-fold.c (can_refer_decl_in_current_unit_p): Update.
|
||||
* ipa-prop.c (ipa_compute_jump_functions): Update.
|
||||
(ipa_print_node_params, ipa_prop_read_section, ipa_update_after_lto_read,
|
||||
read_replacements_section): Update.
|
||||
* varasm.c (mark_decl_referenced): Update.
|
||||
(assemble_alias, dump_tm_clone_pairs): Update.
|
||||
* tree-inline.c (copy_bb): Update.
|
||||
(estimate_num_insns, optimize_inline_calls, tree_function_versioning):
|
||||
Update.
|
||||
* symtab.c (dump_symtab_base): Print new flags.
|
||||
(verify_symtab_base): Verify new flags.
|
||||
(symtab_alias_ultimate_target): New function.
|
||||
* tree-ssa-structalias.c (get_constraint_for_ssa_var,
|
||||
create_variable_info_for, associate_varinfo_to_alias, ipa_pta_execute):
|
||||
Update.
|
||||
* passes.c (ipa_write_summaries, ipa_write_optimization_summaries): Update.
|
||||
* i386.c (ix86_get_function_versions_dispatcher,
|
||||
ix86_generate_version_dispatcher_body): Update.
|
||||
(fold_builtin_cpu): Use varpool_add_new_variable.
|
||||
* varpool.c (varpool_remove_initializer): Break out from ...
|
||||
(varpool_remove_node): ... this one.
|
||||
(dump_varpool_node, varpool_node_for_asm,
|
||||
cgraph_variable_initializer_availability, varpool_analyze_node,
|
||||
varpool_assemble_decl, varpool_remove_unreferenced_decls,
|
||||
varpool_finalize_named_section_flags, varpool_create_variable_alias): Update
|
||||
|
||||
2013-05-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* passes.c (init_optimization_passes): Move OMP expansion into lowering.
|
||||
|
|
|
|||
66
gcc/cgraph.c
66
gcc/cgraph.c
|
|
@ -563,10 +563,10 @@ cgraph_create_function_alias (tree alias, tree decl)
|
|||
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
||||
gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
|
||||
alias_node = cgraph_get_create_node (alias);
|
||||
gcc_assert (!alias_node->local.finalized);
|
||||
gcc_assert (!alias_node->symbol.definition);
|
||||
alias_node->thunk.alias = decl;
|
||||
alias_node->local.finalized = true;
|
||||
alias_node->alias = 1;
|
||||
alias_node->symbol.definition = true;
|
||||
alias_node->symbol.alias = true;
|
||||
return alias_node;
|
||||
}
|
||||
|
||||
|
|
@ -613,8 +613,8 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED,
|
|||
node = cgraph_get_node (alias);
|
||||
if (node)
|
||||
{
|
||||
gcc_assert (node->local.finalized);
|
||||
gcc_assert (!node->alias);
|
||||
gcc_assert (node->symbol.definition);
|
||||
gcc_assert (!node->symbol.alias);
|
||||
gcc_assert (!node->thunk.thunk_p);
|
||||
cgraph_remove_node (node);
|
||||
}
|
||||
|
|
@ -629,7 +629,7 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED,
|
|||
node->thunk.virtual_offset_p = virtual_offset != NULL;
|
||||
node->thunk.alias = real_alias;
|
||||
node->thunk.thunk_p = true;
|
||||
node->local.finalized = true;
|
||||
node->symbol.definition = true;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
|
@ -1384,7 +1384,7 @@ cgraph_remove_node (struct cgraph_node *node)
|
|||
&& (cgraph_global_info_ready
|
||||
&& (TREE_ASM_WRITTEN (n->symbol.decl)
|
||||
|| DECL_EXTERNAL (n->symbol.decl)
|
||||
|| !n->analyzed
|
||||
|| !n->symbol.analyzed
|
||||
|| n->symbol.in_other_partition))))
|
||||
cgraph_release_function_body (node);
|
||||
|
||||
|
|
@ -1521,8 +1521,6 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
cgraph_availability_names [cgraph_function_body_availability (node)]);
|
||||
|
||||
fprintf (f, " Function flags:");
|
||||
if (node->analyzed)
|
||||
fprintf (f, " analyzed");
|
||||
if (node->count)
|
||||
fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
|
||||
(HOST_WIDEST_INT)node->count);
|
||||
|
|
@ -1534,16 +1532,12 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
fprintf (f, " process");
|
||||
if (node->local.local)
|
||||
fprintf (f, " local");
|
||||
if (node->local.finalized)
|
||||
fprintf (f, " finalized");
|
||||
if (node->local.redefined_extern_inline)
|
||||
fprintf (f, " redefined_extern_inline");
|
||||
if (node->only_called_at_startup)
|
||||
fprintf (f, " only_called_at_startup");
|
||||
if (node->only_called_at_exit)
|
||||
fprintf (f, " only_called_at_exit");
|
||||
else if (node->alias)
|
||||
fprintf (f, " alias");
|
||||
if (node->tm_clone)
|
||||
fprintf (f, " tm_clone");
|
||||
|
||||
|
|
@ -1559,7 +1553,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
(int)node->thunk.virtual_value,
|
||||
(int)node->thunk.virtual_offset_p);
|
||||
}
|
||||
if (node->alias && node->thunk.alias && DECL_P (node->thunk.alias))
|
||||
if (node->symbol.alias && node->thunk.alias
|
||||
&& DECL_P (node->thunk.alias))
|
||||
{
|
||||
fprintf (f, " Alias of %s",
|
||||
lang_hooks.decl_printable_name (node->thunk.alias, 2));
|
||||
|
|
@ -1676,7 +1671,7 @@ cgraph_function_body_availability (struct cgraph_node *node)
|
|||
{
|
||||
enum availability avail;
|
||||
gcc_assert (cgraph_function_flags_ready);
|
||||
if (!node->analyzed)
|
||||
if (!node->symbol.analyzed)
|
||||
avail = AVAIL_NOT_AVAILABLE;
|
||||
else if (node->local.local)
|
||||
avail = AVAIL_LOCAL;
|
||||
|
|
@ -1983,7 +1978,7 @@ cgraph_propagate_frequency (struct cgraph_node *node)
|
|||
|
||||
if (!node->local.local)
|
||||
return false;
|
||||
gcc_assert (node->analyzed);
|
||||
gcc_assert (node->symbol.analyzed);
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node));
|
||||
|
||||
|
|
@ -2342,6 +2337,11 @@ verify_cgraph_node (struct cgraph_node *node)
|
|||
error ("inline clone in same comdat group list");
|
||||
error_found = true;
|
||||
}
|
||||
if (!node->symbol.definition && node->local.local)
|
||||
{
|
||||
error ("local symbols must be defined");
|
||||
error_found = true;
|
||||
}
|
||||
if (node->global.inlined_to && node->symbol.externally_visible)
|
||||
{
|
||||
error ("externally visible inline clone");
|
||||
|
|
@ -2455,7 +2455,7 @@ verify_cgraph_node (struct cgraph_node *node)
|
|||
error_found = true;
|
||||
}
|
||||
|
||||
if (node->analyzed && node->alias)
|
||||
if (node->symbol.analyzed && node->symbol.alias)
|
||||
{
|
||||
bool ref_found = false;
|
||||
int i;
|
||||
|
|
@ -2486,7 +2486,7 @@ verify_cgraph_node (struct cgraph_node *node)
|
|||
error_found = true;
|
||||
}
|
||||
}
|
||||
if (node->analyzed && node->thunk.thunk_p)
|
||||
if (node->symbol.analyzed && node->thunk.thunk_p)
|
||||
{
|
||||
if (!node->callees)
|
||||
{
|
||||
|
|
@ -2504,7 +2504,7 @@ verify_cgraph_node (struct cgraph_node *node)
|
|||
error_found = true;
|
||||
}
|
||||
}
|
||||
else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
|
||||
else if (node->symbol.analyzed && gimple_has_body_p (node->symbol.decl)
|
||||
&& !TREE_ASM_WRITTEN (node->symbol.decl)
|
||||
&& (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
|
||||
&& !flag_wpa)
|
||||
|
|
@ -2653,4 +2653,32 @@ cgraph_get_create_real_symbol_node (tree decl)
|
|||
node->symbol.order);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/* Given NODE, walk the alias chain to return the function NODE is alias of.
|
||||
Walk through thunk, too.
|
||||
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
|
||||
|
||||
struct cgraph_node *
|
||||
cgraph_function_node (struct cgraph_node *node, enum availability *availability)
|
||||
{
|
||||
do
|
||||
{
|
||||
node = cgraph_function_or_thunk_node (node, availability);
|
||||
if (node->thunk.thunk_p)
|
||||
{
|
||||
node = node->callees->callee;
|
||||
if (availability)
|
||||
{
|
||||
enum availability a;
|
||||
a = cgraph_function_body_availability (node);
|
||||
if (a < *availability)
|
||||
*availability = a;
|
||||
}
|
||||
node = cgraph_function_or_thunk_node (node, availability);
|
||||
}
|
||||
} while (node && node->thunk.thunk_p);
|
||||
return node;
|
||||
}
|
||||
|
||||
#include "gt-cgraph.h"
|
||||
|
|
|
|||
219
gcc/cgraph.h
219
gcc/cgraph.h
|
|
@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "ipa-ref.h"
|
||||
|
||||
/* Symbol table consists of functions and variables.
|
||||
TODO: add labels, constant pool and aliases. */
|
||||
TODO: add labels and CONST_DECLs. */
|
||||
enum symtab_type
|
||||
{
|
||||
SYMTAB_SYMBOL,
|
||||
|
|
@ -48,15 +48,21 @@ struct GTY(()) symtab_node_base
|
|||
/* The symbols resolution. */
|
||||
ENUM_BITFIELD (ld_plugin_symbol_resolution) resolution : 8;
|
||||
|
||||
/* Set when function has address taken.
|
||||
In current implementation it imply needed flag. */
|
||||
unsigned address_taken : 1;
|
||||
/* Set when variable is used from other LTRANS partition. */
|
||||
unsigned used_from_other_partition : 1;
|
||||
/* Set when function is available in the other LTRANS partition.
|
||||
During WPA output it is used to mark nodes that are present in
|
||||
multiple partitions. */
|
||||
unsigned in_other_partition : 1;
|
||||
/*** Flags representing the symbol type. ***/
|
||||
|
||||
/* True when symbol corresponds to a definition in current unit.
|
||||
set via cgraph_finalize_function or varpool_finalize_decl */
|
||||
unsigned definition : 1;
|
||||
/* True when symbol is an alias.
|
||||
Set by assemble_alias. */
|
||||
unsigned alias : 1;
|
||||
/* Set once the definition was analyzed. The list of references and
|
||||
other properties are built during analysis. */
|
||||
unsigned analyzed : 1;
|
||||
|
||||
|
||||
/*** Visibility and linkage flags. ***/
|
||||
|
||||
/* Set when function is visible by other units. */
|
||||
unsigned externally_visible : 1;
|
||||
/* Needed variables might become dead by optimization. This flag
|
||||
|
|
@ -65,30 +71,57 @@ struct GTY(()) symtab_node_base
|
|||
/* True when the name is known to be unique and thus it does not need mangling. */
|
||||
unsigned unique_name : 1;
|
||||
|
||||
|
||||
/*** WHOPR Partitioning flags.
|
||||
These flags are used at ltrans stage when only part of the callgraph is
|
||||
available. ***/
|
||||
|
||||
/* Set when variable is used from other LTRANS partition. */
|
||||
unsigned used_from_other_partition : 1;
|
||||
/* Set when function is available in the other LTRANS partition.
|
||||
During WPA output it is used to mark nodes that are present in
|
||||
multiple partitions. */
|
||||
unsigned in_other_partition : 1;
|
||||
|
||||
|
||||
|
||||
/*** other flags. ***/
|
||||
|
||||
/* Set when symbol has address taken. */
|
||||
unsigned address_taken : 1;
|
||||
|
||||
|
||||
/* Ordering of all symtab entries. */
|
||||
int order;
|
||||
|
||||
/* Declaration representing the symbol. */
|
||||
tree decl;
|
||||
|
||||
/* Vectors of referring and referenced entities. */
|
||||
struct ipa_ref_list ref_list;
|
||||
|
||||
/* Circular list of nodes in the same comdat group if non-NULL. */
|
||||
symtab_node same_comdat_group;
|
||||
|
||||
/* File stream where this node is being written to. */
|
||||
struct lto_file_decl_data * lto_file_data;
|
||||
|
||||
/* Linked list of symbol table entries starting with symtab_nodes. */
|
||||
symtab_node next;
|
||||
symtab_node previous;
|
||||
|
||||
/* Linked list of symbols with the same asm name. There may be multiple
|
||||
entries for single symbol name in the case of LTO resolutions,
|
||||
existence of inline clones, or duplicated declaration. The last case
|
||||
is a long standing bug frontends and builtin handling. */
|
||||
entries for single symbol name during LTO, because symbols are renamed
|
||||
only after partitioning.
|
||||
|
||||
Because inline clones are kept in the assembler name has, they also produce
|
||||
duplicate entries.
|
||||
|
||||
There are also several long standing bugs where frontends and builtin
|
||||
code produce duplicated decls. */
|
||||
symtab_node next_sharing_asm_name;
|
||||
symtab_node previous_sharing_asm_name;
|
||||
|
||||
/* Circular list of nodes in the same comdat group if non-NULL. */
|
||||
symtab_node same_comdat_group;
|
||||
|
||||
/* Vectors of referring and referenced entities. */
|
||||
struct ipa_ref_list ref_list;
|
||||
|
||||
/* File stream where this node is being written to. */
|
||||
struct lto_file_decl_data * lto_file_data;
|
||||
|
||||
PTR GTY ((skip)) aux;
|
||||
};
|
||||
|
||||
|
|
@ -142,9 +175,6 @@ struct GTY(()) cgraph_local_info {
|
|||
and its address is never taken. */
|
||||
unsigned local : 1;
|
||||
|
||||
/* Set once it has been finalized so we consider it to be output. */
|
||||
unsigned finalized : 1;
|
||||
|
||||
/* False when there is something makes versioning impossible. */
|
||||
unsigned versionable : 1;
|
||||
|
||||
|
|
@ -260,11 +290,7 @@ struct GTY(()) cgraph_node {
|
|||
unsigned lowered : 1;
|
||||
/* Set once the function has been instantiated and its callee
|
||||
lists created. */
|
||||
unsigned analyzed : 1;
|
||||
/* Set when function is scheduled to be processed by local passes. */
|
||||
unsigned process : 1;
|
||||
/* Set for aliases once they got through assemble_alias. */
|
||||
unsigned alias : 1;
|
||||
/* Set for aliases created as C++ same body aliases. */
|
||||
unsigned same_body_alias : 1;
|
||||
/* How commonly executed the node is. Initialized during branch
|
||||
|
|
@ -455,16 +481,8 @@ struct GTY(()) varpool_node {
|
|||
/* For aliases points to declaration DECL is alias of. */
|
||||
tree alias_of;
|
||||
|
||||
/* Set once the variable has been instantiated and its callee
|
||||
lists created. */
|
||||
unsigned analyzed : 1;
|
||||
/* Set once it has been finalized so we consider it to be output. */
|
||||
unsigned finalized : 1;
|
||||
/* Set when variable is scheduled to be assembled. */
|
||||
unsigned output : 1;
|
||||
/* Set for aliases once they got through assemble_alias. Also set for
|
||||
extra name aliases in varpool_extra_name_alias. */
|
||||
unsigned alias : 1;
|
||||
unsigned extra_name_alias : 1;
|
||||
};
|
||||
|
||||
|
|
@ -558,6 +576,7 @@ void verify_symtab_node (symtab_node);
|
|||
bool verify_symtab_base (symtab_node);
|
||||
bool symtab_used_from_object_file_p (symtab_node);
|
||||
void symtab_make_decl_local (tree);
|
||||
symtab_node symtab_alias_ultimate_target (symtab_node, enum availability *);
|
||||
|
||||
/* In cgraph.c */
|
||||
void dump_cgraph (FILE *);
|
||||
|
|
@ -653,6 +672,7 @@ struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_ho
|
|||
void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
|
||||
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
|
||||
bool cgraph_propagate_frequency (struct cgraph_node *node);
|
||||
struct cgraph_node * cgraph_function_node (struct cgraph_node *, enum availability *);
|
||||
|
||||
/* In cgraphunit.c */
|
||||
struct asm_node *add_asm_node (tree);
|
||||
|
|
@ -663,10 +683,11 @@ void compile (void);
|
|||
void init_cgraph (void);
|
||||
bool cgraph_process_new_functions (void);
|
||||
void cgraph_process_same_body_aliases (void);
|
||||
void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias);
|
||||
void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
|
||||
/* Initialize datastructures so DECL is a function in lowered gimple form.
|
||||
IN_SSA is true if the gimple is in SSA. */
|
||||
basic_block init_lowered_empty_function (tree decl, bool in_ssa);
|
||||
basic_block init_lowered_empty_function (tree, bool);
|
||||
void cgraph_reset_node (struct cgraph_node *);
|
||||
|
||||
/* In cgraphclones.c */
|
||||
|
||||
|
|
@ -728,7 +749,6 @@ void dump_varpool_node_set (FILE *, varpool_node_set);
|
|||
void debug_varpool_node_set (varpool_node_set);
|
||||
void free_varpool_node_set (varpool_node_set);
|
||||
void ipa_discover_readonly_nonaddressable_vars (void);
|
||||
bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *);
|
||||
bool varpool_externally_visible_p (struct varpool_node *);
|
||||
|
||||
/* In predict.c */
|
||||
|
|
@ -765,6 +785,7 @@ bool varpool_for_node_and_aliases (struct varpool_node *,
|
|||
void varpool_add_new_variable (tree);
|
||||
void symtab_initialize_asm_name_hash (void);
|
||||
void symtab_prevail_in_asm_name_hash (symtab_node node);
|
||||
void varpool_remove_initializer (struct varpool_node *);
|
||||
|
||||
|
||||
/* Return callgraph node for given symbol and check it is a function. */
|
||||
|
|
@ -900,7 +921,7 @@ varpool_first_defined_variable (void)
|
|||
for (node = symtab_nodes; node; node = node->symbol.next)
|
||||
{
|
||||
varpool_node *vnode = dyn_cast <varpool_node> (node);
|
||||
if (vnode && vnode->analyzed)
|
||||
if (vnode && vnode->symbol.definition)
|
||||
return vnode;
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -914,7 +935,7 @@ varpool_next_defined_variable (struct varpool_node *node)
|
|||
for (; node1; node1 = node1->symbol.next)
|
||||
{
|
||||
varpool_node *vnode1 = dyn_cast <varpool_node> (node1);
|
||||
if (vnode1 && vnode1->analyzed)
|
||||
if (vnode1 && vnode1->symbol.definition)
|
||||
return vnode1;
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -932,7 +953,7 @@ cgraph_first_defined_function (void)
|
|||
for (node = symtab_nodes; node; node = node->symbol.next)
|
||||
{
|
||||
cgraph_node *cn = dyn_cast <cgraph_node> (node);
|
||||
if (cn && cn->analyzed)
|
||||
if (cn && cn->symbol.definition)
|
||||
return cn;
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -946,7 +967,7 @@ cgraph_next_defined_function (struct cgraph_node *node)
|
|||
for (; node1; node1 = node1->symbol.next)
|
||||
{
|
||||
cgraph_node *cn1 = dyn_cast <cgraph_node> (node1);
|
||||
if (cn1 && cn1->analyzed)
|
||||
if (cn1 && cn1->symbol.definition)
|
||||
return cn1;
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -992,7 +1013,7 @@ cgraph_next_function (struct cgraph_node *node)
|
|||
static inline bool
|
||||
cgraph_function_with_gimple_body_p (struct cgraph_node *node)
|
||||
{
|
||||
return node->analyzed && !node->thunk.thunk_p && !node->alias;
|
||||
return node->symbol.definition && !node->thunk.thunk_p && !node->symbol.alias;
|
||||
}
|
||||
|
||||
/* Return first function with body defined. */
|
||||
|
|
@ -1197,7 +1218,7 @@ varpool_can_remove_if_no_refs (struct varpool_node *node)
|
|||
static inline bool
|
||||
varpool_all_refs_explicit_p (struct varpool_node *vnode)
|
||||
{
|
||||
return (vnode->analyzed
|
||||
return (vnode->symbol.definition
|
||||
&& !vnode->symbol.externally_visible
|
||||
&& !vnode->symbol.used_from_other_partition
|
||||
&& !vnode->symbol.force_output);
|
||||
|
|
@ -1211,60 +1232,25 @@ htab_t constant_pool_htab (void);
|
|||
|
||||
/* Return node that alias N is aliasing. */
|
||||
|
||||
static inline struct cgraph_node *
|
||||
cgraph_alias_aliased_node (struct cgraph_node *n)
|
||||
static inline symtab_node
|
||||
symtab_alias_target (symtab_node n)
|
||||
{
|
||||
struct ipa_ref *ref;
|
||||
|
||||
ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
|
||||
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
|
||||
if (is_a <cgraph_node> (ref->referred))
|
||||
return ipa_ref_node (ref);
|
||||
return NULL;
|
||||
return ref->referred;
|
||||
}
|
||||
|
||||
/* Return node that alias N is aliasing. */
|
||||
static inline struct cgraph_node *
|
||||
cgraph_alias_target (struct cgraph_node *n)
|
||||
{
|
||||
return dyn_cast <cgraph_node> (symtab_alias_target ((symtab_node) n));
|
||||
}
|
||||
|
||||
static inline struct varpool_node *
|
||||
varpool_alias_aliased_node (struct varpool_node *n)
|
||||
varpool_alias_target (struct varpool_node *n)
|
||||
{
|
||||
struct ipa_ref *ref;
|
||||
|
||||
ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
|
||||
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
|
||||
if (is_a <varpool_node> (ref->referred))
|
||||
return ipa_ref_varpool_node (ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Given NODE, walk the alias chain to return the function NODE is alias of.
|
||||
Walk through thunk, too.
|
||||
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
|
||||
|
||||
static inline struct cgraph_node *
|
||||
cgraph_function_node (struct cgraph_node *node, enum availability *availability)
|
||||
{
|
||||
if (availability)
|
||||
*availability = cgraph_function_body_availability (node);
|
||||
while (node)
|
||||
{
|
||||
if (node->alias && node->analyzed)
|
||||
node = cgraph_alias_aliased_node (node);
|
||||
else if (node->thunk.thunk_p)
|
||||
node = node->callees->callee;
|
||||
else
|
||||
return node;
|
||||
if (node && availability)
|
||||
{
|
||||
enum availability a;
|
||||
a = cgraph_function_body_availability (node);
|
||||
if (a < *availability)
|
||||
*availability = a;
|
||||
}
|
||||
}
|
||||
if (availability)
|
||||
*availability = AVAIL_NOT_AVAILABLE;
|
||||
return NULL;
|
||||
return dyn_cast <varpool_node> (symtab_alias_target ((symtab_node) n));
|
||||
}
|
||||
|
||||
/* Given NODE, walk the alias chain to return the function NODE is alias of.
|
||||
|
|
@ -1274,27 +1260,13 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability)
|
|||
static inline struct cgraph_node *
|
||||
cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability)
|
||||
{
|
||||
if (availability)
|
||||
*availability = cgraph_function_body_availability (node);
|
||||
while (node)
|
||||
{
|
||||
if (node->alias && node->analyzed)
|
||||
node = cgraph_alias_aliased_node (node);
|
||||
else
|
||||
return node;
|
||||
if (node && availability)
|
||||
{
|
||||
enum availability a;
|
||||
a = cgraph_function_body_availability (node);
|
||||
if (a < *availability)
|
||||
*availability = a;
|
||||
}
|
||||
}
|
||||
if (availability)
|
||||
*availability = AVAIL_NOT_AVAILABLE;
|
||||
return NULL;
|
||||
}
|
||||
struct cgraph_node *n;
|
||||
|
||||
n = dyn_cast <cgraph_node> (symtab_alias_ultimate_target ((symtab_node)node, availability));
|
||||
if (!n)
|
||||
*availability = AVAIL_NOT_AVAILABLE;
|
||||
return n;
|
||||
}
|
||||
/* Given NODE, walk the alias chain to return the function NODE is alias of.
|
||||
Do not walk through thunks.
|
||||
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
|
||||
|
|
@ -1302,25 +1274,12 @@ cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *avai
|
|||
static inline struct varpool_node *
|
||||
varpool_variable_node (struct varpool_node *node, enum availability *availability)
|
||||
{
|
||||
if (availability)
|
||||
*availability = cgraph_variable_initializer_availability (node);
|
||||
while (node)
|
||||
{
|
||||
if (node->alias && node->analyzed)
|
||||
node = varpool_alias_aliased_node (node);
|
||||
else
|
||||
return node;
|
||||
if (node && availability)
|
||||
{
|
||||
enum availability a;
|
||||
a = cgraph_variable_initializer_availability (node);
|
||||
if (a < *availability)
|
||||
*availability = a;
|
||||
}
|
||||
}
|
||||
if (availability)
|
||||
struct varpool_node *n;
|
||||
|
||||
n = dyn_cast <varpool_node> (symtab_alias_ultimate_target ((symtab_node)node, availability));
|
||||
if (!n)
|
||||
*availability = AVAIL_NOT_AVAILABLE;
|
||||
return NULL;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Return true when the edge E represents a direct recursion. */
|
||||
|
|
@ -1355,7 +1314,7 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
|
|||
}
|
||||
|
||||
/* Return true when the symbol is real symbol, i.e. it is not inline clone
|
||||
or extern function kept around just for inlining. */
|
||||
or abstract function kept for debug info purposes only. */
|
||||
|
||||
static inline bool
|
||||
symtab_real_symbol_p (symtab_node node)
|
||||
|
|
|
|||
|
|
@ -189,7 +189,8 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
|
|||
new_node->next_nested = new_node->origin->nested;
|
||||
new_node->origin->nested = new_node;
|
||||
}
|
||||
new_node->analyzed = n->analyzed;
|
||||
new_node->symbol.analyzed = n->symbol.analyzed;
|
||||
new_node->symbol.definition = n->symbol.definition;
|
||||
new_node->local = n->local;
|
||||
new_node->symbol.externally_visible = false;
|
||||
new_node->local.local = true;
|
||||
|
|
@ -638,10 +639,11 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
|
|||
|
||||
new_version = cgraph_create_node (new_decl);
|
||||
|
||||
new_version->analyzed = old_version->analyzed;
|
||||
new_version->symbol.analyzed = old_version->symbol.analyzed;
|
||||
new_version->symbol.definition = old_version->symbol.definition;
|
||||
new_version->local = old_version->local;
|
||||
new_version->symbol.externally_visible = false;
|
||||
new_version->local.local = old_version->analyzed;
|
||||
new_version->local.local = new_version->symbol.definition;
|
||||
new_version->global = old_version->global;
|
||||
new_version->rtl = old_version->rtl;
|
||||
new_version->count = old_version->count;
|
||||
|
|
@ -791,7 +793,7 @@ cgraph_materialize_clone (struct cgraph_node *node)
|
|||
node->clone_of->clones = node->next_sibling_clone;
|
||||
node->next_sibling_clone = NULL;
|
||||
node->prev_sibling_clone = NULL;
|
||||
if (!node->clone_of->analyzed && !node->clone_of->clones)
|
||||
if (!node->clone_of->symbol.analyzed && !node->clone_of->clones)
|
||||
{
|
||||
cgraph_release_function_body (node->clone_of);
|
||||
cgraph_node_remove_callees (node->clone_of);
|
||||
|
|
@ -874,7 +876,7 @@ cgraph_materialize_all_clones (void)
|
|||
}
|
||||
}
|
||||
FOR_EACH_FUNCTION (node)
|
||||
if (!node->analyzed && node->callees)
|
||||
if (!node->symbol.analyzed && node->callees)
|
||||
cgraph_node_remove_callees (node);
|
||||
if (cgraph_dump_file)
|
||||
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
|
||||
|
|
|
|||
117
gcc/cgraphunit.c
117
gcc/cgraphunit.c
|
|
@ -202,7 +202,7 @@ cgraph_node_set cgraph_new_nodes;
|
|||
static void expand_all_functions (void);
|
||||
static void mark_functions_to_output (void);
|
||||
static void expand_function (struct cgraph_node *);
|
||||
static void cgraph_analyze_function (struct cgraph_node *);
|
||||
static void analyze_function (struct cgraph_node *);
|
||||
static void handle_alias_pairs (void);
|
||||
|
||||
FILE *cgraph_dump_file;
|
||||
|
|
@ -309,8 +309,8 @@ cgraph_process_new_functions (void)
|
|||
cgraph but not on this function. */
|
||||
|
||||
gimple_register_cfg_hooks ();
|
||||
if (!node->analyzed)
|
||||
cgraph_analyze_function (node);
|
||||
if (!node->symbol.analyzed)
|
||||
analyze_function (node);
|
||||
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
|
||||
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
|
||||
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
|
||||
|
|
@ -354,7 +354,7 @@ cgraph_process_new_functions (void)
|
|||
??? It may make more sense to use one body for inlining and other
|
||||
body for expanding the function but this is difficult to do. */
|
||||
|
||||
static void
|
||||
void
|
||||
cgraph_reset_node (struct cgraph_node *node)
|
||||
{
|
||||
/* If node->process is set, then we have already begun whole-unit analysis.
|
||||
|
|
@ -368,10 +368,11 @@ cgraph_reset_node (struct cgraph_node *node)
|
|||
memset (&node->local, 0, sizeof (node->local));
|
||||
memset (&node->global, 0, sizeof (node->global));
|
||||
memset (&node->rtl, 0, sizeof (node->rtl));
|
||||
node->analyzed = false;
|
||||
node->local.finalized = false;
|
||||
node->symbol.analyzed = false;
|
||||
node->symbol.definition = false;
|
||||
|
||||
cgraph_node_remove_callees (node);
|
||||
ipa_remove_all_references (&node->symbol.ref_list);
|
||||
}
|
||||
|
||||
/* Return true when there are references to NODE. */
|
||||
|
|
@ -401,14 +402,14 @@ cgraph_finalize_function (tree decl, bool nested)
|
|||
{
|
||||
struct cgraph_node *node = cgraph_get_create_node (decl);
|
||||
|
||||
if (node->local.finalized)
|
||||
if (node->symbol.definition)
|
||||
{
|
||||
cgraph_reset_node (node);
|
||||
node->local.redefined_extern_inline = true;
|
||||
}
|
||||
|
||||
notice_global_symbol (decl);
|
||||
node->local.finalized = true;
|
||||
node->symbol.definition = true;
|
||||
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
|
||||
|
||||
/* With -fkeep-inline-functions we are keeping all inline functions except
|
||||
|
|
@ -488,7 +489,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
|||
analyzing and compilation. */
|
||||
node = cgraph_get_create_node (fndecl);
|
||||
node->local.local = false;
|
||||
node->local.finalized = true;
|
||||
node->symbol.definition = true;
|
||||
node->symbol.force_output = true;
|
||||
if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
|
||||
{
|
||||
|
|
@ -515,7 +516,8 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
|||
node = cgraph_create_node (fndecl);
|
||||
if (lowered)
|
||||
node->lowered = true;
|
||||
cgraph_analyze_function (node);
|
||||
node->symbol.definition = true;
|
||||
analyze_function (node);
|
||||
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
|
||||
gimple_register_cfg_hooks ();
|
||||
bitmap_obstack_initialize (NULL);
|
||||
|
|
@ -589,23 +591,23 @@ fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alia
|
|||
|
||||
/* Analyze the function scheduled to be output. */
|
||||
static void
|
||||
cgraph_analyze_function (struct cgraph_node *node)
|
||||
analyze_function (struct cgraph_node *node)
|
||||
{
|
||||
tree decl = node->symbol.decl;
|
||||
location_t saved_loc = input_location;
|
||||
input_location = DECL_SOURCE_LOCATION (decl);
|
||||
|
||||
if (node->alias && node->thunk.alias)
|
||||
if (node->symbol.alias && node->thunk.alias)
|
||||
{
|
||||
struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
|
||||
struct cgraph_node *n;
|
||||
|
||||
for (n = tgt; n && n->alias;
|
||||
n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
|
||||
for (n = tgt; n && n->symbol.alias;
|
||||
n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL)
|
||||
if (n == node)
|
||||
{
|
||||
error ("function %q+D part of alias cycle", node->symbol.decl);
|
||||
node->alias = false;
|
||||
node->symbol.alias = false;
|
||||
input_location = saved_loc;
|
||||
return;
|
||||
}
|
||||
|
|
@ -622,7 +624,7 @@ cgraph_analyze_function (struct cgraph_node *node)
|
|||
}
|
||||
|
||||
if (node->symbol.address_taken)
|
||||
cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
|
||||
cgraph_mark_address_taken_node (cgraph_alias_target (node));
|
||||
}
|
||||
else if (node->thunk.thunk_p)
|
||||
{
|
||||
|
|
@ -677,7 +679,7 @@ cgraph_analyze_function (struct cgraph_node *node)
|
|||
|
||||
pop_cfun ();
|
||||
}
|
||||
node->analyzed = true;
|
||||
node->symbol.analyzed = true;
|
||||
|
||||
input_location = saved_loc;
|
||||
}
|
||||
|
|
@ -766,7 +768,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
|
|||
" attribute have effect only on public objects");
|
||||
}
|
||||
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
|
||||
&& (node->local.finalized && !node->alias))
|
||||
&& (node->symbol.definition && !node->symbol.alias))
|
||||
{
|
||||
warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
|
||||
"%<weakref%> attribute ignored"
|
||||
|
|
@ -803,7 +805,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
|
|||
" attribute have effect only on public objects");
|
||||
}
|
||||
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
|
||||
&& vnode->finalized
|
||||
&& vnode->symbol.definition
|
||||
&& DECL_INITIAL (decl))
|
||||
{
|
||||
warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
|
||||
|
|
@ -828,10 +830,10 @@ varpool_finalize_decl (tree decl)
|
|||
|
||||
gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
|
||||
|
||||
if (node->finalized)
|
||||
if (node->symbol.definition)
|
||||
return;
|
||||
notice_global_symbol (decl);
|
||||
node->finalized = true;
|
||||
node->symbol.definition = true;
|
||||
if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
|
||||
/* Traditionally we do not eliminate static variables when not
|
||||
optimizing and when not doing toplevel reoder. */
|
||||
|
|
@ -855,36 +857,23 @@ varpool_finalize_decl (tree decl)
|
|||
/* Determine if a symbol NODE is finalized and needed. */
|
||||
|
||||
inline static bool
|
||||
symbol_finalized_and_needed (symtab_node node)
|
||||
symbol_defined_and_needed (symtab_node node)
|
||||
{
|
||||
if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
|
||||
return cnode->local.finalized
|
||||
return cnode->symbol.definition
|
||||
&& cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
|
||||
if (varpool_node *vnode = dyn_cast <varpool_node> (node))
|
||||
return vnode->finalized
|
||||
return vnode->symbol.definition
|
||||
&& !DECL_EXTERNAL (vnode->symbol.decl)
|
||||
&& decide_is_variable_needed (vnode, vnode->symbol.decl);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Determine if a symbol NODE is finalized. */
|
||||
|
||||
inline static bool
|
||||
symbol_finalized (symtab_node node)
|
||||
{
|
||||
if (cgraph_node *cnode= dyn_cast <cgraph_node> (node))
|
||||
return cnode->local.finalized;
|
||||
if (varpool_node *vnode = dyn_cast <varpool_node> (node))
|
||||
return vnode->finalized;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Discover all functions and variables that are trivially needed, analyze
|
||||
them as well as all functions and variables referred by them */
|
||||
|
||||
static void
|
||||
cgraph_analyze_functions (void)
|
||||
analyze_functions (void)
|
||||
{
|
||||
/* Keep track of already processed nodes when called multiple times for
|
||||
intermodule optimization. */
|
||||
|
|
@ -914,7 +903,7 @@ cgraph_analyze_functions (void)
|
|||
node != (symtab_node)first_analyzed
|
||||
&& node != (symtab_node)first_analyzed_var; node = node->symbol.next)
|
||||
{
|
||||
if (symbol_finalized_and_needed (node))
|
||||
if (symbol_defined_and_needed (node))
|
||||
{
|
||||
enqueue_node (node);
|
||||
if (!changed && cgraph_dump_file)
|
||||
|
|
@ -942,7 +931,7 @@ cgraph_analyze_functions (void)
|
|||
node = first;
|
||||
first = (symtab_node)first->symbol.aux;
|
||||
cgraph_node *cnode = dyn_cast <cgraph_node> (node);
|
||||
if (cnode && cnode->local.finalized)
|
||||
if (cnode && cnode->symbol.definition)
|
||||
{
|
||||
struct cgraph_edge *edge;
|
||||
tree decl = cnode->symbol.decl;
|
||||
|
|
@ -951,7 +940,7 @@ cgraph_analyze_functions (void)
|
|||
and later using weak alias attribute to kill its body.
|
||||
See gcc.c-torture/compile/20011119-1.c */
|
||||
if (!DECL_STRUCT_FUNCTION (decl)
|
||||
&& (!cnode->alias || !cnode->thunk.alias)
|
||||
&& (!cnode->symbol.alias || !cnode->thunk.alias)
|
||||
&& !cnode->thunk.thunk_p
|
||||
&& !cnode->dispatcher_function)
|
||||
{
|
||||
|
|
@ -960,11 +949,11 @@ cgraph_analyze_functions (void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!cnode->analyzed)
|
||||
cgraph_analyze_function (cnode);
|
||||
if (!cnode->symbol.analyzed)
|
||||
analyze_function (cnode);
|
||||
|
||||
for (edge = cnode->callees; edge; edge = edge->next_callee)
|
||||
if (edge->callee->local.finalized)
|
||||
if (edge->callee->symbol.definition)
|
||||
enqueue_node ((symtab_node)edge->callee);
|
||||
|
||||
/* If decl is a clone of an abstract function,
|
||||
|
|
@ -981,7 +970,7 @@ cgraph_analyze_functions (void)
|
|||
else
|
||||
{
|
||||
varpool_node *vnode = dyn_cast <varpool_node> (node);
|
||||
if (vnode && vnode->finalized)
|
||||
if (vnode && vnode->symbol.definition)
|
||||
varpool_analyze_node (vnode);
|
||||
}
|
||||
|
||||
|
|
@ -994,7 +983,7 @@ cgraph_analyze_functions (void)
|
|||
enqueue_node (next);
|
||||
}
|
||||
for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
|
||||
if (symbol_finalized (ref->referred))
|
||||
if (ref->referred->symbol.definition)
|
||||
enqueue_node (ref->referred);
|
||||
cgraph_process_new_functions ();
|
||||
}
|
||||
|
|
@ -1026,15 +1015,15 @@ cgraph_analyze_functions (void)
|
|||
{
|
||||
tree decl = node->symbol.decl;
|
||||
|
||||
if (cnode->local.finalized && !gimple_has_body_p (decl)
|
||||
&& (!cnode->alias || !cnode->thunk.alias)
|
||||
if (cnode->symbol.definition && !gimple_has_body_p (decl)
|
||||
&& (!cnode->symbol.alias || !cnode->thunk.alias)
|
||||
&& !cnode->thunk.thunk_p)
|
||||
cgraph_reset_node (cnode);
|
||||
|
||||
gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
|
||||
|| cnode->alias
|
||||
gcc_assert (!cnode->symbol.definition || cnode->thunk.thunk_p
|
||||
|| cnode->symbol.alias
|
||||
|| gimple_has_body_p (decl));
|
||||
gcc_assert (cnode->analyzed == cnode->local.finalized);
|
||||
gcc_assert (cnode->symbol.analyzed == cnode->symbol.definition);
|
||||
}
|
||||
node->symbol.aux = NULL;
|
||||
}
|
||||
|
|
@ -1071,13 +1060,13 @@ handle_alias_pairs (void)
|
|||
if (TREE_CODE (p->decl) == FUNCTION_DECL)
|
||||
{
|
||||
struct cgraph_node *anode = cgraph_get_create_node (p->decl);
|
||||
anode->alias = true;
|
||||
anode->symbol.alias = true;
|
||||
anode->thunk.alias = p->target;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct varpool_node *anode = varpool_get_node (p->decl);
|
||||
anode->alias = true;
|
||||
anode->symbol.alias = true;
|
||||
anode->alias_of = p->target;
|
||||
}
|
||||
DECL_EXTERNAL (p->decl) = 1;
|
||||
|
|
@ -1117,7 +1106,7 @@ handle_alias_pairs (void)
|
|||
&& target_node && is_a <cgraph_node> (target_node))
|
||||
{
|
||||
struct cgraph_node *src_node = cgraph_get_node (p->decl);
|
||||
if (src_node && src_node->local.finalized)
|
||||
if (src_node && src_node->symbol.definition)
|
||||
cgraph_reset_node (src_node);
|
||||
cgraph_create_function_alias (p->decl, target_node->symbol.decl);
|
||||
alias_pairs->unordered_remove (i);
|
||||
|
|
@ -1165,9 +1154,9 @@ mark_functions_to_output (void)
|
|||
/* We need to output all local functions that are used and not
|
||||
always inlined, as well as those that are reachable from
|
||||
outside the current compilation unit. */
|
||||
if (node->analyzed
|
||||
if (node->symbol.analyzed
|
||||
&& !node->thunk.thunk_p
|
||||
&& !node->alias
|
||||
&& !node->symbol.alias
|
||||
&& !node->global.inlined_to
|
||||
&& !TREE_ASM_WRITTEN (decl)
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
|
|
@ -1179,7 +1168,7 @@ mark_functions_to_output (void)
|
|||
for (next = cgraph (node->symbol.same_comdat_group);
|
||||
next != node;
|
||||
next = cgraph (next->symbol.same_comdat_group))
|
||||
if (!next->thunk.thunk_p && !next->alias)
|
||||
if (!next->thunk.thunk_p && !next->symbol.alias)
|
||||
next->process = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1199,7 +1188,7 @@ mark_functions_to_output (void)
|
|||
are inside partition, we can end up not removing the body since we no longer
|
||||
have analyzed node pointing to it. */
|
||||
&& !node->symbol.in_other_partition
|
||||
&& !node->alias
|
||||
&& !node->symbol.alias
|
||||
&& !node->clones
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
{
|
||||
|
|
@ -1435,7 +1424,7 @@ assemble_thunk (struct cgraph_node *node)
|
|||
set_cfun (NULL);
|
||||
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
|
||||
node->thunk.thunk_p = false;
|
||||
node->analyzed = false;
|
||||
node->symbol.analyzed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1800,7 +1789,7 @@ output_in_order (void)
|
|||
|
||||
FOR_EACH_DEFINED_FUNCTION (pf)
|
||||
{
|
||||
if (pf->process && !pf->thunk.thunk_p && !pf->alias)
|
||||
if (pf->process && !pf->thunk.thunk_p && !pf->symbol.alias)
|
||||
{
|
||||
i = pf->symbol.order;
|
||||
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
|
||||
|
|
@ -1943,14 +1932,14 @@ output_weakrefs (void)
|
|||
struct cgraph_node *node;
|
||||
struct varpool_node *vnode;
|
||||
FOR_EACH_FUNCTION (node)
|
||||
if (node->alias && DECL_EXTERNAL (node->symbol.decl)
|
||||
if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl)
|
||||
&& !TREE_ASM_WRITTEN (node->symbol.decl)
|
||||
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
|
||||
do_assemble_alias (node->symbol.decl,
|
||||
node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias)
|
||||
: get_alias_symbol (node->symbol.decl));
|
||||
FOR_EACH_VARIABLE (vnode)
|
||||
if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
|
||||
if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl)
|
||||
&& !TREE_ASM_WRITTEN (vnode->symbol.decl)
|
||||
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
|
||||
do_assemble_alias (vnode->symbol.decl,
|
||||
|
|
@ -2115,13 +2104,13 @@ finalize_compilation_unit (void)
|
|||
|
||||
/* Gimplify and lower all functions, compute reachability and
|
||||
remove unreachable nodes. */
|
||||
cgraph_analyze_functions ();
|
||||
analyze_functions ();
|
||||
|
||||
/* Mark alias targets necessary and emit diagnostics. */
|
||||
handle_alias_pairs ();
|
||||
|
||||
/* Gimplify and lower thunks. */
|
||||
cgraph_analyze_functions ();
|
||||
analyze_functions ();
|
||||
|
||||
/* Finally drive the pass manager. */
|
||||
compile ();
|
||||
|
|
|
|||
|
|
@ -29468,7 +29468,7 @@ ix86_get_function_versions_dispatcher (void *decl)
|
|||
dispatcher_version_info
|
||||
= insert_new_cgraph_node_version (dispatcher_node);
|
||||
dispatcher_version_info->next = default_version_info;
|
||||
dispatcher_node->local.finalized = 1;
|
||||
dispatcher_node->symbol.definition = 1;
|
||||
|
||||
/* Set the dispatcher for all the versions. */
|
||||
it_v = default_version_info;
|
||||
|
|
@ -29623,7 +29623,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
|
|||
default_ver_decl = node_version_info->next->this_node->symbol.decl;
|
||||
|
||||
/* node is going to be an alias, so remove the finalized bit. */
|
||||
node->local.finalized = false;
|
||||
node->symbol.definition = false;
|
||||
|
||||
resolver_decl = make_resolver_func (default_ver_decl,
|
||||
node->symbol.decl, &empty_bb);
|
||||
|
|
@ -29817,6 +29817,9 @@ fold_builtin_cpu (tree fndecl, tree *args)
|
|||
tree __cpu_model_var = make_var_decl (__processor_model_type,
|
||||
"__cpu_model");
|
||||
|
||||
|
||||
varpool_add_new_variable (__cpu_model_var);
|
||||
|
||||
gcc_assert ((args != NULL) && (*args != NULL));
|
||||
|
||||
param_string_cst = *args;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2013-05-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree.c (cp_fix_function_decl_p): Update for new symtab flags.
|
||||
* decl2.c )var_finalized_p, cp_write_global_declarations): Likewise.
|
||||
|
||||
2013-05-25 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/25666
|
||||
|
|
|
|||
|
|
@ -1803,7 +1803,7 @@ import_export_class (tree ctype)
|
|||
static bool
|
||||
var_finalized_p (tree var)
|
||||
{
|
||||
return varpool_node_for_decl (var)->finalized;
|
||||
return varpool_node_for_decl (var)->symbol.definition;
|
||||
}
|
||||
|
||||
/* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
|
||||
|
|
@ -4202,7 +4202,7 @@ cp_write_global_declarations (void)
|
|||
|
||||
node = cgraph_get_node (decl);
|
||||
if (node->same_body_alias)
|
||||
node = cgraph_alias_aliased_node (node);
|
||||
node = cgraph_alias_target (node);
|
||||
|
||||
cgraph_for_node_and_aliases (node, clear_decl_external,
|
||||
NULL, true);
|
||||
|
|
@ -4224,7 +4224,7 @@ cp_write_global_declarations (void)
|
|||
if (!DECL_EXTERNAL (decl)
|
||||
&& decl_needed_p (decl)
|
||||
&& !TREE_ASM_WRITTEN (decl)
|
||||
&& !cgraph_get_node (decl)->local.finalized)
|
||||
&& !cgraph_get_node (decl)->symbol.definition)
|
||||
{
|
||||
/* We will output the function; no longer consider it in this
|
||||
loop. */
|
||||
|
|
|
|||
|
|
@ -3980,7 +3980,7 @@ cp_fix_function_decl_p (tree decl)
|
|||
|
||||
/* Don't fix same_body aliases. Although they don't have their own
|
||||
CFG, they share it with what they alias to. */
|
||||
if (!node || !node->alias
|
||||
if (!node || !node->symbol.alias
|
||||
|| !vec_safe_length (node->symbol.ref_list.references))
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2480,7 +2480,7 @@ dbxout_expand_expr (tree expr)
|
|||
return NULL, otherwise stabs might reference an undefined
|
||||
symbol. */
|
||||
struct varpool_node *node = varpool_get_node (expr);
|
||||
if (!node || !node->analyzed)
|
||||
if (!node || !node->symbol.definition)
|
||||
return NULL;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
|
|
|||
|
|
@ -14919,7 +14919,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
|
|||
else if (TREE_CODE (*tp) == VAR_DECL)
|
||||
{
|
||||
struct varpool_node *node = varpool_get_node (*tp);
|
||||
if (!node || !node->analyzed)
|
||||
if (!node || !node->symbol.definition)
|
||||
return *tp;
|
||||
}
|
||||
else if (TREE_CODE (*tp) == FUNCTION_DECL
|
||||
|
|
@ -17597,7 +17597,7 @@ premark_types_used_by_global_vars_helper (void **slot,
|
|||
/* Ask cgraph if the global variable really is to be emitted.
|
||||
If yes, then we'll keep the DIE of ENTRY->TYPE. */
|
||||
struct varpool_node *node = varpool_get_node (entry->var_decl);
|
||||
if (node && node->analyzed)
|
||||
if (node && node->symbol.definition)
|
||||
{
|
||||
die->die_perennial_p = 1;
|
||||
/* Keep the parent DIEs as well. */
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
|
|||
The second is important when devirtualization happens during final
|
||||
compilation stage when making a new reference no longer makes callee
|
||||
to be compiled. */
|
||||
if (!node || !node->analyzed || node->global.inlined_to)
|
||||
if (!node || !node->symbol.definition || node->global.inlined_to)
|
||||
{
|
||||
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
|
||||
return false;
|
||||
|
|
@ -123,7 +123,7 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
|
|||
else if (TREE_CODE (decl) == VAR_DECL)
|
||||
{
|
||||
vnode = varpool_get_node (decl);
|
||||
if (!vnode || !vnode->analyzed)
|
||||
if (!vnode || !vnode->symbol.definition)
|
||||
{
|
||||
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
|
||||
return false;
|
||||
|
|
|
|||
17
gcc/ipa-cp.c
17
gcc/ipa-cp.c
|
|
@ -440,14 +440,14 @@ determine_versionability (struct cgraph_node *node)
|
|||
/* There are a number of generic reasons functions cannot be versioned. We
|
||||
also cannot remove parameters if there are type attributes such as fnspec
|
||||
present. */
|
||||
if (node->alias || node->thunk.thunk_p)
|
||||
if (node->symbol.alias || node->thunk.thunk_p)
|
||||
reason = "alias or thunk";
|
||||
else if (!node->local.versionable)
|
||||
reason = "not a tree_versionable_function";
|
||||
else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
|
||||
reason = "insufficient body availability";
|
||||
|
||||
if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
|
||||
if (reason && dump_file && !node->symbol.alias && !node->thunk.thunk_p)
|
||||
fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
|
||||
cgraph_node_name (node), node->symbol.order, reason);
|
||||
|
||||
|
|
@ -727,7 +727,7 @@ initialize_node_lattices (struct cgraph_node *node)
|
|||
set_all_contains_variable (plats);
|
||||
}
|
||||
if (dump_file && (dump_flags & TDF_DETAILS)
|
||||
&& !node->alias && !node->thunk.thunk_p)
|
||||
&& !node->symbol.alias && !node->thunk.thunk_p)
|
||||
fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
|
||||
cgraph_node_name (node), node->symbol.order,
|
||||
disable ? "BOTTOM" : "VARIABLE");
|
||||
|
|
@ -1418,7 +1418,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
|
|||
int i, args_count, parms_count;
|
||||
|
||||
callee = cgraph_function_node (cs->callee, &availability);
|
||||
if (!callee->analyzed)
|
||||
if (!callee->symbol.definition)
|
||||
return false;
|
||||
gcc_checking_assert (cgraph_function_with_gimple_body_p (callee));
|
||||
callee_info = IPA_NODE_REF (callee);
|
||||
|
|
@ -1431,8 +1431,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
|
|||
parameter. However, we might need to uncover a thunk from below a series
|
||||
of aliases first. */
|
||||
alias_or_thunk = cs->callee;
|
||||
while (alias_or_thunk->alias)
|
||||
alias_or_thunk = cgraph_alias_aliased_node (alias_or_thunk);
|
||||
while (alias_or_thunk->symbol.alias)
|
||||
alias_or_thunk = cgraph_alias_target (alias_or_thunk);
|
||||
if (alias_or_thunk->thunk.thunk_p)
|
||||
{
|
||||
ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
|
||||
|
|
@ -1601,7 +1601,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
|
|||
/* Only bare minimum benefit for clearly un-inlineable targets. */
|
||||
res += 1;
|
||||
callee = cgraph_get_node (target);
|
||||
if (!callee || !callee->analyzed)
|
||||
if (!callee || !callee->symbol.definition)
|
||||
continue;
|
||||
isummary = inline_summary (callee);
|
||||
if (!isummary->inlinable)
|
||||
|
|
@ -2231,9 +2231,10 @@ ipcp_propagate_stage (struct topo_info *topo)
|
|||
ipa_get_param_count (info));
|
||||
initialize_node_lattices (node);
|
||||
}
|
||||
if (node->symbol.definition && !node->symbol.alias)
|
||||
overall_size += inline_summary (node)->self_size;
|
||||
if (node->count > max_count)
|
||||
max_count = node->count;
|
||||
overall_size += inline_summary (node)->self_size;
|
||||
}
|
||||
|
||||
max_new_size = overall_size;
|
||||
|
|
|
|||
|
|
@ -1351,7 +1351,7 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
|
|||
void
|
||||
dump_inline_summary (FILE *f, struct cgraph_node *node)
|
||||
{
|
||||
if (node->analyzed)
|
||||
if (node->symbol.definition)
|
||||
{
|
||||
struct inline_summary *s = inline_summary (node);
|
||||
size_time_entry *e;
|
||||
|
|
@ -1427,7 +1427,7 @@ initialize_inline_failed (struct cgraph_edge *e)
|
|||
|
||||
if (e->indirect_unknown_callee)
|
||||
e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
|
||||
else if (!callee->analyzed)
|
||||
else if (!callee->symbol.definition)
|
||||
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
|
||||
else if (callee->local.redefined_extern_inline)
|
||||
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
|
||||
|
|
@ -2765,7 +2765,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
|
|||
gcc_checking_assert (*size >= 0);
|
||||
|
||||
callee = cgraph_get_node (target);
|
||||
if (!callee || !callee->analyzed)
|
||||
if (!callee || !callee->symbol.definition)
|
||||
return false;
|
||||
isummary = inline_summary (callee);
|
||||
return isummary->inlinable;
|
||||
|
|
@ -3683,7 +3683,7 @@ inline_generate_summary (void)
|
|||
inline_free_summary ();
|
||||
|
||||
FOR_EACH_DEFINED_FUNCTION (node)
|
||||
if (!node->alias)
|
||||
if (!node->symbol.alias)
|
||||
inline_analyze_function (node);
|
||||
}
|
||||
|
||||
|
|
@ -3917,7 +3917,7 @@ inline_write_summary (void)
|
|||
{
|
||||
symtab_node snode = lto_symtab_encoder_deref (encoder, i);
|
||||
cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
|
||||
if (cnode && cnode->analyzed)
|
||||
if (cnode && cnode->symbol.definition && !cnode->symbol.alias)
|
||||
count++;
|
||||
}
|
||||
streamer_write_uhwi (ob, count);
|
||||
|
|
@ -3926,7 +3926,7 @@ inline_write_summary (void)
|
|||
{
|
||||
symtab_node snode = lto_symtab_encoder_deref (encoder, i);
|
||||
cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
|
||||
if (cnode && (node = cnode)->analyzed)
|
||||
if (cnode && (node = cnode)->symbol.definition && !node->symbol.alias)
|
||||
{
|
||||
struct inline_summary *info = inline_summary (node);
|
||||
struct bitpack_d bp;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
|
|||
cgraph_remove_unreachable_functions gets rid of them. */
|
||||
gcc_assert (!e->callee->global.inlined_to);
|
||||
symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee);
|
||||
if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->symbol.decl))
|
||||
if (e->callee->symbol.definition && !DECL_EXTERNAL (e->callee->symbol.decl))
|
||||
{
|
||||
if (overall_size)
|
||||
*overall_size -= inline_summary (e->callee)->size;
|
||||
|
|
@ -236,7 +236,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
|
|||
if (!alias->callers
|
||||
&& can_remove_node_now_p (alias, e))
|
||||
{
|
||||
next_alias = cgraph_alias_aliased_node (alias);
|
||||
next_alias = cgraph_alias_target (alias);
|
||||
cgraph_remove_node (alias);
|
||||
alias = next_alias;
|
||||
}
|
||||
|
|
@ -381,7 +381,7 @@ static bool
|
|||
preserve_function_body_p (struct cgraph_node *node)
|
||||
{
|
||||
gcc_assert (cgraph_global_info_ready);
|
||||
gcc_assert (!node->alias && !node->thunk.thunk_p);
|
||||
gcc_assert (!node->symbol.alias && !node->thunk.thunk_p);
|
||||
|
||||
/* Look if there is any clone around. */
|
||||
if (node->clones)
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report)
|
|||
|
||||
gcc_assert (e->inline_failed);
|
||||
|
||||
if (!callee || !callee->analyzed)
|
||||
if (!callee || !callee->symbol.definition)
|
||||
{
|
||||
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
|
||||
inlinable = false;
|
||||
|
|
@ -1100,7 +1100,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
|
|||
int i;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
if ((!node->alias && !inline_summary (node)->inlinable)
|
||||
if ((!node->symbol.alias && !inline_summary (node)->inlinable)
|
||||
|| cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
|
||||
|| node->global.inlined_to)
|
||||
return;
|
||||
|
|
@ -1795,6 +1795,9 @@ ipa_inline (void)
|
|||
}
|
||||
|
||||
inline_small_functions ();
|
||||
|
||||
/* Do first after-inlining removal. We want to remove all "stale" extern inline
|
||||
functions and virtual functions so we really know what is called once. */
|
||||
symtab_remove_unreachable_nodes (false, dump_file);
|
||||
free (order);
|
||||
|
||||
|
|
|
|||
|
|
@ -1521,7 +1521,7 @@ ipa_compute_jump_functions (struct cgraph_node *node,
|
|||
NULL);
|
||||
/* We do not need to bother analyzing calls to unknown
|
||||
functions unless they may become known during lto/whopr. */
|
||||
if (!callee->analyzed && !flag_lto)
|
||||
if (!callee->symbol.definition && !flag_lto)
|
||||
continue;
|
||||
ipa_compute_jump_functions_for_edge (parms_ainfo, cs);
|
||||
}
|
||||
|
|
@ -2978,7 +2978,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
|
|||
tree temp;
|
||||
struct ipa_node_params *info;
|
||||
|
||||
if (!node->analyzed)
|
||||
if (!node->symbol.definition)
|
||||
return;
|
||||
info = IPA_NODE_REF (node);
|
||||
fprintf (f, " function %s/%i parameter descriptors:\n",
|
||||
|
|
@ -3972,7 +3972,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
|
|||
index = streamer_read_uhwi (&ib_main);
|
||||
encoder = file_data->symtab_node_encoder;
|
||||
node = cgraph (lto_symtab_encoder_deref (encoder, index));
|
||||
gcc_assert (node->analyzed);
|
||||
gcc_assert (node->symbol.definition);
|
||||
ipa_read_node_info (&ib_main, node, data_in);
|
||||
}
|
||||
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
|
||||
|
|
@ -4016,7 +4016,6 @@ ipa_update_after_lto_read (void)
|
|||
ipa_check_create_edge_args ();
|
||||
|
||||
FOR_EACH_DEFINED_FUNCTION (node)
|
||||
if (node->analyzed)
|
||||
ipa_initialize_node_params (node);
|
||||
}
|
||||
|
||||
|
|
@ -4154,7 +4153,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
|
|||
index = streamer_read_uhwi (&ib_main);
|
||||
encoder = file_data->symtab_node_encoder;
|
||||
node = cgraph (lto_symtab_encoder_deref (encoder, index));
|
||||
gcc_assert (node->analyzed);
|
||||
gcc_assert (node->symbol.definition);
|
||||
read_agg_replacement_chain (&ib_main, node, data_in);
|
||||
}
|
||||
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
|
||||
|
|
|
|||
|
|
@ -738,7 +738,7 @@ analyze_function (struct cgraph_node *fn, bool ipa)
|
|||
flags_from_decl_or_type (fn->symbol.decl),
|
||||
cgraph_node_cannot_return (fn));
|
||||
|
||||
if (fn->thunk.thunk_p || fn->alias)
|
||||
if (fn->thunk.thunk_p || fn->symbol.alias)
|
||||
{
|
||||
/* Thunk gets propagated through, so nothing interesting happens. */
|
||||
gcc_assert (ipa);
|
||||
|
|
@ -951,7 +951,7 @@ pure_const_write_summary (void)
|
|||
lsei_next_function_in_partition (&lsei))
|
||||
{
|
||||
node = lsei_cgraph_node (lsei);
|
||||
if (node->analyzed && has_function_state (node))
|
||||
if (node->symbol.definition && has_function_state (node))
|
||||
count++;
|
||||
}
|
||||
|
||||
|
|
@ -962,7 +962,7 @@ pure_const_write_summary (void)
|
|||
lsei_next_function_in_partition (&lsei))
|
||||
{
|
||||
node = lsei_cgraph_node (lsei);
|
||||
if (node->analyzed && has_function_state (node))
|
||||
if (node->symbol.definition && has_function_state (node))
|
||||
{
|
||||
struct bitpack_d bp;
|
||||
funct_state fs;
|
||||
|
|
@ -1124,7 +1124,7 @@ propagate_pure_const (void)
|
|||
int count = 0;
|
||||
node = order[i];
|
||||
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
continue;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
|
|
@ -1394,7 +1394,7 @@ propagate_nothrow (void)
|
|||
bool can_throw = false;
|
||||
node = order[i];
|
||||
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
continue;
|
||||
|
||||
/* Find the worst state for any node in the cycle. */
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ propagate (void)
|
|||
|| TREE_ADDRESSABLE (vnode->symbol.decl)
|
||||
|| TREE_READONLY (vnode->symbol.decl)
|
||||
|| !is_proper_for_analysis (vnode->symbol.decl)
|
||||
|| !vnode->analyzed)
|
||||
|| !vnode->symbol.definition)
|
||||
bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl));
|
||||
|
||||
/* Forget info we collected "just for fun" on variables that turned out to be
|
||||
|
|
@ -716,7 +716,7 @@ propagate (void)
|
|||
bool write_all = false;
|
||||
|
||||
node = order[i];
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
continue;
|
||||
|
||||
node_info = get_reference_vars_info (node);
|
||||
|
|
@ -794,7 +794,7 @@ propagate (void)
|
|||
struct cgraph_node *w;
|
||||
|
||||
node = order[i];
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
continue;
|
||||
|
||||
fprintf (dump_file,
|
||||
|
|
@ -835,7 +835,7 @@ propagate (void)
|
|||
ipa_reference_optimization_summary_t opt;
|
||||
|
||||
node_info = get_reference_vars_info (node);
|
||||
if (!node->alias
|
||||
if (!node->symbol.alias
|
||||
&& (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
|
||||
|| (flags_from_decl_or_type (node->symbol.decl) & ECF_LEAF)))
|
||||
{
|
||||
|
|
@ -894,7 +894,7 @@ write_node_summary_p (struct cgraph_node *node,
|
|||
ipa_reference_optimization_summary_t info;
|
||||
|
||||
/* See if we have (non-empty) info. */
|
||||
if (!node->analyzed || node->global.inlined_to)
|
||||
if (!node->symbol.definition || node->global.inlined_to)
|
||||
return false;
|
||||
info = get_reference_optimization_summary (node);
|
||||
if (!info || (bitmap_empty_p (info->statics_not_read)
|
||||
|
|
|
|||
|
|
@ -367,24 +367,47 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
|
|||
unsigned int i;
|
||||
int incoming_freq = 0;
|
||||
tree retval;
|
||||
bool back_edge = false;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
dump_split_point (dump_file, current);
|
||||
|
||||
FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
|
||||
{
|
||||
if (e->flags & EDGE_DFS_BACK)
|
||||
back_edge = true;
|
||||
if (!bitmap_bit_p (current->split_bbs, e->src->index))
|
||||
incoming_freq += EDGE_FREQUENCY (e);
|
||||
}
|
||||
|
||||
/* Do not split when we would end up calling function anyway. */
|
||||
if (incoming_freq
|
||||
>= (ENTRY_BLOCK_PTR->frequency
|
||||
* PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
|
||||
{
|
||||
/* When profile is guessed, we can not expect it to give us
|
||||
realistic estimate on likelyness of function taking the
|
||||
complex path. As a special case, when tail of the function is
|
||||
a loop, enable splitting since inlining code skipping the loop
|
||||
is likely noticeable win. */
|
||||
if (back_edge
|
||||
&& profile_status != PROFILE_READ
|
||||
&& incoming_freq < ENTRY_BLOCK_PTR->frequency)
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file,
|
||||
" Split before loop, accepting despite low frequencies %i %i.\n",
|
||||
incoming_freq,
|
||||
ENTRY_BLOCK_PTR->frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file,
|
||||
" Refused: incoming frequency is too large.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current->header_size)
|
||||
{
|
||||
|
|
@ -1533,6 +1556,11 @@ execute_split_functions (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* We enforce splitting after loop headers when profile info is not
|
||||
available. */
|
||||
if (profile_status != PROFILE_READ)
|
||||
mark_dfs_back_edges ();
|
||||
|
||||
/* Initialize bitmap to track forbidden calls. */
|
||||
forbidden_dominators = BITMAP_ALLOC (NULL);
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ ipa_reverse_postorder (struct cgraph_node **order)
|
|||
&& (pass
|
||||
|| (!node->symbol.address_taken
|
||||
&& !node->global.inlined_to
|
||||
&& !node->alias && !node->thunk.thunk_p
|
||||
&& !node->symbol.alias && !node->thunk.thunk_p
|
||||
&& !cgraph_only_called_directly_p (node))))
|
||||
{
|
||||
stack_size = 0;
|
||||
|
|
|
|||
173
gcc/ipa.c
173
gcc/ipa.c
|
|
@ -39,6 +39,53 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "lto-streamer.h"
|
||||
#include "data-streamer.h"
|
||||
|
||||
/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
|
||||
|
||||
static bool
|
||||
cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
|
||||
return !(cgraph_only_called_directly_or_aliased_p (node)
|
||||
&& !ipa_ref_has_aliases_p (&node->symbol.ref_list)
|
||||
&& node->symbol.definition
|
||||
&& !DECL_EXTERNAL (node->symbol.decl)
|
||||
&& !node->symbol.externally_visible
|
||||
&& !node->symbol.used_from_other_partition
|
||||
&& !node->symbol.in_other_partition);
|
||||
}
|
||||
|
||||
/* Return true when function can be marked local. */
|
||||
|
||||
static bool
|
||||
cgraph_local_node_p (struct cgraph_node *node)
|
||||
{
|
||||
struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
|
||||
|
||||
/* FIXME: thunks can be considered local, but we need prevent i386
|
||||
from attempting to change calling convention of them. */
|
||||
if (n->thunk.thunk_p)
|
||||
return false;
|
||||
return !cgraph_for_node_and_aliases (n,
|
||||
cgraph_non_local_node_p_1, NULL, true);
|
||||
|
||||
}
|
||||
|
||||
/* Return true when NODE has ADDR reference. */
|
||||
|
||||
static bool
|
||||
has_addr_references_p (struct cgraph_node *node,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
|
||||
i, ref); i++)
|
||||
if (ref->use == IPA_REF_ADDR)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Look for all functions inlined to NODE and update their inlined_to pointers
|
||||
to INLINED_TO. */
|
||||
|
||||
|
|
@ -89,79 +136,23 @@ process_references (struct ipa_ref_list *list,
|
|||
struct ipa_ref *ref;
|
||||
for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
|
||||
{
|
||||
if (is_a <cgraph_node> (ref->referred))
|
||||
{
|
||||
struct cgraph_node *node = ipa_ref_node (ref);
|
||||
symtab_node node = ref->referred;
|
||||
|
||||
if (node->analyzed
|
||||
if (node->symbol.definition
|
||||
&& (!DECL_EXTERNAL (node->symbol.decl)
|
||||
|| node->alias
|
||||
|| before_inlining_p))
|
||||
|| node->symbol.alias
|
||||
|| (before_inlining_p
|
||||
/* We use variable constructors during late complation for
|
||||
constant folding. Keep references alive so partitioning
|
||||
knows about potential references. */
|
||||
|| (TREE_CODE (node->symbol.decl) == VAR_DECL
|
||||
&& flag_wpa && const_value_known_p (node->symbol.decl)))))
|
||||
pointer_set_insert (reachable, node);
|
||||
enqueue_node ((symtab_node) node, first, reachable);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct varpool_node *node = ipa_ref_varpool_node (ref);
|
||||
|
||||
if (node->analyzed
|
||||
&& (!DECL_EXTERNAL (node->symbol.decl)
|
||||
|| node->alias
|
||||
|| before_inlining_p))
|
||||
pointer_set_insert (reachable, node);
|
||||
enqueue_node ((symtab_node) node, first, reachable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
|
||||
|
||||
static bool
|
||||
cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
|
||||
return !(cgraph_only_called_directly_or_aliased_p (node)
|
||||
&& !ipa_ref_has_aliases_p (&node->symbol.ref_list)
|
||||
&& node->analyzed
|
||||
&& !DECL_EXTERNAL (node->symbol.decl)
|
||||
&& !node->symbol.externally_visible
|
||||
&& !node->symbol.used_from_other_partition
|
||||
&& !node->symbol.in_other_partition);
|
||||
}
|
||||
|
||||
/* Return true when function can be marked local. */
|
||||
|
||||
static bool
|
||||
cgraph_local_node_p (struct cgraph_node *node)
|
||||
{
|
||||
struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
|
||||
|
||||
/* FIXME: thunks can be considered local, but we need prevent i386
|
||||
from attempting to change calling convention of them. */
|
||||
if (n->thunk.thunk_p)
|
||||
return false;
|
||||
return !cgraph_for_node_and_aliases (n,
|
||||
cgraph_non_local_node_p_1, NULL, true);
|
||||
|
||||
}
|
||||
|
||||
/* Return true when NODE has ADDR reference. */
|
||||
|
||||
static bool
|
||||
has_addr_references_p (struct cgraph_node *node,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
|
||||
i, ref); i++)
|
||||
if (ref->use == IPA_REF_ADDR)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Perform reachability analysis and reclaim all unreachable nodes.
|
||||
|
||||
The algorithm is basically mark&sweep but with some extra refinements:
|
||||
|
|
@ -303,10 +294,10 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
struct cgraph_edge *e;
|
||||
for (e = cnode->callees; e; e = e->next_callee)
|
||||
{
|
||||
if (e->callee->analyzed
|
||||
if (e->callee->symbol.definition
|
||||
&& (!e->inline_failed
|
||||
|| !DECL_EXTERNAL (e->callee->symbol.decl)
|
||||
|| cnode->alias
|
||||
|| cnode->symbol.alias
|
||||
|| before_inlining_p))
|
||||
pointer_set_insert (reachable, e->callee);
|
||||
enqueue_node ((symtab_node) e->callee, &first, reachable);
|
||||
|
|
@ -314,7 +305,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
|
||||
/* When inline clone exists, mark body to be preserved so when removing
|
||||
offline copy of the function we don't kill it. */
|
||||
if (!cnode->alias && cnode->global.inlined_to)
|
||||
if (!cnode->symbol.alias && cnode->global.inlined_to)
|
||||
pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +330,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
varpool_node *vnode = dyn_cast <varpool_node> (node);
|
||||
if (vnode
|
||||
&& DECL_EXTERNAL (node->symbol.decl)
|
||||
&& !vnode->alias
|
||||
&& !vnode->symbol.alias
|
||||
&& in_boundary_p)
|
||||
{
|
||||
struct ipa_ref *ref;
|
||||
|
|
@ -352,6 +343,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
for (node = cgraph_first_function (); node; node = next)
|
||||
{
|
||||
next = cgraph_next_function (node);
|
||||
|
||||
/* If node is not needed at all, remove it. */
|
||||
if (!node->symbol.aux)
|
||||
{
|
||||
if (file)
|
||||
|
|
@ -359,20 +352,18 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
cgraph_remove_node (node);
|
||||
changed = true;
|
||||
}
|
||||
/* If node is unreachable, remove its body. */
|
||||
else if (!pointer_set_contains (reachable, node))
|
||||
{
|
||||
if (node->analyzed)
|
||||
if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
|
||||
cgraph_release_function_body (node);
|
||||
if (node->symbol.definition)
|
||||
{
|
||||
if (file)
|
||||
fprintf (file, " %s", cgraph_node_name (node));
|
||||
cgraph_node_remove_callees (node);
|
||||
ipa_remove_all_references (&node->symbol.ref_list);
|
||||
cgraph_reset_node (node);
|
||||
changed = true;
|
||||
}
|
||||
if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl)
|
||||
&& (node->local.finalized || !DECL_ARTIFICIAL (node->symbol.decl)))
|
||||
cgraph_release_function_body (node);
|
||||
node->analyzed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -406,14 +397,20 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
}
|
||||
else if (!pointer_set_contains (reachable, vnode))
|
||||
{
|
||||
if (vnode->analyzed)
|
||||
if (vnode->symbol.definition)
|
||||
{
|
||||
if (file)
|
||||
fprintf (file, " %s", varpool_node_name (vnode));
|
||||
changed = true;
|
||||
}
|
||||
vnode->analyzed = false;
|
||||
vnode->symbol.definition = false;
|
||||
vnode->symbol.analyzed = false;
|
||||
vnode->symbol.aux = NULL;
|
||||
|
||||
/* Keep body if it may be useful for constant folding. */
|
||||
if (!const_value_known_p (vnode->symbol.decl))
|
||||
varpool_remove_initializer (vnode);
|
||||
ipa_remove_all_references (&vnode->symbol.ref_list);
|
||||
}
|
||||
else
|
||||
vnode->symbol.aux = NULL;
|
||||
|
|
@ -474,7 +471,7 @@ ipa_discover_readonly_nonaddressable_vars (void)
|
|||
if (dump_file)
|
||||
fprintf (dump_file, "Clearing variable flags:");
|
||||
FOR_EACH_VARIABLE (vnode)
|
||||
if (vnode->finalized && varpool_all_refs_explicit_p (vnode)
|
||||
if (vnode->symbol.definition && varpool_all_refs_explicit_p (vnode)
|
||||
&& (TREE_ADDRESSABLE (vnode->symbol.decl)
|
||||
|| !TREE_READONLY (vnode->symbol.decl)))
|
||||
{
|
||||
|
|
@ -546,12 +543,12 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
|
|||
Virtual functions do have their addresses taken from the vtables,
|
||||
but in C++ there is no way to compare their addresses for equality. */
|
||||
|
||||
bool
|
||||
static bool
|
||||
cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
|
||||
{
|
||||
if ((cgraph_address_taken_from_non_vtable_p (node)
|
||||
&& !DECL_VIRTUAL_P (node->symbol.decl))
|
||||
|| !node->analyzed)
|
||||
|| !node->symbol.definition)
|
||||
return false;
|
||||
if (node->symbol.same_comdat_group)
|
||||
{
|
||||
|
|
@ -575,7 +572,7 @@ static bool
|
|||
cgraph_externally_visible_p (struct cgraph_node *node,
|
||||
bool whole_program)
|
||||
{
|
||||
if (!node->local.finalized)
|
||||
if (!node->symbol.definition)
|
||||
return false;
|
||||
if (!DECL_COMDAT (node->symbol.decl)
|
||||
&& (!TREE_PUBLIC (node->symbol.decl)
|
||||
|
|
@ -619,7 +616,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
|
|||
|| DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
|
||||
/* Be sure that node is defined in IR file, not in other object
|
||||
file. In that case we don't set used_from_other_object_file. */
|
||||
&& node->analyzed)
|
||||
&& node->symbol.definition)
|
||||
;
|
||||
else if (!whole_program)
|
||||
return true;
|
||||
|
|
@ -638,7 +635,7 @@ varpool_externally_visible_p (struct varpool_node *vnode)
|
|||
/* Do not touch weakrefs; while they are not externally visible,
|
||||
dropping their DECL_EXTERNAL flags confuse most
|
||||
of code handling them. */
|
||||
if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl))
|
||||
if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl))
|
||||
return true;
|
||||
|
||||
if (DECL_EXTERNAL (vnode->symbol.decl))
|
||||
|
|
@ -690,7 +687,7 @@ varpool_externally_visible_p (struct varpool_node *vnode)
|
|||
|| DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
|
||||
/* Be sure that node is defined in IR file, not in other object
|
||||
file. In that case we don't set used_from_other_object_file. */
|
||||
&& vnode->finalized)
|
||||
&& vnode->symbol.definition)
|
||||
;
|
||||
else if (!flag_whole_program)
|
||||
return true;
|
||||
|
|
@ -744,7 +741,7 @@ function_and_variable_visibility (bool whole_program)
|
|||
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->analyzed))
|
||||
&& (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition))
|
||||
node->symbol.force_output = 0;
|
||||
|
||||
/* C++ FE on lack of COMDAT support create local COMDAT functions
|
||||
|
|
@ -781,7 +778,7 @@ function_and_variable_visibility (bool whole_program)
|
|||
}
|
||||
else
|
||||
node->symbol.externally_visible = false;
|
||||
if (!node->symbol.externally_visible && node->analyzed
|
||||
if (!node->symbol.externally_visible && node->symbol.definition
|
||||
&& !DECL_EXTERNAL (node->symbol.decl))
|
||||
{
|
||||
gcc_assert (whole_program || in_lto_p
|
||||
|
|
@ -854,7 +851,7 @@ function_and_variable_visibility (bool whole_program)
|
|||
}
|
||||
FOR_EACH_DEFINED_VARIABLE (vnode)
|
||||
{
|
||||
if (!vnode->finalized)
|
||||
if (!vnode->symbol.definition)
|
||||
continue;
|
||||
if (varpool_externally_visible_p (vnode))
|
||||
vnode->symbol.externally_visible = true;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2013-05-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* decl.c (java_mark_decl_local): Update for new symtab flags.
|
||||
|
||||
2013-05-22 Matthias Klose <doko@ubuntu.com>
|
||||
|
||||
* jvspec.c (jvgenmain_spec): Add %I to cc1 call.
|
||||
|
|
|
|||
|
|
@ -1904,7 +1904,7 @@ java_mark_decl_local (tree decl)
|
|||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
struct cgraph_node *node = cgraph_get_node (decl);
|
||||
gcc_assert (!node || !node->local.finalized);
|
||||
gcc_assert (!node || !node->symbol.definition);
|
||||
}
|
||||
#endif
|
||||
gcc_assert (!DECL_RTL_SET_P (decl));
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ bool
|
|||
reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t encoder)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
if (!node->analyzed)
|
||||
if (!node->symbol.definition)
|
||||
return false;
|
||||
if (node->global.inlined_to)
|
||||
return false;
|
||||
|
|
@ -380,7 +380,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|
|||
|
||||
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node);
|
||||
|
||||
if (node->analyzed && !boundary_p)
|
||||
if (node->symbol.analyzed && !boundary_p)
|
||||
tag = LTO_symtab_analyzed_node;
|
||||
else
|
||||
tag = LTO_symtab_unavail_node;
|
||||
|
|
@ -399,7 +399,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|
|||
Cherry-picked nodes: These are nodes we pulled from other
|
||||
translation units into SET during IPA-inlining. We make them as
|
||||
local static nodes to prevent clashes with other local statics. */
|
||||
if (boundary_p && node->analyzed && !DECL_EXTERNAL (node->symbol.decl))
|
||||
if (boundary_p && node->symbol.analyzed && !DECL_EXTERNAL (node->symbol.decl))
|
||||
{
|
||||
/* Inline clones can not be part of boundary.
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
|
|
@ -463,7 +463,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|
|||
bp = bitpack_create (ob->main_stream);
|
||||
bp_pack_value (&bp, node->local.local, 1);
|
||||
bp_pack_value (&bp, node->symbol.externally_visible, 1);
|
||||
bp_pack_value (&bp, node->local.finalized, 1);
|
||||
bp_pack_value (&bp, node->symbol.definition, 1);
|
||||
bp_pack_value (&bp, node->local.versionable, 1);
|
||||
bp_pack_value (&bp, node->local.can_change_signature, 1);
|
||||
bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
|
||||
|
|
@ -485,7 +485,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|
|||
defined in other unit, we may use the info on aliases to resolve
|
||||
symbol1 != symbol2 type tests that we can do only for locally defined objects
|
||||
otherwise. */
|
||||
bp_pack_value (&bp, node->alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)), 1);
|
||||
bp_pack_value (&bp, node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)), 1);
|
||||
bp_pack_value (&bp, node->frequency, 2);
|
||||
bp_pack_value (&bp, node->only_called_at_startup, 1);
|
||||
bp_pack_value (&bp, node->only_called_at_exit, 1);
|
||||
|
|
@ -504,8 +504,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|
|||
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
|
||||
streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
|
||||
}
|
||||
if ((node->alias || node->thunk.thunk_p)
|
||||
&& (!boundary_p || (node->alias && DECL_EXTERNAL (node->symbol.decl))))
|
||||
if ((node->symbol.alias || node->thunk.thunk_p)
|
||||
&& (!boundary_p || (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl))))
|
||||
{
|
||||
streamer_write_hwi_in_range (ob->main_stream, 0, 1,
|
||||
node->thunk.alias != NULL);
|
||||
|
|
@ -522,7 +522,7 @@ static void
|
|||
lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node,
|
||||
lto_symtab_encoder_t encoder)
|
||||
{
|
||||
bool boundary_p = (node->analyzed
|
||||
bool boundary_p = (node->symbol.definition
|
||||
&& !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node));
|
||||
struct bitpack_d bp;
|
||||
int ref;
|
||||
|
|
@ -535,10 +535,10 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
|
|||
bp_pack_value (&bp, node->symbol.externally_visible, 1);
|
||||
bp_pack_value (&bp, node->symbol.force_output, 1);
|
||||
bp_pack_value (&bp, node->symbol.unique_name, 1);
|
||||
bp_pack_value (&bp, node->finalized, 1);
|
||||
bp_pack_value (&bp, node->alias, 1);
|
||||
bp_pack_value (&bp, node->symbol.definition, 1);
|
||||
bp_pack_value (&bp, node->symbol.alias, 1);
|
||||
bp_pack_value (&bp, node->alias_of != NULL, 1);
|
||||
gcc_assert (node->finalized || !node->analyzed);
|
||||
gcc_assert (node->symbol.definition || !node->symbol.analyzed);
|
||||
/* Constant pool initializers can be de-unified into individual ltrans units.
|
||||
FIXME: Alternatively at -Os we may want to avoid generating for them the local
|
||||
labels and share them across LTRANS partitions. */
|
||||
|
|
@ -551,7 +551,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
|
|||
}
|
||||
else
|
||||
{
|
||||
bp_pack_value (&bp, node->analyzed
|
||||
bp_pack_value (&bp, node->symbol.definition
|
||||
&& referenced_from_other_partition_p (&node->symbol.ref_list,
|
||||
encoder), 1);
|
||||
bp_pack_value (&bp, boundary_p && !DECL_EXTERNAL (node->symbol.decl), 1);
|
||||
|
|
@ -756,7 +756,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
|
|||
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
|
||||
{
|
||||
struct varpool_node *vnode = lsei_varpool_node (lsei);
|
||||
gcc_assert (!vnode->alias || vnode->alias_of);
|
||||
gcc_assert (!vnode->symbol.alias || vnode->alias_of);
|
||||
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
|
||||
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
|
||||
add_references (encoder, &vnode->symbol.ref_list);
|
||||
|
|
@ -883,7 +883,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
|
|||
|
||||
node->local.local = bp_unpack_value (bp, 1);
|
||||
node->symbol.externally_visible = bp_unpack_value (bp, 1);
|
||||
node->local.finalized = bp_unpack_value (bp, 1);
|
||||
node->symbol.definition = bp_unpack_value (bp, 1);
|
||||
node->local.versionable = 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);
|
||||
|
|
@ -893,7 +893,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
|
|||
node->abstract_and_needed = bp_unpack_value (bp, 1);
|
||||
node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
|
||||
node->lowered = bp_unpack_value (bp, 1);
|
||||
node->analyzed = tag == LTO_symtab_analyzed_node;
|
||||
node->symbol.analyzed = tag == LTO_symtab_analyzed_node;
|
||||
node->symbol.in_other_partition = bp_unpack_value (bp, 1);
|
||||
if (node->symbol.in_other_partition
|
||||
/* Avoid updating decl when we are seeing just inline clone.
|
||||
|
|
@ -909,7 +909,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
|
|||
DECL_EXTERNAL (node->symbol.decl) = 1;
|
||||
TREE_STATIC (node->symbol.decl) = 0;
|
||||
}
|
||||
node->alias = bp_unpack_value (bp, 1);
|
||||
node->symbol.alias = bp_unpack_value (bp, 1);
|
||||
node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
|
||||
node->only_called_at_startup = bp_unpack_value (bp, 1);
|
||||
node->only_called_at_exit = bp_unpack_value (bp, 1);
|
||||
|
|
@ -1004,7 +1004,7 @@ input_node (struct lto_file_decl_data *file_data,
|
|||
node->thunk.virtual_value = virtual_value;
|
||||
node->thunk.virtual_offset_p = (type & 4);
|
||||
}
|
||||
if (node->thunk.thunk_p || node->alias)
|
||||
if (node->thunk.thunk_p || node->symbol.alias)
|
||||
{
|
||||
if (streamer_read_hwi_in_range (ib, "alias nonzero flag", 0, 1))
|
||||
{
|
||||
|
|
@ -1044,12 +1044,12 @@ input_varpool_node (struct lto_file_decl_data *file_data,
|
|||
node->symbol.externally_visible = bp_unpack_value (&bp, 1);
|
||||
node->symbol.force_output = bp_unpack_value (&bp, 1);
|
||||
node->symbol.unique_name = bp_unpack_value (&bp, 1);
|
||||
node->finalized = bp_unpack_value (&bp, 1);
|
||||
node->alias = bp_unpack_value (&bp, 1);
|
||||
node->symbol.definition = bp_unpack_value (&bp, 1);
|
||||
node->symbol.alias = bp_unpack_value (&bp, 1);
|
||||
non_null_aliasof = bp_unpack_value (&bp, 1);
|
||||
node->symbol.used_from_other_partition = bp_unpack_value (&bp, 1);
|
||||
node->symbol.in_other_partition = bp_unpack_value (&bp, 1);
|
||||
node->analyzed = (node->finalized && (!node->alias || !node->symbol.in_other_partition));
|
||||
node->symbol.analyzed = (node->symbol.definition && (!node->symbol.alias || !node->symbol.in_other_partition));
|
||||
if (node->symbol.in_other_partition)
|
||||
{
|
||||
DECL_EXTERNAL (node->symbol.decl) = 1;
|
||||
|
|
|
|||
|
|
@ -1013,7 +1013,7 @@ lto_output (void)
|
|||
cgraph_node *node = dyn_cast <cgraph_node> (snode);
|
||||
if (node
|
||||
&& lto_symtab_encoder_encode_body_p (encoder, node)
|
||||
&& !node->alias
|
||||
&& !node->symbol.alias
|
||||
&& !node->thunk.thunk_p)
|
||||
{
|
||||
#ifdef ENABLE_CHECKING
|
||||
|
|
@ -1243,10 +1243,10 @@ write_symbol (struct streamer_tree_cache_d *cache,
|
|||
|
||||
/* When something is defined, it should have node attached. */
|
||||
gcc_assert (alias || TREE_CODE (t) != VAR_DECL
|
||||
|| varpool_get_node (t)->finalized);
|
||||
|| varpool_get_node (t)->symbol.definition);
|
||||
gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
|
||||
|| (cgraph_get_node (t)
|
||||
&& cgraph_get_node (t)->analyzed));
|
||||
&& cgraph_get_node (t)->symbol.definition));
|
||||
}
|
||||
|
||||
/* Imitate what default_elf_asm_output_external do.
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ static void
|
|||
lto_varpool_replace_node (struct varpool_node *vnode,
|
||||
struct varpool_node *prevailing_node)
|
||||
{
|
||||
gcc_assert (!vnode->finalized || prevailing_node->finalized);
|
||||
gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
|
||||
gcc_assert (!vnode->symbol.definition || prevailing_node->symbol.definition);
|
||||
gcc_assert (!vnode->symbol.analyzed || prevailing_node->symbol.analyzed);
|
||||
|
||||
ipa_clone_referring ((symtab_node)prevailing_node, &vnode->symbol.ref_list);
|
||||
|
||||
|
|
@ -255,14 +255,7 @@ lto_symtab_resolve_can_prevail_p (symtab_node e)
|
|||
if (DECL_EXTERNAL (e->symbol.decl))
|
||||
return false;
|
||||
|
||||
/* For functions we need a non-discarded body. */
|
||||
if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
|
||||
return (cgraph (e)->analyzed);
|
||||
|
||||
else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
|
||||
return varpool (e)->finalized;
|
||||
|
||||
gcc_unreachable ();
|
||||
return e->symbol.definition;
|
||||
}
|
||||
|
||||
/* Resolve the symbol with the candidates in the chain *SLOT and store
|
||||
|
|
@ -594,33 +587,33 @@ lto_symtab_merge_cgraph_nodes (void)
|
|||
FOR_EACH_FUNCTION (cnode)
|
||||
{
|
||||
/* Resolve weakrefs to symbol defined in other unit. */
|
||||
if (!cnode->analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
|
||||
if (!cnode->symbol.analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
|
||||
{
|
||||
symtab_node node = symtab_node_for_asm (cnode->thunk.alias);
|
||||
if (node && is_a <cgraph_node> (node))
|
||||
{
|
||||
struct cgraph_node *n;
|
||||
|
||||
for (n = cgraph (node); n && n->alias;
|
||||
n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
|
||||
for (n = cgraph (node); n && n->symbol.alias;
|
||||
n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL)
|
||||
if (n == cnode)
|
||||
{
|
||||
error ("function %q+D part of alias cycle", cnode->symbol.decl);
|
||||
cnode->alias = false;
|
||||
cnode->symbol.alias = false;
|
||||
break;
|
||||
}
|
||||
if (cnode->alias)
|
||||
if (cnode->symbol.alias)
|
||||
{
|
||||
cgraph_create_function_alias (cnode->symbol.decl, node->symbol.decl);
|
||||
ipa_record_reference ((symtab_node)cnode, (symtab_node)node,
|
||||
IPA_REF_ALIAS, NULL);
|
||||
cnode->analyzed = true;
|
||||
cnode->symbol.analyzed = true;
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
error ("%q+D alias in between function and variable is not supported", cnode->symbol.decl);
|
||||
}
|
||||
if ((cnode->thunk.thunk_p || cnode->alias)
|
||||
if ((cnode->thunk.thunk_p || cnode->symbol.alias)
|
||||
&& cnode->thunk.alias && DECL_P (cnode->thunk.alias))
|
||||
cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
|
||||
cnode->symbol.aux = NULL;
|
||||
|
|
@ -628,33 +621,33 @@ lto_symtab_merge_cgraph_nodes (void)
|
|||
FOR_EACH_VARIABLE (vnode)
|
||||
{
|
||||
/* Resolve weakrefs to symbol defined in other unit. */
|
||||
if (!vnode->analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
|
||||
if (!vnode->symbol.analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
|
||||
{
|
||||
symtab_node node = symtab_node_for_asm (vnode->alias_of);
|
||||
if (node && is_a <cgraph_node> (node))
|
||||
{
|
||||
struct varpool_node *n;
|
||||
|
||||
for (n = varpool (node); n && n->alias;
|
||||
n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
|
||||
for (n = varpool (node); n && n->symbol.alias;
|
||||
n = n->symbol.analyzed ? varpool_alias_target (n) : NULL)
|
||||
if (n == vnode)
|
||||
{
|
||||
error ("function %q+D part of alias cycle", vnode->symbol.decl);
|
||||
vnode->alias = false;
|
||||
vnode->symbol.alias = false;
|
||||
break;
|
||||
}
|
||||
if (vnode->alias)
|
||||
if (vnode->symbol.alias)
|
||||
{
|
||||
varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl);
|
||||
ipa_record_reference ((symtab_node)vnode, (symtab_node)node,
|
||||
IPA_REF_ALIAS, NULL);
|
||||
vnode->analyzed = true;
|
||||
vnode->symbol.analyzed = true;
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
|
||||
}
|
||||
if (vnode->alias_of)
|
||||
if (vnode->symbol.alias && DECL_P (vnode->alias_of))
|
||||
vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
|
||||
vnode->symbol.aux = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
2013-05-29 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab
|
||||
flags.
|
||||
* lto-partition.c (get_symbol_class, lto_balanced_map): Likewise.
|
||||
|
||||
2013-05-15 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto-partition.c (privatize_symbol_name): Return true when
|
||||
|
|
|
|||
|
|
@ -74,13 +74,13 @@ get_symbol_class (symtab_node node)
|
|||
objects that can not be duplicated across partitions. */
|
||||
if (DECL_IN_CONSTANT_POOL (node->symbol.decl))
|
||||
return SYMBOL_DUPLICATE;
|
||||
gcc_checking_assert (vnode->analyzed);
|
||||
gcc_checking_assert (vnode->symbol.definition);
|
||||
}
|
||||
/* Functions that are cloned may stay in callgraph even if they are unused.
|
||||
Handle them as external; compute_ltrans_boundary take care to make
|
||||
proper things to happen (i.e. to make them appear in the boundary but
|
||||
with body streamed, so clone can me materialized). */
|
||||
else if (!cgraph (node)->analyzed)
|
||||
else if (!cgraph (node)->symbol.definition)
|
||||
return SYMBOL_EXTERNAL;
|
||||
|
||||
/* Comdats are duplicated to every use unless they are keyed.
|
||||
|
|
@ -561,12 +561,12 @@ lto_balanced_map (void)
|
|||
|
||||
last_visited_node++;
|
||||
|
||||
gcc_assert (node->analyzed
|
||||
gcc_assert (node->symbol.definition
|
||||
|| lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)));
|
||||
|
||||
/* Compute boundary cost of callgraph edges. */
|
||||
for (edge = node->callees; edge; edge = edge->next_callee)
|
||||
if (edge->callee->analyzed)
|
||||
if (edge->callee->symbol.definition)
|
||||
{
|
||||
int edge_cost = edge->frequency;
|
||||
int index;
|
||||
|
|
@ -587,7 +587,7 @@ lto_balanced_map (void)
|
|||
int edge_cost = edge->frequency;
|
||||
int index;
|
||||
|
||||
gcc_assert (edge->caller->analyzed);
|
||||
gcc_assert (edge->caller->symbol.definition);
|
||||
if (!edge_cost)
|
||||
edge_cost = 1;
|
||||
gcc_assert (edge_cost > 0);
|
||||
|
|
@ -614,7 +614,7 @@ lto_balanced_map (void)
|
|||
int index;
|
||||
|
||||
vnode = ipa_ref_varpool_node (ref);
|
||||
if (!vnode->finalized)
|
||||
if (!vnode->symbol.definition)
|
||||
continue;
|
||||
if (!symbol_partitioned_p ((symtab_node) vnode) && flag_toplevel_reorder
|
||||
&& get_symbol_class ((symtab_node) vnode) == SYMBOL_PARTITION)
|
||||
|
|
@ -632,7 +632,7 @@ lto_balanced_map (void)
|
|||
int index;
|
||||
|
||||
node = ipa_ref_node (ref);
|
||||
if (!node->analyzed)
|
||||
if (!node->symbol.definition)
|
||||
continue;
|
||||
index = lto_symtab_encoder_lookup (partition->encoder,
|
||||
(symtab_node)node);
|
||||
|
|
@ -648,7 +648,7 @@ lto_balanced_map (void)
|
|||
int index;
|
||||
|
||||
vnode = ipa_ref_referring_varpool_node (ref);
|
||||
gcc_assert (vnode->finalized);
|
||||
gcc_assert (vnode->symbol.definition);
|
||||
if (!symbol_partitioned_p ((symtab_node) vnode) && flag_toplevel_reorder
|
||||
&& get_symbol_class ((symtab_node) vnode) == SYMBOL_PARTITION)
|
||||
add_symbol_to_partition (partition, (symtab_node) vnode);
|
||||
|
|
@ -665,7 +665,7 @@ lto_balanced_map (void)
|
|||
int index;
|
||||
|
||||
node = ipa_ref_referring_node (ref);
|
||||
gcc_assert (node->analyzed);
|
||||
gcc_assert (node->symbol.definition);
|
||||
index = lto_symtab_encoder_lookup (partition->encoder,
|
||||
(symtab_node)node);
|
||||
if (index != LCC_NOT_FOUND
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ has_analyzed_clone_p (struct cgraph_node *node)
|
|||
if (node)
|
||||
while (node != orig)
|
||||
{
|
||||
if (node->analyzed)
|
||||
if (node->symbol.analyzed)
|
||||
return true;
|
||||
if (node->clones)
|
||||
node = node->clones;
|
||||
|
|
@ -196,7 +196,8 @@ lto_materialize_function (struct cgraph_node *node)
|
|||
decl = node->symbol.decl;
|
||||
/* Read in functions with body (analyzed nodes)
|
||||
and also functions that are needed to produce virtual clones. */
|
||||
if (cgraph_function_with_gimple_body_p (node) || has_analyzed_clone_p (node))
|
||||
if ((cgraph_function_with_gimple_body_p (node) && node->symbol.analyzed)
|
||||
|| has_analyzed_clone_p (node))
|
||||
{
|
||||
/* Clones don't need to be read. */
|
||||
if (node->clone_of)
|
||||
|
|
|
|||
|
|
@ -2492,12 +2492,12 @@ ipa_write_summaries (void)
|
|||
renumber_gimple_stmt_uids ();
|
||||
pop_cfun ();
|
||||
}
|
||||
if (node->analyzed)
|
||||
if (node->symbol.definition)
|
||||
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
|
||||
}
|
||||
|
||||
FOR_EACH_DEFINED_VARIABLE (vnode)
|
||||
if ((!vnode->alias || vnode->alias_of))
|
||||
if ((!vnode->symbol.alias || vnode->alias_of))
|
||||
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
|
||||
|
||||
ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
|
||||
|
|
@ -2564,7 +2564,7 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder)
|
|||
|
||||
For functions newly born at WPA stage we need to initialize
|
||||
the uids here. */
|
||||
if (node->analyzed
|
||||
if (node->symbol.definition
|
||||
&& gimple_has_body_p (node->symbol.decl))
|
||||
{
|
||||
push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
|
||||
|
|
|
|||
52
gcc/symtab.c
52
gcc/symtab.c
|
|
@ -473,9 +473,15 @@ dump_symtab_base (FILE *f, symtab_node node)
|
|||
node->symbol.order,
|
||||
symtab_node_name (node));
|
||||
dump_addr (f, " @", (void *)node);
|
||||
fprintf (f, "\n Type: %s\n", symtab_type_names[node->symbol.type]);
|
||||
fprintf (f, " Visibility:");
|
||||
fprintf (f, "\n Type: %s", symtab_type_names[node->symbol.type]);
|
||||
|
||||
if (node->symbol.definition)
|
||||
fprintf (f, " definition");
|
||||
if (node->symbol.analyzed)
|
||||
fprintf (f, " analyzed");
|
||||
if (node->symbol.alias)
|
||||
fprintf (f, " alias");
|
||||
fprintf (f, "\n Visibility:");
|
||||
if (node->symbol.in_other_partition)
|
||||
fprintf (f, " in_other_partition");
|
||||
if (node->symbol.used_from_other_partition)
|
||||
|
|
@ -653,6 +659,12 @@ verify_symtab_base (symtab_node node)
|
|||
&& node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node)
|
||||
{
|
||||
error ("double linked list of assembler names corrupted");
|
||||
error_found = true;
|
||||
}
|
||||
if (node->symbol.analyzed && !node->symbol.definition)
|
||||
{
|
||||
error ("node is analyzed byt it is not a definition");
|
||||
error_found = true;
|
||||
}
|
||||
if (node->symbol.same_comdat_group)
|
||||
{
|
||||
|
|
@ -783,4 +795,40 @@ symtab_make_decl_local (tree decl)
|
|||
|
||||
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
|
||||
}
|
||||
|
||||
/* Given NODE, walk the alias chain to return the symbol NODE is alias of.
|
||||
If NODE is not an alias, return NODE.
|
||||
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
|
||||
|
||||
symtab_node
|
||||
symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
|
||||
{
|
||||
if (availability)
|
||||
{
|
||||
if (is_a <cgraph_node> (node))
|
||||
*availability = cgraph_function_body_availability (cgraph (node));
|
||||
else
|
||||
*availability = cgraph_variable_initializer_availability (varpool (node));
|
||||
}
|
||||
while (node)
|
||||
{
|
||||
if (node->symbol.alias && node->symbol.analyzed)
|
||||
node = symtab_alias_target (node);
|
||||
else
|
||||
return node;
|
||||
if (node && availability)
|
||||
{
|
||||
enum availability a;
|
||||
if (is_a <cgraph_node> (node))
|
||||
a = cgraph_function_body_availability (cgraph (node));
|
||||
else
|
||||
a = cgraph_variable_initializer_availability (varpool (node));
|
||||
if (a < *availability)
|
||||
*availability = a;
|
||||
}
|
||||
}
|
||||
if (availability)
|
||||
*availability = AVAIL_NOT_AVAILABLE;
|
||||
return NULL;
|
||||
}
|
||||
#include "gt-symtab.h"
|
||||
|
|
|
|||
|
|
@ -393,15 +393,15 @@ wrapup_global_declaration_2 (tree decl)
|
|||
|
||||
if (!node && flag_ltrans)
|
||||
needed = false;
|
||||
else if (node && node->finalized)
|
||||
else if (node && node->symbol.definition)
|
||||
needed = false;
|
||||
else if (node && node->alias)
|
||||
else if (node && node->symbol.alias)
|
||||
needed = false;
|
||||
else if (!cgraph_global_info_ready
|
||||
&& (TREE_USED (decl)
|
||||
|| TREE_USED (DECL_ASSEMBLER_NAME (decl))))
|
||||
/* needed */;
|
||||
else if (node && node->analyzed)
|
||||
else if (node && node->symbol.analyzed)
|
||||
/* needed */;
|
||||
else if (DECL_COMDAT (decl))
|
||||
needed = false;
|
||||
|
|
|
|||
|
|
@ -3932,7 +3932,7 @@ get_cg_data (struct cgraph_node **node, bool traverse_aliases)
|
|||
{
|
||||
struct tm_ipa_cg_data *d;
|
||||
|
||||
if (traverse_aliases && (*node)->alias)
|
||||
if (traverse_aliases && (*node)->symbol.alias)
|
||||
*node = cgraph_get_node ((*node)->thunk.alias);
|
||||
|
||||
d = (struct tm_ipa_cg_data *) (*node)->symbol.aux;
|
||||
|
|
@ -4518,7 +4518,7 @@ ipa_tm_mayenterirr_function (struct cgraph_node *node)
|
|||
/* Recurse on the main body for aliases. In general, this will
|
||||
result in one of the bits above being set so that we will not
|
||||
have to recurse next time. */
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
return ipa_tm_mayenterirr_function (cgraph_get_node (node->thunk.alias));
|
||||
|
||||
/* What remains is unmarked local functions without items that force
|
||||
|
|
@ -4678,9 +4678,7 @@ static inline void
|
|||
ipa_tm_mark_force_output_node (struct cgraph_node *node)
|
||||
{
|
||||
cgraph_mark_force_output_node (node);
|
||||
/* ??? function_and_variable_visibility will reset
|
||||
the needed bit, without actually checking. */
|
||||
node->analyzed = 1;
|
||||
node->symbol.analyzed = true;
|
||||
}
|
||||
|
||||
/* Callback data for ipa_tm_create_version_alias. */
|
||||
|
|
@ -5250,7 +5248,7 @@ ipa_tm_execute (void)
|
|||
{
|
||||
/* If this is an alias, make sure its base is queued as well.
|
||||
we need not scan the callees now, as the base will do. */
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
{
|
||||
node = cgraph_get_node (node->thunk.alias);
|
||||
d = get_cg_data (&node, true);
|
||||
|
|
@ -5393,7 +5391,7 @@ ipa_tm_execute (void)
|
|||
for (i = 0; i < tm_callees.length (); ++i)
|
||||
{
|
||||
node = tm_callees[i];
|
||||
if (node->analyzed)
|
||||
if (node->symbol.analyzed)
|
||||
{
|
||||
d = get_cg_data (&node, true);
|
||||
if (d->clone)
|
||||
|
|
|
|||
|
|
@ -2580,7 +2580,7 @@ tree_could_trap_p (tree expr)
|
|||
/* Assume that accesses to weak functions may trap, unless we know
|
||||
they are certainly defined in current TU or in some other
|
||||
LTO partition. */
|
||||
if (DECL_WEAK (expr))
|
||||
if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
if (!DECL_EXTERNAL (expr))
|
||||
|
|
@ -2596,7 +2596,7 @@ tree_could_trap_p (tree expr)
|
|||
/* Assume that accesses to weak vars may trap, unless we know
|
||||
they are certainly defined in current TU or in some other
|
||||
LTO partition. */
|
||||
if (DECL_WEAK (expr))
|
||||
if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
|
||||
{
|
||||
struct varpool_node *node;
|
||||
if (!DECL_EXTERNAL (expr))
|
||||
|
|
|
|||
|
|
@ -704,15 +704,15 @@ create_emultls_var (struct varpool_node *var, void *data)
|
|||
cvar = varpool_get_node (cdecl);
|
||||
control_vars.quick_push (cvar);
|
||||
|
||||
if (!var->alias)
|
||||
if (!var->symbol.alias)
|
||||
{
|
||||
/* Make sure the COMMON block control variable gets initialized.
|
||||
Note that there's no point in doing this for aliases; we only
|
||||
need to do this once for the main variable. */
|
||||
emutls_common_1 (var->symbol.decl, cdecl, (tree *)data);
|
||||
}
|
||||
if (var->alias && !var->alias_of)
|
||||
cvar->alias = true;
|
||||
if (var->symbol.alias && !var->alias_of)
|
||||
cvar->symbol.alias = true;
|
||||
|
||||
/* Indicate that the value of the TLS variable may be found elsewhere,
|
||||
preventing the variable from re-appearing in the GIMPLE. We cheat
|
||||
|
|
@ -743,7 +743,7 @@ ipa_lower_emutls (void)
|
|||
gcc_checking_assert (TREE_STATIC (var->symbol.decl)
|
||||
|| DECL_EXTERNAL (var->symbol.decl));
|
||||
varpool_node_set_add (tls_vars, var);
|
||||
if (var->alias && var->analyzed)
|
||||
if (var->symbol.alias && var->symbol.definition)
|
||||
varpool_node_set_add (tls_vars, varpool_variable_node (var, NULL));
|
||||
}
|
||||
|
||||
|
|
@ -767,9 +767,9 @@ ipa_lower_emutls (void)
|
|||
{
|
||||
var = tls_vars->nodes[i];
|
||||
|
||||
if (var->alias && !var->alias_of)
|
||||
if (var->symbol.alias && !var->alias_of)
|
||||
any_aliases = true;
|
||||
else if (!var->alias)
|
||||
else if (!var->symbol.alias)
|
||||
varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1726,7 +1726,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
|
|||
if ((!edge
|
||||
|| (edge->indirect_inlining_edge
|
||||
&& id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
|
||||
&& id->dst_node->analyzed
|
||||
&& id->dst_node->symbol.definition
|
||||
&& (fn = gimple_call_fndecl (stmt)) != NULL)
|
||||
{
|
||||
struct cgraph_node *dest = cgraph_get_node (fn);
|
||||
|
|
@ -1737,10 +1737,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
|
|||
producing dead clone (for further cloning). In all
|
||||
other cases we hit a bug (incorrect node sharing is the
|
||||
most common reason for missing edges). */
|
||||
gcc_assert (!dest->analyzed
|
||||
gcc_assert (!dest->symbol.definition
|
||||
|| dest->symbol.address_taken
|
||||
|| !id->src_node->analyzed
|
||||
|| !id->dst_node->analyzed);
|
||||
|| !id->src_node->symbol.definition
|
||||
|| !id->dst_node->symbol.definition);
|
||||
if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
|
||||
cgraph_create_edge_including_clones
|
||||
(id->dst_node, dest, orig_stmt, stmt, bb->count,
|
||||
|
|
@ -3611,7 +3611,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
|
|||
|
||||
/* Do not special case builtins where we see the body.
|
||||
This just confuse inliner. */
|
||||
if (!decl || !(node = cgraph_get_node (decl)) || node->analyzed)
|
||||
if (!decl || !(node = cgraph_get_node (decl)) || node->symbol.definition)
|
||||
;
|
||||
/* For buitins that are likely expanded to nothing or
|
||||
inlined do not account operand costs. */
|
||||
|
|
@ -4344,7 +4344,7 @@ optimize_inline_calls (tree fn)
|
|||
memset (&id, 0, sizeof (id));
|
||||
|
||||
id.src_node = id.dst_node = cgraph_get_node (fn);
|
||||
gcc_assert (id.dst_node->analyzed);
|
||||
gcc_assert (id.dst_node->symbol.definition);
|
||||
id.dst_fn = fn;
|
||||
/* Or any functions that aren't finished yet. */
|
||||
if (current_function_decl)
|
||||
|
|
@ -5238,7 +5238,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
|
|||
pointer_set_destroy (id.statements_to_fold);
|
||||
fold_cond_expr_cond ();
|
||||
delete_unreachable_blocks_update_callgraph (&id);
|
||||
if (id.dst_node->analyzed)
|
||||
if (id.dst_node->symbol.definition)
|
||||
cgraph_rebuild_references ();
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
|
|
|
|||
|
|
@ -2874,7 +2874,7 @@ get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
|
|||
&& (TREE_STATIC (t) || DECL_EXTERNAL (t)))
|
||||
{
|
||||
struct varpool_node *node = varpool_get_node (t);
|
||||
if (node && node->alias)
|
||||
if (node && node->symbol.alias && node->symbol.analyzed)
|
||||
{
|
||||
node = varpool_variable_node (node, NULL);
|
||||
t = node->symbol.decl;
|
||||
|
|
@ -5751,7 +5751,7 @@ create_variable_info_for (tree decl, const char *name)
|
|||
/* If this is a global variable with an initializer and we are in
|
||||
IPA mode generate constraints for it. */
|
||||
if (DECL_INITIAL (decl)
|
||||
&& vnode->analyzed)
|
||||
&& vnode->symbol.definition)
|
||||
{
|
||||
vec<ce_s> rhsc = vNULL;
|
||||
struct constraint_expr lhs, *rhsp;
|
||||
|
|
@ -7023,7 +7023,8 @@ struct pt_solution ipa_escaped_pt
|
|||
static bool
|
||||
associate_varinfo_to_alias (struct cgraph_node *node, void *data)
|
||||
{
|
||||
if (node->alias || node->thunk.thunk_p)
|
||||
if ((node->symbol.alias || node->thunk.thunk_p)
|
||||
&& node->symbol.analyzed)
|
||||
insert_vi_for_tree (node->symbol.decl, (varinfo_t)data);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -7066,7 +7067,7 @@ ipa_pta_execute (void)
|
|||
/* Create constraints for global variables and their initializers. */
|
||||
FOR_EACH_VARIABLE (var)
|
||||
{
|
||||
if (var->alias)
|
||||
if (var->symbol.alias && var->symbol.analyzed)
|
||||
continue;
|
||||
|
||||
get_vi_for_tree (var->symbol.decl);
|
||||
|
|
|
|||
10
gcc/varasm.c
10
gcc/varasm.c
|
|
@ -2256,7 +2256,7 @@ mark_decl_referenced (tree decl)
|
|||
definition. */
|
||||
struct cgraph_node *node = cgraph_get_create_node (decl);
|
||||
if (!DECL_EXTERNAL (decl)
|
||||
&& !node->local.finalized)
|
||||
&& !node->symbol.definition)
|
||||
cgraph_mark_force_output_node (node);
|
||||
}
|
||||
else if (TREE_CODE (decl) == VAR_DECL)
|
||||
|
|
@ -5595,9 +5595,9 @@ assemble_alias (tree decl, tree target)
|
|||
|
||||
/* Allow aliases to aliases. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
cgraph_get_create_node (decl)->alias = true;
|
||||
cgraph_get_create_node (decl)->symbol.alias = true;
|
||||
else
|
||||
varpool_node_for_decl (decl)->alias = true;
|
||||
varpool_node_for_decl (decl)->symbol.alias = true;
|
||||
|
||||
/* If the target has already been emitted, we don't have to queue the
|
||||
alias. This saves a tad of memory. */
|
||||
|
|
@ -5700,12 +5700,12 @@ dump_tm_clone_pairs (vec<tm_alias_pair> tm_alias_pairs)
|
|||
TM_GETTMCLONE. If neither of these are true, we didn't generate
|
||||
a clone, and we didn't call it indirectly... no sense keeping it
|
||||
in the clone table. */
|
||||
if (!dst_n || !dst_n->analyzed)
|
||||
if (!dst_n || !dst_n->symbol.definition)
|
||||
continue;
|
||||
|
||||
/* This covers the case where we have optimized the original
|
||||
function away, and only access the transactional clone. */
|
||||
if (!src_n || !src_n->analyzed)
|
||||
if (!src_n || !src_n->symbol.definition)
|
||||
continue;
|
||||
|
||||
if (!switched)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,19 @@ void
|
|||
varpool_remove_node (struct varpool_node *node)
|
||||
{
|
||||
symtab_unregister_node ((symtab_node)node);
|
||||
|
||||
/* Because we remove references from external functions before final compilation,
|
||||
we may end up removing useful constructors.
|
||||
FIXME: We probably want to trace boundaries better. */
|
||||
if (!const_value_known_p (node->symbol.decl))
|
||||
varpool_remove_initializer (node);
|
||||
ggc_free (node);
|
||||
}
|
||||
|
||||
/* Renove node initializer when it is no longer needed. */
|
||||
void
|
||||
varpool_remove_initializer (struct varpool_node *node)
|
||||
{
|
||||
if (DECL_INITIAL (node->symbol.decl)
|
||||
&& !DECL_IN_CONSTANT_POOL (node->symbol.decl)
|
||||
/* Keep vtables for BINFO folding. */
|
||||
|
|
@ -65,7 +78,6 @@ varpool_remove_node (struct varpool_node *node)
|
|||
/* FIXME: http://gcc.gnu.org/PR55395 */
|
||||
&& debug_info_level == DINFO_LEVEL_NONE)
|
||||
DECL_INITIAL (node->symbol.decl) = error_mark_node;
|
||||
ggc_free (node);
|
||||
}
|
||||
|
||||
/* Dump given cgraph node. */
|
||||
|
|
@ -80,10 +92,6 @@ dump_varpool_node (FILE *f, struct varpool_node *node)
|
|||
fprintf (f, " Varpool flags:");
|
||||
if (DECL_INITIAL (node->symbol.decl))
|
||||
fprintf (f, " initialized");
|
||||
if (node->analyzed)
|
||||
fprintf (f, " analyzed");
|
||||
if (node->finalized)
|
||||
fprintf (f, " finalized");
|
||||
if (node->output)
|
||||
fprintf (f, " output");
|
||||
if (TREE_READONLY (node->symbol.decl))
|
||||
|
|
@ -117,8 +125,8 @@ struct varpool_node *
|
|||
varpool_node_for_asm (tree asmname)
|
||||
{
|
||||
if (symtab_node node = symtab_node_for_asm (asmname))
|
||||
if (varpool_node *vnode = dyn_cast <varpool_node> (node))
|
||||
return vnode;
|
||||
return dyn_cast <varpool_node> (node);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -205,12 +213,12 @@ enum availability
|
|||
cgraph_variable_initializer_availability (struct varpool_node *node)
|
||||
{
|
||||
gcc_assert (cgraph_function_flags_ready);
|
||||
if (!node->finalized)
|
||||
if (!node->symbol.definition)
|
||||
return AVAIL_NOT_AVAILABLE;
|
||||
if (!TREE_PUBLIC (node->symbol.decl))
|
||||
return AVAIL_AVAILABLE;
|
||||
/* If the variable can be overwritten, return OVERWRITABLE. Takes
|
||||
care of at least two notable extensions - the COMDAT variables
|
||||
care of at least one notable extension - the COMDAT variables
|
||||
used to share template instantiations in C++. */
|
||||
if (!decl_replaceable_p (node->symbol.decl))
|
||||
return AVAIL_OVERWRITABLE;
|
||||
|
|
@ -225,24 +233,24 @@ varpool_analyze_node (struct varpool_node *node)
|
|||
/* When reading back varpool at LTO time, we re-construct the queue in order
|
||||
to have "needed" list right by inserting all needed nodes into varpool.
|
||||
We however don't want to re-analyze already analyzed nodes. */
|
||||
if (!node->analyzed)
|
||||
if (!node->symbol.analyzed)
|
||||
{
|
||||
gcc_assert (!in_lto_p || cgraph_function_flags_ready);
|
||||
/* Compute the alignment early so function body expanders are
|
||||
already informed about increased alignment. */
|
||||
align_variable (decl, 0);
|
||||
}
|
||||
if (node->alias && node->alias_of)
|
||||
if (node->symbol.alias && node->alias_of)
|
||||
{
|
||||
struct varpool_node *tgt = varpool_node_for_decl (node->alias_of);
|
||||
struct varpool_node *n;
|
||||
|
||||
for (n = tgt; n && n->alias;
|
||||
n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
|
||||
for (n = tgt; n && n->symbol.alias;
|
||||
n = n->symbol.analyzed ? varpool_alias_target (n) : NULL)
|
||||
if (n == node)
|
||||
{
|
||||
error ("variable %q+D part of alias cycle", node->symbol.decl);
|
||||
node->alias = false;
|
||||
node->symbol.alias = false;
|
||||
continue;
|
||||
}
|
||||
if (!vec_safe_length (node->symbol.ref_list.references))
|
||||
|
|
@ -257,8 +265,8 @@ varpool_analyze_node (struct varpool_node *node)
|
|||
}
|
||||
}
|
||||
else if (DECL_INITIAL (decl))
|
||||
record_references_in_initializer (decl, node->analyzed);
|
||||
node->analyzed = true;
|
||||
record_references_in_initializer (decl, node->symbol.analyzed);
|
||||
node->symbol.analyzed = true;
|
||||
}
|
||||
|
||||
/* Assemble thunks and aliases associated to NODE. */
|
||||
|
|
@ -287,7 +295,7 @@ varpool_assemble_decl (struct varpool_node *node)
|
|||
|
||||
/* Aliases are outout when their target is produced or by
|
||||
output_weakrefs. */
|
||||
if (node->alias)
|
||||
if (node->symbol.alias)
|
||||
return false;
|
||||
|
||||
/* Constant pool is output from RTL land when the reference
|
||||
|
|
@ -316,7 +324,7 @@ varpool_assemble_decl (struct varpool_node *node)
|
|||
{
|
||||
assemble_variable (decl, 0, 1, 0);
|
||||
gcc_assert (TREE_ASM_WRITTEN (decl));
|
||||
node->finalized = 1;
|
||||
node->symbol.definition = true;
|
||||
assemble_aliases (node);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -357,7 +365,7 @@ varpool_remove_unreferenced_decls (void)
|
|||
fprintf (cgraph_dump_file, "Trivially needed variables:");
|
||||
FOR_EACH_DEFINED_VARIABLE (node)
|
||||
{
|
||||
if (node->analyzed
|
||||
if (node->symbol.analyzed
|
||||
&& (!varpool_can_remove_if_no_refs (node)
|
||||
/* We just expanded all function bodies. See if any of
|
||||
them needed the variable. */
|
||||
|
|
@ -381,7 +389,7 @@ varpool_remove_unreferenced_decls (void)
|
|||
next = next->symbol.same_comdat_group)
|
||||
{
|
||||
varpool_node *vnext = dyn_cast <varpool_node> (next);
|
||||
if (vnext && vnext->analyzed)
|
||||
if (vnext && vnext->symbol.analyzed)
|
||||
enqueue_node (vnext, &first);
|
||||
}
|
||||
}
|
||||
|
|
@ -390,8 +398,8 @@ varpool_remove_unreferenced_decls (void)
|
|||
varpool_node *vnode = dyn_cast <varpool_node> (ref->referred);
|
||||
if (vnode
|
||||
&& (!DECL_EXTERNAL (ref->referred->symbol.decl)
|
||||
|| vnode->alias)
|
||||
&& vnode->analyzed)
|
||||
|| vnode->symbol.alias)
|
||||
&& vnode->symbol.analyzed)
|
||||
enqueue_node (vnode, &first);
|
||||
}
|
||||
}
|
||||
|
|
@ -419,7 +427,7 @@ void
|
|||
varpool_finalize_named_section_flags (struct varpool_node *node)
|
||||
{
|
||||
if (!TREE_ASM_WRITTEN (node->symbol.decl)
|
||||
&& !node->alias
|
||||
&& !node->symbol.alias
|
||||
&& !node->symbol.in_other_partition
|
||||
&& !DECL_EXTERNAL (node->symbol.decl)
|
||||
&& TREE_CODE (node->symbol.decl) == VAR_DECL
|
||||
|
|
@ -484,8 +492,8 @@ varpool_create_variable_alias (tree alias, tree decl)
|
|||
gcc_assert (TREE_CODE (decl) == VAR_DECL);
|
||||
gcc_assert (TREE_CODE (alias) == VAR_DECL);
|
||||
alias_node = varpool_node_for_decl (alias);
|
||||
alias_node->alias = 1;
|
||||
alias_node->finalized = 1;
|
||||
alias_node->symbol.alias = true;
|
||||
alias_node->symbol.definition = true;
|
||||
alias_node->alias_of = decl;
|
||||
|
||||
/* Extra name alias mechanizm creates aliases really late
|
||||
|
|
|
|||
Loading…
Reference in New Issue