mirror of git://gcc.gnu.org/git/gcc.git
cgraph.c (ld_plugin_symbol_resolution_names): Move to symtab.c
* cgraph.c (ld_plugin_symbol_resolution_names): Move to symtab.c (cgraph_asm_nodes, cgraph_asm_last_node): Move to cgraphunit.c (cgraph_add_to_same_comdat_group): Remove. (cgraph_add_asm_node): Move to cgraphunit.c. (cgraph_make_decl_local): Move to symtab.c (cgraph_make_node_local_1): Update. (cgraph_can_remove_if_no_direct_calls_and): Update. (used_from_object_file_p): Update. (resolution_used_from_other_file_p): Move to symtab.c (cgraph_used_from_object_file_p): move to symtab.c (verify_cgraph_node): Verify same comdat groups. * cgraph.h (cgraph_asm_node): Rename to ... (asm_node): ... this one. (cgraph_asm_nodes): Rename to ... (asm_nodes): ... this one. (symtab_add_to_same_comdat_group): New function. (symtab_dissolve_same_comdat_group_list): New function. (symtab_used_from_object_file_p): Declare. (symtab_make_decl_local): Declare. (cgraph_add_to_same_comdat_group): Remove. (cgraph_add_asm_node): Remove. (cgraph_used_from_object_file_p, varpool_used_from_object_file_p): Remove. (cgraph_finalize_compilation_unit): Rename to ... (finalize_compilation_unit): ... this one. (cgraph_optimize): Rename to .... (compile): ... this one. (add_asm_node): Declare. (fixup_same_cpp_alias_visibility): Declare. (cgraph_make_decl_local): Remove. (varpool_assemble_pending_decls): Rename to ... (varpool_output_variables): ... this one. (varpool_remove_unreferenced_decls): Remove. * ipa-inline-transform.c (clone_inlined_nodes): Dissolve comdat groups. (preserve_function_body_p): Make static. * toplev.c (compile_file): Update comments; update. * cgraphunit.c: Update comments. (cgraph_expand_all_functions): Rename to ... (expand_all_functions): ... this one; update. (cgraph_mark_functions_to_output): Rename to ... (mark_functions_to_output): ... this one; cleanup. (cgraph_output_pending_asms): Remove prototype. (asm_nodes, asm_last_node): New static vars. (cgraph_process_new_functions): Update. (cgraph_reset_node): Cleanup; add comment. (cgraph_add_new_function): Update. (cgraph_output_pending_asms): Rename to ... (output_asm_statements): ... this one. (add_asm_node): New function. (fixup_same_cpp_alias_visibility): New function based on code in cgraph_analyze_function. (cgraph_analyze_function): Use it. (cgraph_order_sort): Update. (cgraph_output_in_order): Update. (cgraph_function_versioning): Update. (cgraph_optimize): Rename to ... (compile): ... this one; initialize streamer hooks here. (cgraph_finalize_compilation_unit): Rename to ... (finalize_compilation_unit): ... this one; do not initialize streamer hook here. * lto-streamer-out.c (lto_output_toplevel_asms): Update. * dwarf2out.c: Update ocmment. * optimize.c (maybe_clone_body): Use symtab_add_to_same_comdat_group. * method.c (use_thunk): Likewise. * semantics.c (maybe_add_lambda_conv_op): Likewise. * decl2.c (maybe_emit_vtables): Likewise. (cp_write_global_declarations): Use finalize_compilation_unit. * parser.c (cp_parser_asm_definition): Use add_asm_node. * lto-streamer-in.c (lto_input_toplevel_asms): Use add_asm_node * c-decl.c (c_write_global_declarations): Use finalize_compilation_unit. * langhooks.c (write_global_declarations): Update. * ipa.c (cgraph_externally_visible_p): Update. (dissolve_same_comdat_group_list): Remove. (function_and_variable_visibility): Update. * symtab.c: Inlcude lto-streamer.h and rtl.h (ld_plugin_symbol_resolution_names): New. (symtab_add_to_same_comdat_group): New. (symtab_dissolve_same_comdat_group_list): New. (resolution_used_from_other_file_p): Move here from cgraph.c (symtab_used_from_object_file_p): New. (symtab_make_decl_local): New. * passes.c (register_pass): Update comments. * c-parser.c (c_parser_asm_definition): Update. * varpool.c (varpool_analyze_node): Use fixup_same_cpp_alias_visibility. (varpool_remove_unreferenced_decls): Make static. (varpool_assemble_pending_decls): Rename to ... (varpool_output_variables): ... this one; call varpool_remove_unreferenced_decls. (varpool_used_from_object_file_p): Remove. * gogo-tree.cc (Gogo::write_globals): Use finalize_compilation_unit. * gcc-interface/utils.c (rest_of_subprog_body_compilation): Update comment. (gnat_write_global_declarations): Use finalize_compilation_unit. * f95-lang.c (gfc_finish): Update comments. * lto.c (lto_main): Use compile (). * lto-partition.c (partition_cgraph_node_p): Use symtab_used_from_object_file_p. (partition_varpool_node_p): Likewise. From-SVN: r186998
This commit is contained in:
parent
7edaa4d2a5
commit
65d630d474
|
|
@ -1,3 +1,96 @@
|
|||
012-04-30 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraph.c (ld_plugin_symbol_resolution_names): Move to symtab.c
|
||||
(cgraph_asm_nodes, cgraph_asm_last_node): Move to cgraphunit.c
|
||||
(cgraph_add_to_same_comdat_group): Remove.
|
||||
(cgraph_add_asm_node): Move to cgraphunit.c.
|
||||
(cgraph_make_decl_local): Move to symtab.c
|
||||
(cgraph_make_node_local_1): Update.
|
||||
(cgraph_can_remove_if_no_direct_calls_and): Update.
|
||||
(used_from_object_file_p): Update.
|
||||
(resolution_used_from_other_file_p): Move to symtab.c
|
||||
(cgraph_used_from_object_file_p): move to symtab.c
|
||||
(verify_cgraph_node): Verify same comdat groups.
|
||||
* cgraph.h (cgraph_asm_node): Rename to ...
|
||||
(asm_node): ... this one.
|
||||
(cgraph_asm_nodes): Rename to ...
|
||||
(asm_nodes): ... this one.
|
||||
(symtab_add_to_same_comdat_group): New function.
|
||||
(symtab_dissolve_same_comdat_group_list): New function.
|
||||
(symtab_used_from_object_file_p): Declare.
|
||||
(symtab_make_decl_local): Declare.
|
||||
(cgraph_add_to_same_comdat_group): Remove.
|
||||
(cgraph_add_asm_node): Remove.
|
||||
(cgraph_used_from_object_file_p, varpool_used_from_object_file_p):
|
||||
Remove.
|
||||
(cgraph_finalize_compilation_unit): Rename to ...
|
||||
(finalize_compilation_unit): ... this one.
|
||||
(cgraph_optimize): Rename to ....
|
||||
(compile): ... this one.
|
||||
(add_asm_node): Declare.
|
||||
(fixup_same_cpp_alias_visibility): Declare.
|
||||
(cgraph_make_decl_local): Remove.
|
||||
(varpool_assemble_pending_decls): Rename to ...
|
||||
(varpool_output_variables): ... this one.
|
||||
(varpool_remove_unreferenced_decls): Remove.
|
||||
* ipa-inline-transform.c (clone_inlined_nodes): Dissolve comdat groups.
|
||||
(preserve_function_body_p): Make static.
|
||||
* toplev.c (compile_file): Update comments;
|
||||
update.
|
||||
* cgraphunit.c: Update comments.
|
||||
(cgraph_expand_all_functions): Rename to ...
|
||||
(expand_all_functions): ... this one; update.
|
||||
(cgraph_mark_functions_to_output): Rename to ...
|
||||
(mark_functions_to_output): ... this one; cleanup.
|
||||
(cgraph_output_pending_asms): Remove prototype.
|
||||
(asm_nodes, asm_last_node): New static vars.
|
||||
(cgraph_process_new_functions): Update.
|
||||
(cgraph_reset_node): Cleanup; add comment.
|
||||
(cgraph_add_new_function): Update.
|
||||
(cgraph_output_pending_asms): Rename to ...
|
||||
(output_asm_statements): ... this one.
|
||||
(add_asm_node): New function.
|
||||
(fixup_same_cpp_alias_visibility): New function based on code
|
||||
in cgraph_analyze_function.
|
||||
(cgraph_analyze_function): Use it.
|
||||
(cgraph_order_sort): Update.
|
||||
(cgraph_output_in_order): Update.
|
||||
(cgraph_function_versioning): Update.
|
||||
(cgraph_optimize): Rename to ...
|
||||
(compile): ... this one; initialize streamer hooks here.
|
||||
(cgraph_finalize_compilation_unit): Rename to ...
|
||||
(finalize_compilation_unit): ... this one; do not initialize streamer
|
||||
hook here.
|
||||
* lto-streamer-out.c (lto_output_toplevel_asms): Update.
|
||||
* dwarf2out.c: Update ocmment.
|
||||
* optimize.c (maybe_clone_body): Use symtab_add_to_same_comdat_group.
|
||||
* method.c (use_thunk): Likewise.
|
||||
* semantics.c (maybe_add_lambda_conv_op): Likewise.
|
||||
* decl2.c (maybe_emit_vtables): Likewise.
|
||||
(cp_write_global_declarations): Use finalize_compilation_unit.
|
||||
* parser.c (cp_parser_asm_definition): Use add_asm_node.
|
||||
* lto-streamer-in.c (lto_input_toplevel_asms): Use add_asm_node
|
||||
* c-decl.c (c_write_global_declarations): Use finalize_compilation_unit.
|
||||
* langhooks.c (write_global_declarations): Update.
|
||||
* ipa.c (cgraph_externally_visible_p): Update.
|
||||
(dissolve_same_comdat_group_list): Remove.
|
||||
(function_and_variable_visibility): Update.
|
||||
* symtab.c: Inlcude lto-streamer.h and rtl.h
|
||||
(ld_plugin_symbol_resolution_names): New.
|
||||
(symtab_add_to_same_comdat_group): New.
|
||||
(symtab_dissolve_same_comdat_group_list): New.
|
||||
(resolution_used_from_other_file_p): Move here from cgraph.c
|
||||
(symtab_used_from_object_file_p): New.
|
||||
(symtab_make_decl_local): New.
|
||||
* passes.c (register_pass): Update comments.
|
||||
* c-parser.c (c_parser_asm_definition): Update.
|
||||
* varpool.c (varpool_analyze_node): Use fixup_same_cpp_alias_visibility.
|
||||
(varpool_remove_unreferenced_decls): Make static.
|
||||
(varpool_assemble_pending_decls): Rename to ...
|
||||
(varpool_output_variables): ... this one; call
|
||||
varpool_remove_unreferenced_decls.
|
||||
(varpool_used_from_object_file_p): Remove.
|
||||
|
||||
2012-04-30 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/51033
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
2012-04-30 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcc-interface/utils.c (rest_of_subprog_body_compilation): Update
|
||||
comment.
|
||||
(gnat_write_global_declarations): Use finalize_compilation_unit.
|
||||
|
||||
2012-04-30 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode,
|
||||
|
|
|
|||
|
|
@ -2036,7 +2036,6 @@ rest_of_subprog_body_compilation (tree subprog_decl)
|
|||
/* Dump functions before gimplification. */
|
||||
dump_function (TDI_original, subprog_decl);
|
||||
|
||||
/* ??? This special handling of nested functions is probably obsolete. */
|
||||
if (!decl_function_context (subprog_decl))
|
||||
cgraph_finalize_function (subprog_decl, false);
|
||||
else
|
||||
|
|
@ -4907,9 +4906,8 @@ gnat_write_global_declarations (void)
|
|||
if (TREE_CODE (iter) == TYPE_DECL)
|
||||
debug_hooks->global_decl (iter);
|
||||
|
||||
/* Proceed to optimize and emit assembly.
|
||||
FIXME: shouldn't be the front end's responsibility to call this. */
|
||||
cgraph_finalize_compilation_unit ();
|
||||
/* Proceed to optimize and emit assembly. */
|
||||
finalize_compilation_unit ();
|
||||
|
||||
/* After cgraph has had a chance to emit everything that's going to
|
||||
be emitted, output debug information for the rest of globals. */
|
||||
|
|
|
|||
|
|
@ -10040,7 +10040,7 @@ c_write_global_declarations (void)
|
|||
|
||||
/* We're done parsing; proceed to optimize and emit assembly.
|
||||
FIXME: shouldn't be the front end's responsibility to call this. */
|
||||
cgraph_finalize_compilation_unit ();
|
||||
finalize_compilation_unit ();
|
||||
|
||||
timevar_stop (TV_PHASE_CGRAPH);
|
||||
timevar_start (TV_PHASE_DBGINFO);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "diagnostic.h"
|
||||
#include "opts.h"
|
||||
#include "plugin.h"
|
||||
#include "cgraph.h"
|
||||
|
||||
#define GCC_BAD(gmsgid) \
|
||||
do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
|
||||
|
|
@ -311,6 +312,7 @@ maybe_apply_pending_pragma_weaks (void)
|
|||
tree alias_id, id, decl;
|
||||
int i;
|
||||
pending_weak *pe;
|
||||
symtab_node target;
|
||||
|
||||
FOR_EACH_VEC_ELT (pending_weak, pending_weaks, i, pe)
|
||||
{
|
||||
|
|
@ -320,13 +322,22 @@ maybe_apply_pending_pragma_weaks (void)
|
|||
if (id == NULL)
|
||||
continue;
|
||||
|
||||
target = symtab_node_for_asm (id);
|
||||
decl = build_decl (UNKNOWN_LOCATION,
|
||||
FUNCTION_DECL, alias_id, default_function_type);
|
||||
target ? TREE_CODE (target->symbol.decl) : FUNCTION_DECL,
|
||||
alias_id, default_function_type);
|
||||
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
DECL_WEAK (decl) = 1;
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
TREE_STATIC (decl) = 1;
|
||||
if (!target)
|
||||
{
|
||||
error ("%q+D aliased to undefined symbol %qE",
|
||||
decl, id);
|
||||
continue;
|
||||
}
|
||||
|
||||
assemble_alias (decl, id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1792,7 +1792,7 @@ c_parser_asm_definition (c_parser *parser)
|
|||
{
|
||||
tree asm_str = c_parser_simple_asm_expr (parser);
|
||||
if (asm_str)
|
||||
cgraph_add_asm_node (asm_str);
|
||||
add_asm_node (asm_str);
|
||||
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
|
||||
}
|
||||
|
||||
|
|
|
|||
172
gcc/cgraph.c
172
gcc/cgraph.c
|
|
@ -54,20 +54,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cfgloop.h"
|
||||
#include "gimple-pretty-print.h"
|
||||
|
||||
const char * const ld_plugin_symbol_resolution_names[]=
|
||||
{
|
||||
"",
|
||||
"undef",
|
||||
"prevailing_def",
|
||||
"prevailing_def_ironly",
|
||||
"preempted_reg",
|
||||
"preempted_ir",
|
||||
"resolved_ir",
|
||||
"resolved_exec",
|
||||
"resolved_dyn",
|
||||
"prevailing_def_ironly_exp"
|
||||
};
|
||||
|
||||
static void cgraph_node_remove_callers (struct cgraph_node *node);
|
||||
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
|
||||
static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
|
||||
|
|
@ -94,12 +80,6 @@ enum cgraph_state cgraph_state = CGRAPH_STATE_PARSING;
|
|||
/* Set when the cgraph is fully build and the basic flags are computed. */
|
||||
bool cgraph_function_flags_ready = false;
|
||||
|
||||
/* Linked list of cgraph asm nodes. */
|
||||
struct cgraph_asm_node *cgraph_asm_nodes;
|
||||
|
||||
/* Last node in cgraph_asm_nodes. */
|
||||
static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
|
||||
|
||||
/* List of hooks triggered on cgraph_edge events. */
|
||||
struct cgraph_edge_hook_list {
|
||||
cgraph_edge_hook hook;
|
||||
|
|
@ -1377,31 +1357,6 @@ cgraph_remove_node (struct cgraph_node *node)
|
|||
free_nodes = node;
|
||||
}
|
||||
|
||||
/* Add NEW_ to the same comdat group that OLD is in. */
|
||||
|
||||
void
|
||||
cgraph_add_to_same_comdat_group (struct cgraph_node *new_node,
|
||||
struct cgraph_node *old_node)
|
||||
{
|
||||
gcc_assert (DECL_ONE_ONLY (old_node->symbol.decl));
|
||||
gcc_assert (!new_node->symbol.same_comdat_group);
|
||||
gcc_assert (new_node != old_node);
|
||||
|
||||
DECL_COMDAT_GROUP (new_node->symbol.decl) = DECL_COMDAT_GROUP (old_node->symbol.decl);
|
||||
new_node->symbol.same_comdat_group = (symtab_node)old_node;
|
||||
if (!old_node->symbol.same_comdat_group)
|
||||
old_node->symbol.same_comdat_group = (symtab_node)new_node;
|
||||
else
|
||||
{
|
||||
symtab_node n;
|
||||
for (n = old_node->symbol.same_comdat_group;
|
||||
n->symbol.same_comdat_group != (symtab_node)old_node;
|
||||
n = n->symbol.same_comdat_group)
|
||||
;
|
||||
n->symbol.same_comdat_group = (symtab_node)new_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the node from cgraph and all inline clones inlined into it.
|
||||
Skip however removal of FORBIDDEN_NODE and return true if it needs to be
|
||||
removed. This allows to call the function from outer loop walking clone
|
||||
|
|
@ -1660,25 +1615,6 @@ debug_cgraph (void)
|
|||
dump_cgraph (stderr);
|
||||
}
|
||||
|
||||
/* Add a top-level asm statement to the list. */
|
||||
|
||||
struct cgraph_asm_node *
|
||||
cgraph_add_asm_node (tree asm_str)
|
||||
{
|
||||
struct cgraph_asm_node *node;
|
||||
|
||||
node = ggc_alloc_cleared_cgraph_asm_node ();
|
||||
node->asm_str = asm_str;
|
||||
node->order = symtab_order++;
|
||||
node->next = NULL;
|
||||
if (cgraph_asm_nodes == NULL)
|
||||
cgraph_asm_nodes = node;
|
||||
else
|
||||
cgraph_asm_last_node->next = node;
|
||||
cgraph_asm_last_node = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Return true when the DECL can possibly be inlined. */
|
||||
bool
|
||||
cgraph_function_possibly_inlined_p (tree decl)
|
||||
|
|
@ -2047,77 +1983,6 @@ cgraph_node_can_be_local_p (struct cgraph_node *node)
|
|||
NULL, true));
|
||||
}
|
||||
|
||||
/* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
|
||||
but other code such as notice_global_symbol generates rtl. */
|
||||
void
|
||||
cgraph_make_decl_local (tree decl)
|
||||
{
|
||||
rtx rtl, symbol;
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
DECL_COMMON (decl) = 0;
|
||||
else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
||||
|
||||
if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
|
||||
{
|
||||
/* It is possible that we are linking against library defining same COMDAT
|
||||
function. To avoid conflict we need to rename our local name of the
|
||||
function just in the case WHOPR partitioning decide to make it hidden
|
||||
to avoid cross partition references. */
|
||||
if (flag_wpa)
|
||||
{
|
||||
const char *old_name;
|
||||
|
||||
old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
struct cgraph_node *node = cgraph_get_node (decl);
|
||||
change_decl_assembler_name (decl,
|
||||
clone_function_name (decl, "local"));
|
||||
if (node->symbol.lto_file_data)
|
||||
lto_record_renamed_decl (node->symbol.lto_file_data,
|
||||
old_name,
|
||||
IDENTIFIER_POINTER
|
||||
(DECL_ASSEMBLER_NAME (decl)));
|
||||
}
|
||||
else if (TREE_CODE (decl) == VAR_DECL)
|
||||
{
|
||||
struct varpool_node *vnode = varpool_get_node (decl);
|
||||
/* change_decl_assembler_name will warn here on vtables because
|
||||
C++ frontend still sets TREE_SYMBOL_REFERENCED on them. */
|
||||
SET_DECL_ASSEMBLER_NAME (decl,
|
||||
clone_function_name (decl, "local"));
|
||||
if (vnode->symbol.lto_file_data)
|
||||
lto_record_renamed_decl (vnode->symbol.lto_file_data,
|
||||
old_name,
|
||||
IDENTIFIER_POINTER
|
||||
(DECL_ASSEMBLER_NAME (decl)));
|
||||
}
|
||||
}
|
||||
DECL_SECTION_NAME (decl) = 0;
|
||||
DECL_COMDAT (decl) = 0;
|
||||
}
|
||||
DECL_COMDAT_GROUP (decl) = 0;
|
||||
DECL_WEAK (decl) = 0;
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
if (!DECL_RTL_SET_P (decl))
|
||||
return;
|
||||
|
||||
/* Update rtl flags. */
|
||||
make_decl_rtl (decl);
|
||||
|
||||
rtl = DECL_RTL (decl);
|
||||
if (!MEM_P (rtl))
|
||||
return;
|
||||
|
||||
symbol = XEXP (rtl, 0);
|
||||
if (GET_CODE (symbol) != SYMBOL_REF)
|
||||
return;
|
||||
|
||||
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
|
||||
}
|
||||
|
||||
/* Call calback on NODE, thunks and aliases asociated to NODE.
|
||||
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
|
||||
skipped. */
|
||||
|
|
@ -2190,7 +2055,7 @@ cgraph_make_node_local_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
|||
gcc_checking_assert (cgraph_node_can_be_local_p (node));
|
||||
if (DECL_COMDAT (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl))
|
||||
{
|
||||
cgraph_make_decl_local (node->symbol.decl);
|
||||
symtab_make_decl_local (node->symbol.decl);
|
||||
|
||||
node->symbol.externally_visible = false;
|
||||
node->local.local = true;
|
||||
|
|
@ -2472,7 +2337,7 @@ cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
|
|||
/* Only COMDAT functions can be removed if externally visible. */
|
||||
if (node->symbol.externally_visible
|
||||
&& (!DECL_COMDAT (node->symbol.decl)
|
||||
|| cgraph_used_from_object_file_p (node)))
|
||||
|| symtab_used_from_object_file_p ((symtab_node) node)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2504,7 +2369,7 @@ cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node)
|
|||
static bool
|
||||
used_from_object_file_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return cgraph_used_from_object_file_p (node);
|
||||
return symtab_used_from_object_file_p ((symtab_node) node);
|
||||
}
|
||||
|
||||
/* Return true when function NODE can be expected to be removed
|
||||
|
|
@ -2537,32 +2402,6 @@ cgraph_will_be_removed_from_program_if_no_direct_calls (struct cgraph_node *node
|
|||
}
|
||||
}
|
||||
|
||||
/* Return true when RESOLUTION indicate that linker will use
|
||||
the symbol from non-LTO object files. */
|
||||
|
||||
bool
|
||||
resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
|
||||
{
|
||||
return (resolution == LDPR_PREVAILING_DEF
|
||||
|| resolution == LDPR_PREEMPTED_REG
|
||||
|| resolution == LDPR_RESOLVED_EXEC
|
||||
|| resolution == LDPR_RESOLVED_DYN);
|
||||
}
|
||||
|
||||
|
||||
/* Return true when NODE is known to be used from other (non-LTO) object file.
|
||||
Known only when doing LTO via linker plugin. */
|
||||
|
||||
bool
|
||||
cgraph_used_from_object_file_p (struct cgraph_node *node)
|
||||
{
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
if (!TREE_PUBLIC (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl))
|
||||
return false;
|
||||
if (resolution_used_from_other_file_p (node->symbol.resolution))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Worker for cgraph_only_called_directly_p. */
|
||||
|
||||
|
|
@ -2741,6 +2580,11 @@ verify_cgraph_node (struct cgraph_node *node)
|
|||
error ("execution count is negative");
|
||||
error_found = true;
|
||||
}
|
||||
if (node->global.inlined_to && node->symbol.same_comdat_group)
|
||||
{
|
||||
error ("inline clone in same comdat group list");
|
||||
error_found = true;
|
||||
}
|
||||
if (node->global.inlined_to && node->symbol.externally_visible)
|
||||
{
|
||||
error ("externally visible inline clone");
|
||||
|
|
|
|||
28
gcc/cgraph.h
28
gcc/cgraph.h
|
|
@ -422,11 +422,11 @@ struct GTY(()) varpool_node {
|
|||
unsigned extra_name_alias : 1;
|
||||
};
|
||||
|
||||
/* Every top level asm statement is put into a cgraph_asm_node. */
|
||||
/* Every top level asm statement is put into a asm_node. */
|
||||
|
||||
struct GTY(()) cgraph_asm_node {
|
||||
struct GTY(()) asm_node {
|
||||
/* Next asm node. */
|
||||
struct cgraph_asm_node *next;
|
||||
struct asm_node *next;
|
||||
/* String for this asm node. */
|
||||
tree asm_str;
|
||||
/* Ordering of all cgraph nodes. */
|
||||
|
|
@ -467,7 +467,7 @@ extern enum cgraph_state cgraph_state;
|
|||
extern bool cgraph_function_flags_ready;
|
||||
extern cgraph_node_set cgraph_new_nodes;
|
||||
|
||||
extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
|
||||
extern GTY(()) struct asm_node *asm_nodes;
|
||||
extern GTY(()) int symtab_order;
|
||||
extern bool same_body_aliases_done;
|
||||
|
||||
|
|
@ -480,6 +480,8 @@ symtab_node symtab_node_for_asm (const_tree asmname);
|
|||
const char * symtab_node_asm_name (symtab_node);
|
||||
const char * symtab_node_name (symtab_node);
|
||||
void symtab_insert_node_to_hashtable (symtab_node);
|
||||
void symtab_add_to_same_comdat_group (symtab_node, symtab_node);
|
||||
void symtab_dissolve_same_comdat_group_list (symtab_node node);
|
||||
void dump_symtab (FILE *);
|
||||
void debug_symtab (void);
|
||||
void dump_symtab_node (FILE *, symtab_node);
|
||||
|
|
@ -488,6 +490,8 @@ void dump_symtab_base (FILE *, symtab_node);
|
|||
void verify_symtab (void);
|
||||
void verify_symtab_node (symtab_node);
|
||||
bool verify_symtab_base (symtab_node);
|
||||
bool symtab_used_from_object_file_p (symtab_node);
|
||||
void symtab_make_decl_local (tree);
|
||||
|
||||
/* In cgraph.c */
|
||||
void dump_cgraph (FILE *);
|
||||
|
|
@ -497,7 +501,6 @@ void debug_cgraph_node (struct cgraph_node *);
|
|||
void cgraph_remove_edge (struct cgraph_edge *);
|
||||
void cgraph_remove_node (struct cgraph_node *);
|
||||
struct cgraph_node *cgraph_find_replacement_node (struct cgraph_node *);
|
||||
void cgraph_add_to_same_comdat_group (struct cgraph_node *, struct cgraph_node *);
|
||||
bool cgraph_remove_node_and_inline_clones (struct cgraph_node *, struct cgraph_node *);
|
||||
void cgraph_release_function_body (struct cgraph_node *);
|
||||
void cgraph_node_remove_callees (struct cgraph_node *node);
|
||||
|
|
@ -538,8 +541,6 @@ void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
|
|||
void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *);
|
||||
bool cgraph_only_called_directly_p (struct cgraph_node *);
|
||||
|
||||
struct cgraph_asm_node *cgraph_add_asm_node (tree);
|
||||
|
||||
bool cgraph_function_possibly_inlined_p (tree);
|
||||
void cgraph_unnest_node (struct cgraph_node *);
|
||||
|
||||
|
|
@ -564,8 +565,6 @@ bool cgraph_can_remove_if_no_direct_calls_and_refs_p
|
|||
(struct cgraph_node *node);
|
||||
bool cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node);
|
||||
bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution);
|
||||
bool cgraph_used_from_object_file_p (struct cgraph_node *);
|
||||
bool varpool_used_from_object_file_p (struct varpool_node *);
|
||||
bool cgraph_for_node_thunks_and_aliases (struct cgraph_node *,
|
||||
bool (*) (struct cgraph_node *, void *),
|
||||
void *,
|
||||
|
|
@ -605,10 +604,11 @@ gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
|
|||
bool cgraph_propagate_frequency (struct cgraph_node *node);
|
||||
|
||||
/* In cgraphunit.c */
|
||||
struct asm_node *add_asm_node (tree);
|
||||
extern FILE *cgraph_dump_file;
|
||||
void cgraph_finalize_function (tree, bool);
|
||||
void cgraph_finalize_compilation_unit (void);
|
||||
void cgraph_optimize (void);
|
||||
void finalize_compilation_unit (void);
|
||||
void compile (void);
|
||||
void init_cgraph (void);
|
||||
struct cgraph_node * cgraph_copy_node_for_versioning (struct cgraph_node *,
|
||||
tree, VEC(cgraph_edge_p,heap)*, bitmap);
|
||||
|
|
@ -621,6 +621,7 @@ void tree_function_versioning (tree, tree, VEC (ipa_replace_map_p,gc)*,
|
|||
bool, bitmap, bool, bitmap, basic_block);
|
||||
bool cgraph_process_new_functions (void);
|
||||
void cgraph_process_same_body_aliases (void);
|
||||
void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias);
|
||||
|
||||
|
||||
/* In cgraphbuild.c */
|
||||
|
|
@ -668,17 +669,15 @@ void dump_varpool_node (FILE *, struct varpool_node *);
|
|||
void varpool_finalize_decl (tree);
|
||||
bool decide_is_variable_needed (struct varpool_node *, tree);
|
||||
enum availability cgraph_variable_initializer_availability (struct varpool_node *);
|
||||
void cgraph_make_decl_local (tree);
|
||||
void cgraph_make_node_local (struct cgraph_node *);
|
||||
bool cgraph_node_can_be_local_p (struct cgraph_node *);
|
||||
|
||||
|
||||
void varpool_remove_node (struct varpool_node *node);
|
||||
void varpool_finalize_named_section_flags (struct varpool_node *node);
|
||||
bool varpool_assemble_pending_decls (void);
|
||||
bool varpool_output_variables (void);
|
||||
bool varpool_assemble_decl (struct varpool_node *node);
|
||||
void varpool_analyze_node (struct varpool_node *);
|
||||
void varpool_remove_unreferenced_decls (void);
|
||||
struct varpool_node * varpool_extra_name_alias (tree, tree);
|
||||
struct varpool_node * varpool_create_variable_alias (tree, tree);
|
||||
void varpool_reset_queue (void);
|
||||
|
|
@ -1288,4 +1287,5 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
|
|||
node->symbol.force_output = 1;
|
||||
gcc_checking_assert (!node->global.inlined_to);
|
||||
}
|
||||
|
||||
#endif /* GCC_CGRAPH_H */
|
||||
|
|
|
|||
161
gcc/cgraphunit.c
161
gcc/cgraphunit.c
|
|
@ -39,7 +39,11 @@ along with GCC; see the file COPYING3. If not see
|
|||
This function has same behavior as the above but is used for static
|
||||
variables.
|
||||
|
||||
- cgraph_finalize_compilation_unit
|
||||
- add_asm_node
|
||||
|
||||
Insert new toplevel ASM statement
|
||||
|
||||
- finalize_compilation_unit
|
||||
|
||||
This function is called once (source level) compilation unit is finalized
|
||||
and it will no longer change.
|
||||
|
|
@ -54,7 +58,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
The function can be called multiple times when multiple source level
|
||||
compilation units are combined.
|
||||
|
||||
- cgraph_optimize
|
||||
- compile
|
||||
|
||||
This passes control to the back-end. Optimizations are performed and
|
||||
final assembler is generated. This is done in the following way. Note
|
||||
|
|
@ -130,7 +134,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
Simple IP passes working within single program partition.
|
||||
|
||||
5) Expansion
|
||||
(cgraph_expand_all_functions)
|
||||
(expand_all_functions)
|
||||
|
||||
At this stage functions that needs to be output into
|
||||
assembler are identified and compiled in topological order
|
||||
|
|
@ -197,14 +201,19 @@ along with GCC; see the file COPYING3. If not see
|
|||
may generate new functions that need to be optimized and expanded. */
|
||||
cgraph_node_set cgraph_new_nodes;
|
||||
|
||||
static void cgraph_expand_all_functions (void);
|
||||
static void cgraph_mark_functions_to_output (void);
|
||||
static void cgraph_expand_function (struct cgraph_node *);
|
||||
static void cgraph_output_pending_asms (void);
|
||||
static void expand_all_functions (void);
|
||||
static void mark_functions_to_output (void);
|
||||
static void expand_function (struct cgraph_node *);
|
||||
static void cgraph_analyze_function (struct cgraph_node *);
|
||||
|
||||
FILE *cgraph_dump_file;
|
||||
|
||||
/* Linked list of cgraph asm nodes. */
|
||||
struct asm_node *asm_nodes;
|
||||
|
||||
/* Last node in cgraph_asm_nodes. */
|
||||
static GTY(()) struct asm_node *asm_last_node;
|
||||
|
||||
/* Used for vtable lookup in thunk adjusting. */
|
||||
static GTY (()) tree vtable_entry_type;
|
||||
|
||||
|
|
@ -324,7 +333,7 @@ cgraph_process_new_functions (void)
|
|||
directly. */
|
||||
node->process = 0;
|
||||
cgraph_call_function_insertion_hooks (node);
|
||||
cgraph_expand_function (node);
|
||||
expand_function (node);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -372,12 +381,12 @@ cgraph_reset_node (struct cgraph_node *node)
|
|||
static bool
|
||||
referred_to_p (symtab_node node)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref;
|
||||
|
||||
for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref);
|
||||
i++)
|
||||
/* See if there are any refrences at all. */
|
||||
if (ipa_ref_list_referring_iterate (&node->symbol.ref_list, 0, ref))
|
||||
return true;
|
||||
/* For functions check also calls. */
|
||||
if (symtab_function_p (node) && cgraph (node)->callers)
|
||||
return true;
|
||||
return false;
|
||||
|
|
@ -518,7 +527,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
|||
execute_pass_list (pass_early_local_passes.pass.sub);
|
||||
bitmap_obstack_release (NULL);
|
||||
pop_cfun ();
|
||||
cgraph_expand_function (node);
|
||||
expand_function (node);
|
||||
current_function_decl = NULL;
|
||||
break;
|
||||
|
||||
|
|
@ -533,19 +542,54 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
|||
DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
|
||||
}
|
||||
|
||||
/* Add a top-level asm statement to the list. */
|
||||
|
||||
struct asm_node *
|
||||
add_asm_node (tree asm_str)
|
||||
{
|
||||
struct asm_node *node;
|
||||
|
||||
node = ggc_alloc_cleared_asm_node ();
|
||||
node->asm_str = asm_str;
|
||||
node->order = symtab_order++;
|
||||
node->next = NULL;
|
||||
if (asm_nodes == NULL)
|
||||
asm_nodes = node;
|
||||
else
|
||||
asm_last_node->next = node;
|
||||
asm_last_node = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Output all asm statements we have stored up to be output. */
|
||||
|
||||
static void
|
||||
cgraph_output_pending_asms (void)
|
||||
output_asm_statements (void)
|
||||
{
|
||||
struct cgraph_asm_node *can;
|
||||
struct asm_node *can;
|
||||
|
||||
if (seen_error ())
|
||||
return;
|
||||
|
||||
for (can = cgraph_asm_nodes; can; can = can->next)
|
||||
for (can = asm_nodes; can; can = can->next)
|
||||
assemble_asm (can->asm_str);
|
||||
cgraph_asm_nodes = NULL;
|
||||
asm_nodes = NULL;
|
||||
}
|
||||
|
||||
/* C++ FE sometimes change linkage flags after producing same body aliases. */
|
||||
void
|
||||
fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
|
||||
{
|
||||
DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
|
||||
if (TREE_PUBLIC (node->symbol.decl))
|
||||
{
|
||||
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
|
||||
DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
|
||||
DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
|
||||
if (DECL_ONE_ONLY (alias)
|
||||
&& !node->symbol.same_comdat_group)
|
||||
symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
|
||||
}
|
||||
}
|
||||
|
||||
/* Analyze the function scheduled to be output. */
|
||||
|
|
@ -576,39 +620,13 @@ cgraph_analyze_function (struct cgraph_node *node)
|
|||
IPA_REF_ALIAS, NULL);
|
||||
if (node->same_body_alias)
|
||||
{
|
||||
DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (node->thunk.alias);
|
||||
DECL_DECLARED_INLINE_P (node->symbol.decl)
|
||||
= DECL_DECLARED_INLINE_P (node->thunk.alias);
|
||||
DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
|
||||
= DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
|
||||
fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
|
||||
}
|
||||
|
||||
/* Fixup visibility nonsences C++ frontend produce on same body aliases. */
|
||||
if (TREE_PUBLIC (node->symbol.decl) && node->same_body_alias)
|
||||
{
|
||||
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->thunk.alias);
|
||||
if (DECL_ONE_ONLY (node->thunk.alias))
|
||||
{
|
||||
DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (node->thunk.alias);
|
||||
DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (node->thunk.alias);
|
||||
if (DECL_ONE_ONLY (node->thunk.alias) && !node->symbol.same_comdat_group)
|
||||
{
|
||||
struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
|
||||
node->symbol.same_comdat_group = (symtab_node)tgt;
|
||||
if (!tgt->symbol.same_comdat_group)
|
||||
tgt->symbol.same_comdat_group = (symtab_node)node;
|
||||
else
|
||||
{
|
||||
symtab_node n;
|
||||
for (n = tgt->symbol.same_comdat_group;
|
||||
n->symbol.same_comdat_group != (symtab_node)tgt;
|
||||
n = n->symbol.same_comdat_group)
|
||||
;
|
||||
n->symbol.same_comdat_group = (symtab_node)node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node->symbol.address_taken)
|
||||
cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
|
||||
}
|
||||
|
|
@ -1074,7 +1092,7 @@ handle_alias_pairs (void)
|
|||
/* Figure out what functions we want to assemble. */
|
||||
|
||||
static void
|
||||
cgraph_mark_functions_to_output (void)
|
||||
mark_functions_to_output (void)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
#ifdef ENABLE_CHECKING
|
||||
|
|
@ -1087,16 +1105,11 @@ cgraph_mark_functions_to_output (void)
|
|||
FOR_EACH_FUNCTION (node)
|
||||
{
|
||||
tree decl = node->symbol.decl;
|
||||
struct cgraph_edge *e;
|
||||
|
||||
gcc_assert (!node->process || node->symbol.same_comdat_group);
|
||||
if (node->process)
|
||||
continue;
|
||||
|
||||
for (e = node->callers; e; e = e->next_caller)
|
||||
if (e->inline_failed)
|
||||
break;
|
||||
|
||||
/* We need to output all local functions that are used and not
|
||||
always inlined, as well as those that are reachable from
|
||||
outside the current compilation unit. */
|
||||
|
|
@ -1544,7 +1557,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
|
|||
/* Expand function specified by NODE. */
|
||||
|
||||
static void
|
||||
cgraph_expand_function (struct cgraph_node *node)
|
||||
expand_function (struct cgraph_node *node)
|
||||
{
|
||||
tree decl = node->symbol.decl;
|
||||
location_t saved_loc;
|
||||
|
|
@ -1641,9 +1654,9 @@ cgraph_expand_function (struct cgraph_node *node)
|
|||
current_function_decl = NULL;
|
||||
|
||||
/* It would make a lot more sense to output thunks before function body to get more
|
||||
forward and lest backwarding jumps. This is however would need solving problem
|
||||
forward and lest backwarding jumps. This however would need solving problem
|
||||
with comdats. See PR48668. Also aliases must come after function itself to
|
||||
make one pass assemblers, like one on AIX happy. See PR 50689.
|
||||
make one pass assemblers, like one on AIX, happy. See PR 50689.
|
||||
FIXME: Perhaps thunks should be move before function IFF they are not in comdat
|
||||
groups. */
|
||||
assemble_thunks_and_aliases (node);
|
||||
|
|
@ -1665,7 +1678,7 @@ cgraph_expand_function (struct cgraph_node *node)
|
|||
order). */
|
||||
|
||||
static void
|
||||
cgraph_expand_all_functions (void)
|
||||
expand_all_functions (void)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
|
||||
|
|
@ -1687,7 +1700,7 @@ cgraph_expand_all_functions (void)
|
|||
if (node->process)
|
||||
{
|
||||
node->process = 0;
|
||||
cgraph_expand_function (node);
|
||||
expand_function (node);
|
||||
}
|
||||
}
|
||||
cgraph_process_new_functions ();
|
||||
|
|
@ -1713,7 +1726,7 @@ struct cgraph_order_sort
|
|||
{
|
||||
struct cgraph_node *f;
|
||||
struct varpool_node *v;
|
||||
struct cgraph_asm_node *a;
|
||||
struct asm_node *a;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
|
@ -1724,14 +1737,14 @@ struct cgraph_order_sort
|
|||
need to be output. */
|
||||
|
||||
static void
|
||||
cgraph_output_in_order (void)
|
||||
output_in_order (void)
|
||||
{
|
||||
int max;
|
||||
struct cgraph_order_sort *nodes;
|
||||
int i;
|
||||
struct cgraph_node *pf;
|
||||
struct varpool_node *pv;
|
||||
struct cgraph_asm_node *pa;
|
||||
struct asm_node *pa;
|
||||
|
||||
max = symtab_order;
|
||||
nodes = XCNEWVEC (struct cgraph_order_sort, max);
|
||||
|
|
@ -1755,7 +1768,7 @@ cgraph_output_in_order (void)
|
|||
nodes[i].u.v = pv;
|
||||
}
|
||||
|
||||
for (pa = cgraph_asm_nodes; pa; pa = pa->next)
|
||||
for (pa = asm_nodes; pa; pa = pa->next)
|
||||
{
|
||||
i = pa->order;
|
||||
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
|
||||
|
|
@ -1775,7 +1788,7 @@ cgraph_output_in_order (void)
|
|||
{
|
||||
case ORDER_FUNCTION:
|
||||
nodes[i].u.f->process = 0;
|
||||
cgraph_expand_function (nodes[i].u.f);
|
||||
expand_function (nodes[i].u.f);
|
||||
break;
|
||||
|
||||
case ORDER_VAR:
|
||||
|
|
@ -1794,7 +1807,7 @@ cgraph_output_in_order (void)
|
|||
}
|
||||
}
|
||||
|
||||
cgraph_asm_nodes = NULL;
|
||||
asm_nodes = NULL;
|
||||
free (nodes);
|
||||
}
|
||||
|
||||
|
|
@ -2054,7 +2067,7 @@ cgraph_function_versioning (struct cgraph_node *old_version_node,
|
|||
that is not weak also.
|
||||
??? We cannot use COMDAT linkage because there is no
|
||||
ABI support for this. */
|
||||
cgraph_make_decl_local (new_version_node->symbol.decl);
|
||||
symtab_make_decl_local (new_version_node->symbol.decl);
|
||||
DECL_VIRTUAL_P (new_version_node->symbol.decl) = 0;
|
||||
new_version_node->symbol.externally_visible = 0;
|
||||
new_version_node->local.local = 1;
|
||||
|
|
@ -2275,7 +2288,7 @@ cgraph_materialize_all_clones (void)
|
|||
/* Perform simple optimizations based on callgraph. */
|
||||
|
||||
void
|
||||
cgraph_optimize (void)
|
||||
compile (void)
|
||||
{
|
||||
if (seen_error ())
|
||||
return;
|
||||
|
|
@ -2294,6 +2307,10 @@ cgraph_optimize (void)
|
|||
fprintf (stderr, "Performing interprocedural optimizations\n");
|
||||
cgraph_state = CGRAPH_STATE_IPA;
|
||||
|
||||
/* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
|
||||
if (flag_lto)
|
||||
lto_streamer_hooks_init ();
|
||||
|
||||
/* Don't run the IPA passes if there was any error or sorry messages. */
|
||||
if (!seen_error ())
|
||||
ipa_passes ();
|
||||
|
|
@ -2338,20 +2355,18 @@ cgraph_optimize (void)
|
|||
verify_symtab ();
|
||||
#endif
|
||||
bitmap_obstack_release (NULL);
|
||||
cgraph_mark_functions_to_output ();
|
||||
mark_functions_to_output ();
|
||||
output_weakrefs ();
|
||||
|
||||
cgraph_state = CGRAPH_STATE_EXPANSION;
|
||||
if (!flag_toplevel_reorder)
|
||||
cgraph_output_in_order ();
|
||||
output_in_order ();
|
||||
else
|
||||
{
|
||||
cgraph_output_pending_asms ();
|
||||
output_asm_statements ();
|
||||
|
||||
cgraph_expand_all_functions ();
|
||||
varpool_remove_unreferenced_decls ();
|
||||
|
||||
varpool_assemble_pending_decls ();
|
||||
expand_all_functions ();
|
||||
varpool_output_variables ();
|
||||
}
|
||||
|
||||
cgraph_process_new_functions ();
|
||||
|
|
@ -2388,14 +2403,10 @@ cgraph_optimize (void)
|
|||
/* Analyze the whole compilation unit once it is parsed completely. */
|
||||
|
||||
void
|
||||
cgraph_finalize_compilation_unit (void)
|
||||
finalize_compilation_unit (void)
|
||||
{
|
||||
timevar_push (TV_CGRAPH);
|
||||
|
||||
/* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
|
||||
if (flag_lto)
|
||||
lto_streamer_hooks_init ();
|
||||
|
||||
/* If we're here there's no current function anymore. Some frontends
|
||||
are lazy in clearing these. */
|
||||
current_function_decl = NULL;
|
||||
|
|
@ -2432,7 +2443,7 @@ cgraph_finalize_compilation_unit (void)
|
|||
cgraph_analyze_functions ();
|
||||
|
||||
/* Finally drive the pass manager. */
|
||||
cgraph_optimize ();
|
||||
compile ();
|
||||
|
||||
timevar_pop (TV_CGRAPH);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1830,7 +1830,7 @@ maybe_emit_vtables (tree ctype)
|
|||
tree vtbl;
|
||||
tree primary_vtbl;
|
||||
int needed = 0;
|
||||
struct varpool_node *current = NULL, *last = NULL, *first = NULL;
|
||||
struct varpool_node *current = NULL, *last = NULL;
|
||||
|
||||
/* If the vtables for this class have already been emitted there is
|
||||
nothing more to do. */
|
||||
|
|
@ -1894,16 +1894,11 @@ maybe_emit_vtables (tree ctype)
|
|||
{
|
||||
current = varpool_node (vtbl);
|
||||
if (last)
|
||||
last->symbol.same_comdat_group = (symtab_node) current;
|
||||
symtab_add_to_same_comdat_group ((symtab_node) current, (symtab_node) last);
|
||||
last = current;
|
||||
if (!first)
|
||||
first = current;
|
||||
}
|
||||
}
|
||||
|
||||
if (first != last)
|
||||
last->symbol.same_comdat_group = (symtab_node)first;
|
||||
|
||||
/* Since we're writing out the vtable here, also write the debug
|
||||
info. */
|
||||
note_debug_info_needed (ctype);
|
||||
|
|
@ -4027,7 +4022,7 @@ cp_write_global_declarations (void)
|
|||
timevar_stop (TV_PHASE_DEFERRED);
|
||||
timevar_start (TV_PHASE_CGRAPH);
|
||||
|
||||
cgraph_finalize_compilation_unit ();
|
||||
finalize_compilation_unit ();
|
||||
|
||||
timevar_stop (TV_PHASE_CGRAPH);
|
||||
timevar_start (TV_PHASE_CHECK_DBGINFO);
|
||||
|
|
|
|||
|
|
@ -389,7 +389,8 @@ use_thunk (tree thunk_fndecl, bool emit_p)
|
|||
this_adjusting, fixed_offset, virtual_value,
|
||||
virtual_offset, alias);
|
||||
if (DECL_ONE_ONLY (function))
|
||||
cgraph_add_to_same_comdat_group (thunk_node, funcn);
|
||||
symtab_add_to_same_comdat_group ((symtab_node) thunk_node,
|
||||
(symtab_node) funcn);
|
||||
|
||||
if (!this_adjusting
|
||||
|| !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
|
||||
|
|
|
|||
|
|
@ -324,8 +324,8 @@ maybe_clone_body (tree fn)
|
|||
*[CD][12]*. */
|
||||
comdat_group = cdtor_comdat_group (fns[1], fns[0]);
|
||||
DECL_COMDAT_GROUP (fns[0]) = comdat_group;
|
||||
cgraph_add_to_same_comdat_group (cgraph_get_node (clone),
|
||||
cgraph_get_node (fns[0]));
|
||||
symtab_add_to_same_comdat_group (symtab_get_node (clone),
|
||||
symtab_get_node (fns[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -337,8 +337,9 @@ maybe_clone_body (tree fn)
|
|||
/* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is
|
||||
virtual, it goes into the same comdat group as well. */
|
||||
if (comdat_group)
|
||||
cgraph_add_to_same_comdat_group (cgraph_get_create_node (clone),
|
||||
cgraph_get_node (fns[0]));
|
||||
symtab_add_to_same_comdat_group
|
||||
((symtab_node) cgraph_get_create_node (clone),
|
||||
symtab_get_node (fns[0]));
|
||||
}
|
||||
else if (alias)
|
||||
/* No need to populate body. */ ;
|
||||
|
|
|
|||
|
|
@ -15377,7 +15377,7 @@ cp_parser_asm_definition (cp_parser* parser)
|
|||
}
|
||||
}
|
||||
else
|
||||
cgraph_add_asm_node (string);
|
||||
add_asm_node (string);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9330,8 +9330,9 @@ maybe_add_lambda_conv_op (tree type)
|
|||
if (DECL_ONE_ONLY (statfn))
|
||||
{
|
||||
/* Put the thunk in the same comdat group as the call op. */
|
||||
cgraph_add_to_same_comdat_group (cgraph_get_create_node (statfn),
|
||||
cgraph_get_create_node (callop));
|
||||
symtab_add_to_same_comdat_group
|
||||
((symtab_node) cgraph_get_create_node (statfn),
|
||||
(symtab_node) cgraph_get_create_node (callop));
|
||||
}
|
||||
body = begin_function_body ();
|
||||
compound_stmt = begin_compound_stmt (0);
|
||||
|
|
|
|||
|
|
@ -20378,7 +20378,7 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
|
|||
text_section_line_info->end_label = text_end_label;
|
||||
}
|
||||
|
||||
/* Called before cgraph_optimize starts outputtting functions, variables
|
||||
/* Called before compile () starts outputtting functions, variables
|
||||
and toplevel asms into assembly. */
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2012-04-30 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* f95-lang.c (gfc_finish): Update comments.
|
||||
|
||||
2012-04-29 Thomas Koenig <tkoenig@gcc.gnu.org>
|
||||
|
||||
PR fortran/53148
|
||||
|
|
|
|||
|
|
@ -242,11 +242,11 @@ gfc_finish (void)
|
|||
/* ??? This is something of a hack.
|
||||
|
||||
Emulated tls lowering needs to see all TLS variables before we call
|
||||
cgraph_finalize_compilation_unit. The C/C++ front ends manage this
|
||||
finalize_compilation_unit. The C/C++ front ends manage this
|
||||
by calling decl_rest_of_compilation on each global and static variable
|
||||
as they are seen. The Fortran front end waits until this hook.
|
||||
|
||||
A Correct solution is for cgraph_finalize_compilation_unit not to be
|
||||
A Correct solution is for finalize_compilation_unit not to be
|
||||
called during the WRITE_GLOBALS langhook, and have that hook only do what
|
||||
its name suggests and write out globals. But the C++ and Java front ends
|
||||
have (unspecified) problems with aliases that gets in the way. It has
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2012-04-30 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gogo-tree.cc (Gogo::write_globals): Use finalize_compilation_unit.
|
||||
|
||||
2012-04-23 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* go-lang.c (go_langhook_init): Set MPFR precision to 256.
|
||||
|
|
|
|||
|
|
@ -930,7 +930,7 @@ Gogo::write_globals()
|
|||
|
||||
wrapup_global_declarations(vec, count);
|
||||
|
||||
cgraph_finalize_compilation_unit();
|
||||
finalize_compilation_unit();
|
||||
|
||||
check_global_declarations(vec, count);
|
||||
emit_debug_global_declarations(vec, count);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
|
|||
For now we keep the ohter functions in the group in program until
|
||||
cgraph_remove_unreachable_functions gets rid of them. */
|
||||
gcc_assert (!e->callee->global.inlined_to);
|
||||
symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee);
|
||||
if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->symbol.decl))
|
||||
{
|
||||
if (overall_size)
|
||||
|
|
@ -176,6 +177,8 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
|
|||
cgraph_redirect_edge_callee (e, n);
|
||||
}
|
||||
}
|
||||
else
|
||||
symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee);
|
||||
|
||||
if (e->caller->global.inlined_to)
|
||||
e->callee->global.inlined_to = e->caller->global.inlined_to;
|
||||
|
|
@ -355,7 +358,7 @@ save_inline_function_body (struct cgraph_node *node)
|
|||
|
||||
/* Return true when function body of DECL still needs to be kept around
|
||||
for later re-use. */
|
||||
bool
|
||||
static bool
|
||||
preserve_function_body_p (struct cgraph_node *node)
|
||||
{
|
||||
gcc_assert (cgraph_global_info_ready);
|
||||
|
|
|
|||
31
gcc/ipa.c
31
gcc/ipa.c
|
|
@ -598,7 +598,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
|
|||
return true;
|
||||
|
||||
/* If linker counts on us, we must preserve the function. */
|
||||
if (cgraph_used_from_object_file_p (node))
|
||||
if (symtab_used_from_object_file_p ((symtab_node) node))
|
||||
return true;
|
||||
if (DECL_PRESERVE_P (node->symbol.decl))
|
||||
return true;
|
||||
|
|
@ -657,7 +657,7 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
|
|||
return true;
|
||||
|
||||
/* If linker counts on us, we must preserve the function. */
|
||||
if (varpool_used_from_object_file_p (vnode))
|
||||
if (symtab_used_from_object_file_p ((symtab_node) vnode))
|
||||
return true;
|
||||
|
||||
if (DECL_HARD_REGISTER (vnode->symbol.decl))
|
||||
|
|
@ -678,7 +678,7 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
|
|||
Even if the linker clams the symbol is unused, never bring internal
|
||||
symbols that are declared by user as used or externally visible.
|
||||
This is needed for i.e. references from asm statements. */
|
||||
if (varpool_used_from_object_file_p (vnode))
|
||||
if (symtab_used_from_object_file_p ((symtab_node) vnode))
|
||||
return true;
|
||||
if (vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY)
|
||||
return false;
|
||||
|
|
@ -716,21 +716,6 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Dissolve the same_comdat_group list in which NODE resides. */
|
||||
|
||||
static void
|
||||
dissolve_same_comdat_group_list (symtab_node node)
|
||||
{
|
||||
symtab_node n = node, next;
|
||||
do
|
||||
{
|
||||
next = n->symbol.same_comdat_group;
|
||||
n->symbol.same_comdat_group = NULL;
|
||||
n = next;
|
||||
}
|
||||
while (n != node);
|
||||
}
|
||||
|
||||
/* Mark visibility of all functions.
|
||||
|
||||
A local function is one whose calls can occur only in the current
|
||||
|
|
@ -825,7 +810,7 @@ function_and_variable_visibility (bool whole_program)
|
|||
all of them have to be, otherwise it is a front-end bug. */
|
||||
gcc_assert (DECL_EXTERNAL (n->symbol.decl));
|
||||
#endif
|
||||
dissolve_same_comdat_group_list ((symtab_node) node);
|
||||
symtab_dissolve_same_comdat_group_list ((symtab_node) node);
|
||||
}
|
||||
gcc_assert ((!DECL_WEAK (node->symbol.decl)
|
||||
&& !DECL_COMDAT (node->symbol.decl))
|
||||
|
|
@ -845,14 +830,14 @@ function_and_variable_visibility (bool whole_program)
|
|||
{
|
||||
gcc_assert (whole_program || in_lto_p
|
||||
|| !TREE_PUBLIC (node->symbol.decl));
|
||||
cgraph_make_decl_local (node->symbol.decl);
|
||||
symtab_make_decl_local (node->symbol.decl);
|
||||
node->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
|
||||
if (node->symbol.same_comdat_group)
|
||||
/* cgraph_externally_visible_p has already checked all other nodes
|
||||
in the group and they will all be made local. We need to
|
||||
dissolve the group at once so that the predicate does not
|
||||
segfault though. */
|
||||
dissolve_same_comdat_group_list ((symtab_node) node);
|
||||
symtab_dissolve_same_comdat_group_list ((symtab_node) node);
|
||||
}
|
||||
|
||||
if (node->thunk.thunk_p
|
||||
|
|
@ -921,9 +906,9 @@ function_and_variable_visibility (bool whole_program)
|
|||
if (!vnode->symbol.externally_visible)
|
||||
{
|
||||
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
|
||||
cgraph_make_decl_local (vnode->symbol.decl);
|
||||
symtab_make_decl_local (vnode->symbol.decl);
|
||||
if (vnode->symbol.same_comdat_group)
|
||||
dissolve_same_comdat_group_list ((symtab_node) vnode);
|
||||
symtab_dissolve_same_comdat_group_list ((symtab_node) vnode);
|
||||
vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
|
||||
}
|
||||
gcc_assert (TREE_STATIC (vnode->symbol.decl));
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ write_global_declarations (void)
|
|||
|
||||
/* This lang hook is dual-purposed, and also finalizes the
|
||||
compilation unit. */
|
||||
cgraph_finalize_compilation_unit ();
|
||||
finalize_compilation_unit ();
|
||||
|
||||
/* Really define vars that have had only a tentative definition.
|
||||
Really output inline functions that must actually be callable
|
||||
|
|
|
|||
|
|
@ -1223,7 +1223,7 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
|
|||
|
||||
while ((str = streamer_read_string_cst (data_in, &ib)))
|
||||
{
|
||||
struct cgraph_asm_node *node = cgraph_add_asm_node (str);
|
||||
struct asm_node *node = add_asm_node (str);
|
||||
node->order = streamer_read_hwi (&ib) + order_base;
|
||||
if (node->order >= symtab_order)
|
||||
symtab_order = node->order + 1;
|
||||
|
|
|
|||
|
|
@ -968,12 +968,12 @@ void
|
|||
lto_output_toplevel_asms (void)
|
||||
{
|
||||
struct output_block *ob;
|
||||
struct cgraph_asm_node *can;
|
||||
struct asm_node *can;
|
||||
char *section_name;
|
||||
struct lto_output_stream *header_stream;
|
||||
struct lto_asm_header header;
|
||||
|
||||
if (! cgraph_asm_nodes)
|
||||
if (! asm_nodes)
|
||||
return;
|
||||
|
||||
ob = create_output_block (LTO_section_asm);
|
||||
|
|
@ -981,7 +981,7 @@ lto_output_toplevel_asms (void)
|
|||
/* Make string 0 be a NULL string. */
|
||||
streamer_write_char_stream (ob->string_stream, 0);
|
||||
|
||||
for (can = cgraph_asm_nodes; can; can = can->next)
|
||||
for (can = asm_nodes; can; can = can->next)
|
||||
{
|
||||
streamer_write_string_cst (ob, ob->main_stream, can->asm_str);
|
||||
streamer_write_hwi (ob, can->order);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
2012-04-30 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto.c (lto_main): Use compile ().
|
||||
* lto-partition.c (partition_cgraph_node_p): Use symtab_used_from_object_file_p.
|
||||
(partition_varpool_node_p): Likewise.
|
||||
|
||||
2012-04-20 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto-partition.c (partition_cgraph_node_p): Use force_output.
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ partition_cgraph_node_p (struct cgraph_node *node)
|
|||
if (DECL_EXTERNAL (node->symbol.decl)
|
||||
|| (DECL_COMDAT (node->symbol.decl)
|
||||
&& !node->symbol.force_output
|
||||
&& !cgraph_used_from_object_file_p (node)))
|
||||
&& !symtab_used_from_object_file_p ((symtab_node) node)))
|
||||
return false;
|
||||
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
|
||||
return false;
|
||||
|
|
@ -289,7 +289,7 @@ partition_varpool_node_p (struct varpool_node *vnode)
|
|||
if (DECL_IN_CONSTANT_POOL (vnode->symbol.decl)
|
||||
|| (DECL_COMDAT (vnode->symbol.decl)
|
||||
&& !vnode->symbol.force_output
|
||||
&& !varpool_used_from_object_file_p (vnode)))
|
||||
&& !symtab_used_from_object_file_p ((symtab_node) vnode)))
|
||||
return false;
|
||||
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -2116,7 +2116,7 @@ lto_main (void)
|
|||
|
||||
/* Let the middle end know that we have read and merged all of
|
||||
the input files. */
|
||||
cgraph_optimize ();
|
||||
compile ();
|
||||
|
||||
/* FIXME lto, if the processes spawned by WPA fail, we miss
|
||||
the chance to print WPA's report, so WPA will call
|
||||
|
|
|
|||
17
gcc/passes.c
17
gcc/passes.c
|
|
@ -1248,19 +1248,24 @@ register_pass (struct register_pass_info *pass_info)
|
|||
/* Construct the pass tree. The sequencing of passes is driven by
|
||||
the cgraph routines:
|
||||
|
||||
cgraph_finalize_compilation_unit ()
|
||||
finalize_compilation_unit ()
|
||||
for each node N in the cgraph
|
||||
cgraph_analyze_function (N)
|
||||
cgraph_lower_function (N) -> all_lowering_passes
|
||||
|
||||
If we are optimizing, cgraph_optimize is then invoked:
|
||||
If we are optimizing, compile is then invoked:
|
||||
|
||||
cgraph_optimize ()
|
||||
compile ()
|
||||
ipa_passes () -> all_small_ipa_passes
|
||||
cgraph_expand_all_functions ()
|
||||
-> Analysis of all_regular_ipa_passes
|
||||
* possible LTO streaming at copmilation time *
|
||||
-> Execution of all_regular_ipa_passes
|
||||
* possible LTO streaming at link time *
|
||||
-> all_late_ipa_passes
|
||||
expand_all_functions ()
|
||||
for each node N in the cgraph
|
||||
cgraph_expand_function (N)
|
||||
tree_rest_of_compilation (DECL (N)) -> all_passes
|
||||
expand_function (N) -> Transformation of all_regular_ipa_passes
|
||||
-> all_passes
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
|
|||
137
gcc/symtab.c
137
gcc/symtab.c
|
|
@ -30,6 +30,22 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cgraph.h"
|
||||
#include "diagnostic.h"
|
||||
#include "timevar.h"
|
||||
#include "lto-streamer.h"
|
||||
#include "rtl.h"
|
||||
|
||||
const char * const ld_plugin_symbol_resolution_names[]=
|
||||
{
|
||||
"",
|
||||
"undef",
|
||||
"prevailing_def",
|
||||
"prevailing_def_ironly",
|
||||
"preempted_reg",
|
||||
"preempted_ir",
|
||||
"resolved_ir",
|
||||
"resolved_exec",
|
||||
"resolved_dyn",
|
||||
"prevailing_def_ironly_exp"
|
||||
};
|
||||
|
||||
/* Hash table used to convert declarations into nodes. */
|
||||
static GTY((param_is (union symtab_node_def))) htab_t symtab_hash;
|
||||
|
|
@ -335,6 +351,49 @@ change_decl_assembler_name (tree decl, tree name)
|
|||
}
|
||||
}
|
||||
|
||||
/* Add NEW_ to the same comdat group that OLD is in. */
|
||||
|
||||
void
|
||||
symtab_add_to_same_comdat_group (symtab_node new_node,
|
||||
symtab_node old_node)
|
||||
{
|
||||
gcc_assert (DECL_ONE_ONLY (old_node->symbol.decl));
|
||||
gcc_assert (!new_node->symbol.same_comdat_group);
|
||||
gcc_assert (new_node != old_node);
|
||||
|
||||
DECL_COMDAT_GROUP (new_node->symbol.decl) = DECL_COMDAT_GROUP (old_node->symbol.decl);
|
||||
new_node->symbol.same_comdat_group = old_node;
|
||||
if (!old_node->symbol.same_comdat_group)
|
||||
old_node->symbol.same_comdat_group = new_node;
|
||||
else
|
||||
{
|
||||
symtab_node n;
|
||||
for (n = old_node->symbol.same_comdat_group;
|
||||
n->symbol.same_comdat_group != old_node;
|
||||
n = n->symbol.same_comdat_group)
|
||||
;
|
||||
n->symbol.same_comdat_group = new_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dissolve the same_comdat_group list in which NODE resides. */
|
||||
|
||||
void
|
||||
symtab_dissolve_same_comdat_group_list (symtab_node node)
|
||||
{
|
||||
symtab_node n = node, next;
|
||||
|
||||
if (!node->symbol.same_comdat_group)
|
||||
return;
|
||||
do
|
||||
{
|
||||
next = n->symbol.same_comdat_group;
|
||||
n->symbol.same_comdat_group = NULL;
|
||||
n = next;
|
||||
}
|
||||
while (n != node);
|
||||
}
|
||||
|
||||
/* Return printable assembler name of NODE.
|
||||
This function is used only for debugging. When assembler name
|
||||
is unknown go with identifier name. */
|
||||
|
|
@ -611,4 +670,82 @@ verify_symtab (void)
|
|||
verify_symtab_node (node);
|
||||
}
|
||||
|
||||
/* Return true when RESOLUTION indicate that linker will use
|
||||
the symbol from non-LTO object files. */
|
||||
|
||||
bool
|
||||
resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution resolution)
|
||||
{
|
||||
return (resolution == LDPR_PREVAILING_DEF
|
||||
|| resolution == LDPR_PREEMPTED_REG
|
||||
|| resolution == LDPR_RESOLVED_EXEC
|
||||
|| resolution == LDPR_RESOLVED_DYN);
|
||||
}
|
||||
|
||||
/* Return true when NODE is known to be used from other (non-LTO) object file.
|
||||
Known only when doing LTO via linker plugin. */
|
||||
|
||||
bool
|
||||
symtab_used_from_object_file_p (symtab_node node)
|
||||
{
|
||||
if (!TREE_PUBLIC (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl))
|
||||
return false;
|
||||
if (resolution_used_from_other_file_p (node->symbol.resolution))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
|
||||
but other code such as notice_global_symbol generates rtl. */
|
||||
void
|
||||
symtab_make_decl_local (tree decl)
|
||||
{
|
||||
rtx rtl, symbol;
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL)
|
||||
DECL_COMMON (decl) = 0;
|
||||
else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
|
||||
|
||||
if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
|
||||
{
|
||||
/* It is possible that we are linking against library defining same COMDAT
|
||||
function. To avoid conflict we need to rename our local name of the
|
||||
function just in the case WHOPR partitioning decide to make it hidden
|
||||
to avoid cross partition references. */
|
||||
if (flag_wpa)
|
||||
{
|
||||
const char *old_name;
|
||||
symtab_node node = symtab_get_node (decl);
|
||||
old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
change_decl_assembler_name (decl,
|
||||
clone_function_name (decl, "local"));
|
||||
if (node->symbol.lto_file_data)
|
||||
lto_record_renamed_decl (node->symbol.lto_file_data,
|
||||
old_name,
|
||||
IDENTIFIER_POINTER
|
||||
(DECL_ASSEMBLER_NAME (decl)));
|
||||
}
|
||||
DECL_SECTION_NAME (decl) = 0;
|
||||
DECL_COMDAT (decl) = 0;
|
||||
}
|
||||
DECL_COMDAT_GROUP (decl) = 0;
|
||||
DECL_WEAK (decl) = 0;
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
if (!DECL_RTL_SET_P (decl))
|
||||
return;
|
||||
|
||||
/* Update rtl flags. */
|
||||
make_decl_rtl (decl);
|
||||
|
||||
rtl = DECL_RTL (decl);
|
||||
if (!MEM_P (rtl))
|
||||
return;
|
||||
|
||||
symbol = XEXP (rtl, 0);
|
||||
if (GET_CODE (symbol) != SYMBOL_REF)
|
||||
return;
|
||||
|
||||
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
|
||||
}
|
||||
#include "gt-symtab.h"
|
||||
|
|
|
|||
|
|
@ -567,7 +567,7 @@ compile_file (void)
|
|||
|
||||
ggc_protect_identifiers = false;
|
||||
|
||||
/* This must also call cgraph_finalize_compilation_unit. */
|
||||
/* This must also call finalize_compilation_unit. */
|
||||
lang_hooks.decls.final_write_globals ();
|
||||
|
||||
if (seen_error ())
|
||||
|
|
@ -580,8 +580,7 @@ compile_file (void)
|
|||
basically finished. */
|
||||
if (in_lto_p || !flag_lto || flag_fat_lto_objects)
|
||||
{
|
||||
varpool_remove_unreferenced_decls ();
|
||||
varpool_assemble_pending_decls ();
|
||||
varpool_output_variables ();
|
||||
finish_aliases_2 ();
|
||||
|
||||
/* Likewise for mudflap static object registrations. */
|
||||
|
|
|
|||
|
|
@ -237,34 +237,13 @@ varpool_analyze_node (struct varpool_node *node)
|
|||
}
|
||||
if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
|
||||
ipa_record_reference ((symtab_node)node, (symtab_node)tgt, IPA_REF_ALIAS, NULL);
|
||||
/* C++ FE sometimes change linkage flags after producing same body aliases. */
|
||||
if (node->extra_name_alias)
|
||||
{
|
||||
DECL_WEAK (node->symbol.decl) = DECL_WEAK (node->alias_of);
|
||||
TREE_PUBLIC (node->symbol.decl) = TREE_PUBLIC (node->alias_of);
|
||||
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->alias_of);
|
||||
DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (node->alias_of);
|
||||
if (TREE_PUBLIC (node->symbol.decl))
|
||||
{
|
||||
DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (node->alias_of);
|
||||
DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (node->alias_of);
|
||||
if (DECL_ONE_ONLY (node->alias_of)
|
||||
&& !node->symbol.same_comdat_group)
|
||||
{
|
||||
node->symbol.same_comdat_group = (symtab_node)tgt;
|
||||
if (!tgt->symbol.same_comdat_group)
|
||||
tgt->symbol.same_comdat_group = (symtab_node)node;
|
||||
else
|
||||
{
|
||||
symtab_node n;
|
||||
for (n = tgt->symbol.same_comdat_group;
|
||||
n->symbol.same_comdat_group != (symtab_node)tgt;
|
||||
n = n->symbol.same_comdat_group)
|
||||
;
|
||||
n->symbol.same_comdat_group = (symtab_node)node;
|
||||
}
|
||||
}
|
||||
}
|
||||
fixup_same_cpp_alias_visibility ((symtab_node) node,
|
||||
(symtab_node) tgt, node->alias_of);
|
||||
}
|
||||
}
|
||||
else if (DECL_INITIAL (decl))
|
||||
|
|
@ -331,7 +310,7 @@ enqueue_node (struct varpool_node *node, struct varpool_node **first)
|
|||
reachability starting from variables that are either externally visible
|
||||
or was referred from the asm output routines. */
|
||||
|
||||
void
|
||||
static void
|
||||
varpool_remove_unreferenced_decls (void)
|
||||
{
|
||||
struct varpool_node *next, *node;
|
||||
|
|
@ -413,7 +392,7 @@ varpool_finalize_named_section_flags (struct varpool_node *node)
|
|||
|
||||
/* Output all variables enqueued to be assembled. */
|
||||
bool
|
||||
varpool_assemble_pending_decls (void)
|
||||
varpool_output_variables (void)
|
||||
{
|
||||
bool changed = false;
|
||||
struct varpool_node *node;
|
||||
|
|
@ -421,6 +400,8 @@ varpool_assemble_pending_decls (void)
|
|||
if (seen_error ())
|
||||
return false;
|
||||
|
||||
varpool_remove_unreferenced_decls ();
|
||||
|
||||
timevar_push (TV_VAROUT);
|
||||
|
||||
FOR_EACH_DEFINED_VARIABLE (node)
|
||||
|
|
@ -501,19 +482,6 @@ varpool_extra_name_alias (tree alias, tree decl)
|
|||
return alias_node;
|
||||
}
|
||||
|
||||
/* Return true when NODE is known to be used from other (non-LTO) object file.
|
||||
Known only when doing LTO via linker plugin. */
|
||||
|
||||
bool
|
||||
varpool_used_from_object_file_p (struct varpool_node *node)
|
||||
{
|
||||
if (!TREE_PUBLIC (node->symbol.decl))
|
||||
return false;
|
||||
if (resolution_used_from_other_file_p (node->symbol.resolution))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Call calback on NODE and aliases asociated to NODE.
|
||||
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
|
||||
skipped. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue