(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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186998
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
+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,
/* 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
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. */
/* 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);
#include "diagnostic.h"
#include "opts.h"
#include "plugin.h"
+#include "cgraph.h"
#define GCC_BAD(gmsgid) \
do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
tree alias_id, id, decl;
int i;
pending_weak *pe;
+ symtab_node target;
FOR_EACH_VEC_ELT (pending_weak, pending_weaks, i, pe)
{
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);
}
{
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 %<;%>");
}
#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);
/* 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;
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
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)
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. */
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;
/* 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;
}
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
}
}
-/* 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. */
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");
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. */
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;
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);
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 *);
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);
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 *);
(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 *,
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);
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 */
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);
node->symbol.force_output = 1;
gcc_checking_assert (!node->global.inlined_to);
}
+
#endif /* GCC_CGRAPH_H */
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.
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
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
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;
directly. */
node->process = 0;
cgraph_call_function_insertion_hooks (node);
- cgraph_expand_function (node);
+ expand_function (node);
break;
default:
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;
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;
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. */
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));
}
/* 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
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. */
/* 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;
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);
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);
if (node->process)
{
node->process = 0;
- cgraph_expand_function (node);
+ expand_function (node);
}
}
cgraph_process_new_functions ();
{
struct cgraph_node *f;
struct varpool_node *v;
- struct cgraph_asm_node *a;
+ struct asm_node *a;
} u;
};
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);
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);
{
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:
}
}
- cgraph_asm_nodes = NULL;
+ asm_nodes = NULL;
free (nodes);
}
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;
/* Perform simple optimizations based on callgraph. */
void
-cgraph_optimize (void)
+compile (void)
{
if (seen_error ())
return;
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 ();
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 ();
-
- cgraph_expand_all_functions ();
- varpool_remove_unreferenced_decls ();
+ output_asm_statements ();
- varpool_assemble_pending_decls ();
+ expand_all_functions ();
+ varpool_output_variables ();
}
cgraph_process_new_functions ();
/* 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;
cgraph_analyze_functions ();
/* Finally drive the pass manager. */
- cgraph_optimize ();
+ compile ();
timevar_pop (TV_CGRAPH);
}
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. */
{
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);
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);
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,
*[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]));
}
}
/* 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. */ ;
}
}
else
- cgraph_add_asm_node (string);
+ add_asm_node (string);
}
}
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);
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
+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
/* ??? 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
+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.
wrapup_global_declarations(vec, count);
- cgraph_finalize_compilation_unit();
+ finalize_compilation_unit();
check_global_declarations(vec, count);
emit_debug_global_declarations(vec, count);
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)
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;
/* 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);
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;
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))
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;
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
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))
{
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
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));
/* 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
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;
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);
/* 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);
+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.
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;
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;
/* 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
/* 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
#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;
}
}
+/* 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. */
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"
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 ())
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. */
}
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))
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;
/* Output all variables enqueued to be assembled. */
bool
-varpool_assemble_pending_decls (void)
+varpool_output_variables (void)
{
bool changed = false;
struct varpool_node *node;
if (seen_error ())
return false;
+ varpool_remove_unreferenced_decls ();
+
timevar_push (TV_VAROUT);
FOR_EACH_DEFINED_VARIABLE (node)
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. */