diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-01 13:08:53 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-01 13:08:53 +0000 |
commit | 48669653091db6b1a1e1ff6fa5c2acf65fdad761 (patch) | |
tree | 227ede588b4d6d5d96381098725519f26a853909 /gcc/cgraphunit.c | |
parent | a47321b78ae92ae535fb3f3de0c05250c1c03068 (diff) | |
download | gcc-48669653091db6b1a1e1ff6fa5c2acf65fdad761.tar.gz |
* lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Rename to ...
(lto_symtab_merge_symbols_1): ... this one.
(lto_symtab_merge_cgraph_nodes): Rename to ...
(lto_symtab_merge_symbols): ... this one; simplify.
* cgraph.c (same_body_aliases_done): Rename to ...
(cpp_implicit_aliases_done): ... this one.
(cgraph_create_function_alias): Update.
(cgraph_same_body_alias): Update.
(dump_cgraph_node): Remove alias dumping; simplify
thunk dumping.
(verify_edge_corresponds_to_fndecl): Simplify.
* cgraph.h (symtab_node_base): Add cpp_implicit_alias,
alias_target.
(cgraph_node): Remove same_body_alias.
(varpool_node): Remove alias_of and extra_name_alias.
(same_body_aliases_done): Rename to ..
(cpp_implicit_aliases_done): ... this one.
(symtab_alias_ultimate_target): Add default parameter.
(symtab_resolve_alias): New function.
(fixup_same_cpp_alias_visibility): Declare.
(cgraph_function_node): Add default parameter.
(cgraph_node_asm_name): Likewise.
(cgraph_function_or_thunk_node): Add default parameter; do
not ICE when it is NULL.
(varpool_variable_node): Likewise.
* tree-emutls.c (create_emultls_var): Update.
(ipa_lower_emutls): Update.
* cgraphunit.c (cgraph_decide_is_function_needed): Update.
(cgraph_reset_node): Reset alias info.
(cgraph_finalize_function): Update.
(fixup_same_cpp_alias_visibility): Move to symtab.c.
(analyze_function): Simplify.
(cgraph_process_same_body_aliases): Simplify.
(analyze_functions): Fixup same body aliases.
(handle_alias_pairs): Simplify.
(assemble_thunk): Update.
(assemble_thunks_and_aliases): Update.
(output_weakrefs): Rewrite.
* lto-cgraph.c (lto_output_node): Rewrite alias handling.
(lto_output_varpool_node): Likewise.
(compute_ltrans_boundary): Remve assert.
(get_alias_symbol): New functoin.
(input_node): Rewrite alias handling.
(input_varpool_node): Likewise.
* ipa-pure-const.c (propagate_pure_const): Fix formating.
* ipa.c (process_references): Handle weakrefs correctly.
(symtab_remove_unreachable_nodes): Likewise.
* trans-mem.c (get_cg_data): Update.
(ipa_tm_create_version_alias): Update.
(ipa_tm_execute): Update.
* symtab.c (dump_symtab_base): Dump aliases.
(verify_symtab_base): Verify aliases.
(symtab_node_availability): New function.
(symtab_alias_ultimate_target): Simplify.
(fixup_same_cpp_alias_visibility): Move here from cgraphunit.c;
handle all the fixup cases.
(symtab_resolve_alias): New function.
* passes.c (ipa_write_summaries): Handle weakrefs.
* varpool.c (varpool_analyze_node): Simplify.
(assemble_aliases): Update.
(varpool_create_variable_alias): Simplify.
(varpool_extra_name_alias): Simplify.
* lto-streamer.h (lto_symtab_merge_cgraph_nodes): Rename to...
(lto_symtab_merge_symbols): ... this one.
* decl2.c (cp_write_global_declarations): Replace same_body_alias
by symbol.cpp_implicit_alias.
* lto.c (read_cgraph_and_symbols): Simplify dumping; Replace
lto_symtab_merge_cgraph_nodes by lto_symtab_merge_symbols.
(do_whole_program_analysis): Update dumping.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199577 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 145 |
1 files changed, 56 insertions, 89 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index ca314a68476..76ef876aa47 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -231,8 +231,7 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl) /* Double check that no one output the function into assembly file early. */ gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl) - || (node->thunk.thunk_p || node->same_body_alias) - || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))); + || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))); /* Keep constructors, destructors and virtual functions. */ @@ -370,6 +369,8 @@ cgraph_reset_node (struct cgraph_node *node) memset (&node->rtl, 0, sizeof (node->rtl)); node->symbol.analyzed = false; node->symbol.definition = false; + node->symbol.alias = false; + node->symbol.cpp_implicit_alias = false; cgraph_node_remove_callees (node); ipa_remove_all_references (&node->symbol.ref_list); @@ -426,7 +427,7 @@ cgraph_finalize_function (tree decl, bool nested) in the original implementation and it is unclear whether we want to change the behavior here. */ if ((!optimize - && !node->same_body_alias + && !node->symbol.cpp_implicit_alias && !DECL_DISREGARD_INLINE_LIMITS (decl) && !DECL_DECLARED_INLINE_P (decl) && !(DECL_CONTEXT (decl) @@ -573,22 +574,6 @@ output_asm_statements (void) 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. */ static void analyze_function (struct cgraph_node *node) @@ -597,39 +582,14 @@ analyze_function (struct cgraph_node *node) location_t saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (decl); - if (node->symbol.alias && node->thunk.alias) - { - struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); - struct cgraph_node *n; - - for (n = tgt; n && n->symbol.alias; - n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL) - if (n == node) - { - error ("function %q+D part of alias cycle", node->symbol.decl); - node->symbol.alias = false; - input_location = saved_loc; - return; - } - if (!vec_safe_length (node->symbol.ref_list.references)) - ipa_record_reference ((symtab_node)node, (symtab_node)tgt, - IPA_REF_ALIAS, NULL); - if (node->same_body_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); - } - - if (node->symbol.address_taken) - cgraph_mark_address_taken_node (cgraph_alias_target (node)); - } + if (node->symbol.alias) + symtab_resolve_alias + ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target)); else if (node->thunk.thunk_p) { cgraph_create_edge (node, cgraph_get_node (node->thunk.alias), NULL, 0, CGRAPH_FREQ_BASE); + node->thunk.alias = NULL; } else if (node->dispatcher_function) { @@ -693,16 +653,12 @@ analyze_function (struct cgraph_node *node) void cgraph_process_same_body_aliases (void) { - struct cgraph_node *node; - FOR_EACH_FUNCTION (node) - if (node->same_body_alias - && !vec_safe_length (node->symbol.ref_list.references)) - { - struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); - ipa_record_reference ((symtab_node)node, (symtab_node)tgt, - IPA_REF_ALIAS, NULL); - } - same_body_aliases_done = true; + symtab_node node; + FOR_EACH_SYMBOL (node) + if (node->symbol.cpp_implicit_alias && !node->symbol.analyzed) + symtab_resolve_alias (node, + symtab_get_node (node->symbol.alias_target)); + cpp_implicit_aliases_done = true; } /* Process attributes common for vars and functions. */ @@ -890,6 +846,13 @@ analyze_functions (void) bitmap_obstack_initialize (NULL); cgraph_state = CGRAPH_STATE_CONSTRUCTION; + /* Ugly, but the fixup can not happen at a time same body alias is created; + C++ FE is confused about the COMDAT groups being right. */ + if (cpp_implicit_aliases_done) + FOR_EACH_SYMBOL (node) + if (node->symbol.cpp_implicit_alias) + fixup_same_cpp_alias_visibility (node, symtab_alias_target (node)); + /* Analysis adds static variables that in turn adds references to new functions. So we need to iterate the process until it stabilize. */ while (changed) @@ -940,7 +903,7 @@ analyze_functions (void) and later using weak alias attribute to kill its body. See gcc.c-torture/compile/20011119-1.c */ if (!DECL_STRUCT_FUNCTION (decl) - && (!cnode->symbol.alias || !cnode->thunk.alias) + && !cnode->symbol.alias && !cnode->thunk.thunk_p && !cnode->dispatcher_function) { @@ -970,7 +933,7 @@ analyze_functions (void) else { varpool_node *vnode = dyn_cast <varpool_node> (node); - if (vnode && vnode->symbol.definition) + if (vnode && vnode->symbol.definition && !vnode->symbol.analyzed) varpool_analyze_node (vnode); } @@ -1016,7 +979,7 @@ analyze_functions (void) tree decl = node->symbol.decl; if (cnode->symbol.definition && !gimple_has_body_p (decl) - && (!cnode->symbol.alias || !cnode->thunk.alias) + && !cnode->symbol.alias && !cnode->thunk.thunk_p) cgraph_reset_node (cnode); @@ -1057,17 +1020,11 @@ handle_alias_pairs (void) to later output the weakref pseudo op into asm file. */ if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL) { - if (TREE_CODE (p->decl) == FUNCTION_DECL) - { - struct cgraph_node *anode = cgraph_get_create_node (p->decl); - anode->symbol.alias = true; - anode->thunk.alias = p->target; - } - else + symtab_node node = symtab_get_node (p->decl); + if (node) { - struct varpool_node *anode = varpool_get_node (p->decl); - anode->symbol.alias = true; - anode->alias_of = p->target; + node->symbol.alias_target = p->target; + node->symbol.alias = true; } DECL_EXTERNAL (p->decl) = 1; alias_pairs->unordered_remove (i); @@ -1380,7 +1337,7 @@ assemble_thunk (struct cgraph_node *node) HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset; HOST_WIDE_INT virtual_value = node->thunk.virtual_value; tree virtual_offset = NULL; - tree alias = node->thunk.alias; + tree alias = node->callees->callee->symbol.decl; tree thunk_fndecl = node->symbol.decl; tree a = DECL_ARGUMENTS (thunk_fndecl); @@ -1581,15 +1538,15 @@ assemble_thunks_and_aliases (struct cgraph_node *node) if (ref->use == IPA_REF_ALIAS) { struct cgraph_node *alias = ipa_ref_referring_node (ref); - bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias); + bool saved_written = TREE_ASM_WRITTEN (node->symbol.decl); /* Force assemble_alias to really output the alias this time instead of buffering it in same alias pairs. */ - TREE_ASM_WRITTEN (alias->thunk.alias) = 1; + TREE_ASM_WRITTEN (node->symbol.decl) = 1; do_assemble_alias (alias->symbol.decl, - DECL_ASSEMBLER_NAME (alias->thunk.alias)); + DECL_ASSEMBLER_NAME (node->symbol.decl)); assemble_thunks_and_aliases (alias); - TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written; + TREE_ASM_WRITTEN (node->symbol.decl) = saved_written; } } @@ -1929,22 +1886,32 @@ get_alias_symbol (tree decl) static void output_weakrefs (void) { - struct cgraph_node *node; - struct varpool_node *vnode; - FOR_EACH_FUNCTION (node) + symtab_node node; + FOR_EACH_SYMBOL (node) if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl) && !TREE_ASM_WRITTEN (node->symbol.decl) && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) - do_assemble_alias (node->symbol.decl, - node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias) - : get_alias_symbol (node->symbol.decl)); - FOR_EACH_VARIABLE (vnode) - if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl) - && !TREE_ASM_WRITTEN (vnode->symbol.decl) - && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl))) - do_assemble_alias (vnode->symbol.decl, - vnode->alias_of && DECL_P (vnode->alias_of) ? DECL_ASSEMBLER_NAME (vnode->alias_of) - : get_alias_symbol (vnode->symbol.decl)); + { + tree target; + + /* Weakrefs are special by not requiring target definition in current + compilation unit. It is thus bit hard to work out what we want to + alias. + When alias target is defined, we need to fetch it from symtab reference, + otherwise it is pointed to by alias_target. */ + if (node->symbol.alias_target) + target = (DECL_P (node->symbol.alias_target) + ? DECL_ASSEMBLER_NAME (node->symbol.alias_target) + : node->symbol.alias_target); + else if (node->symbol.analyzed) + target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl); + else + { + gcc_unreachable (); + target = get_alias_symbol (node->symbol.decl); + } + do_assemble_alias (node->symbol.decl, target); + } } /* Initialize callgraph dump file. */ |