From: hubicka Date: Mon, 30 Apr 2012 17:55:29 +0000 (+0000) Subject: * cgraph.c (ld_plugin_symbol_resolution_names): Move to symtab.c X-Git-Tag: upstream/4.9.2~12952 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cf951b1adfb70d786d542c0bdf28a72557121c47;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186998 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 461f162..6005359 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,96 @@ +012-04-30 Jan Hubicka + + * 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 PR c++/51033 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 31d5ac4..e733b68 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2012-04-30 Jan Hubicka + + * gcc-interface/utils.c (rest_of_subprog_body_compilation): Update + comment. + (gnat_write_global_declarations): Use finalize_compilation_unit. + 2012-04-30 Eric Botcazou * gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode, diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 03d7cb0..6d267e0 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -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. */ diff --git a/gcc/c-decl.c b/gcc/c-decl.c index e34c843..72fad86 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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); diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index ed847c0..3308ca8 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -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); } diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 87e43dc..47908f1 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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 %<;%>"); } diff --git a/gcc/cgraph.c b/gcc/cgraph.c index e689d10..ebba1b7 100644 --- a/gcc/cgraph.c +++ b/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"); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 652556f..eefb2f4 100644 --- a/gcc/cgraph.h +++ b/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 */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 60ccc82..f922a5e 100644 --- a/gcc/cgraphunit.c +++ b/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 (); - - 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 (); @@ -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); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7088c67..5d1f8de 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index cea44d4..77f8839 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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, diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 6a06988..5698c97 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -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. */ ; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8fcbba6..0c42353 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15377,7 +15377,7 @@ cp_parser_asm_definition (cp_parser* parser) } } else - cgraph_add_asm_node (string); + add_asm_node (string); } } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a621f25..90378dc 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index fd485fb..8bbf954 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 8d04904..ee13c2f 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,7 @@ +2012-04-30 Jan Hubicka + + * f95-lang.c (gfc_finish): Update comments. + 2012-04-29 Thomas Koenig PR fortran/53148 diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 3f28e67..3f0c303 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -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 diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 652a36d..951d3f9 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,7 @@ +2012-04-30 Jan Hubicka + + * gogo-tree.cc (Gogo::write_globals): Use finalize_compilation_unit. + 2012-04-23 Ian Lance Taylor * go-lang.c (go_langhook_init): Set MPFR precision to 256. diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 762f9fc..7f73238 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -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); diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index e07468a..1c77e86 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -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); diff --git a/gcc/ipa.c b/gcc/ipa.c index 5a97008..a722386 100644 --- a/gcc/ipa.c +++ b/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)); diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 9d0e25e..cb5da8c 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -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 diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 1f2bfb6..24d8d4f 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -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; diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 89850f0..9a54f19 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -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); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 6b86475..f9c5d30 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2012-04-30 Jan Hubicka + + * 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 * lto-partition.c (partition_cgraph_node_p): Use force_output. diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index e2aa595..5c931e68 100644 --- a/gcc/lto/lto-partition.c +++ b/gcc/lto/lto-partition.c @@ -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; diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index fb374ff..32fc869 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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 diff --git a/gcc/passes.c b/gcc/passes.c index 4724f80..d6b9b9b 100644 --- a/gcc/passes.c +++ b/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 diff --git a/gcc/symtab.c b/gcc/symtab.c index f393763..1d9fdd8 100644 --- a/gcc/symtab.c +++ b/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" diff --git a/gcc/toplev.c b/gcc/toplev.c index 53590b0..7d7be83 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -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. */ diff --git a/gcc/varpool.c b/gcc/varpool.c index 75e546d..103b5b5 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -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. */