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