diff options
author | Jan Hubicka <jh@suse.cz> | 2013-06-01 15:08:53 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-06-01 13:08:53 +0000 |
commit | 40a7fe1e382e97dda78b7cff9e05bc8e17bc9216 (patch) | |
tree | 227ede588b4d6d5d96381098725519f26a853909 /gcc/symtab.c | |
parent | 2175988161659537ed19aed873d148ed2d04ed7f (diff) | |
download | gcc-40a7fe1e382e97dda78b7cff9e05bc8e17bc9216.zip gcc-40a7fe1e382e97dda78b7cff9e05bc8e17bc9216.tar.gz gcc-40a7fe1e382e97dda78b7cff9e05bc8e17bc9216.tar.bz2 |
lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Rename to ...
* 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.
From-SVN: r199577
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r-- | gcc/symtab.c | 133 |
1 files changed, 122 insertions, 11 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c index 1a7f826..af8e70b 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -481,6 +481,14 @@ dump_symtab_base (FILE *f, symtab_node node) fprintf (f, " analyzed"); if (node->symbol.alias) fprintf (f, " alias"); + if (node->symbol.cpp_implicit_alias) + fprintf (f, " cpp_implicit_alias"); + if (node->symbol.alias_target) + fprintf (f, " target:%s", + DECL_P (node->symbol.alias_target) + ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME + (node->symbol.alias_target)) + : IDENTIFIER_POINTER (node->symbol.alias_target)); fprintf (f, "\n Visibility:"); if (node->symbol.in_other_partition) fprintf (f, " in_other_partition"); @@ -666,6 +674,17 @@ verify_symtab_base (symtab_node node) error ("node is analyzed byt it is not a definition"); error_found = true; } + if (node->symbol.cpp_implicit_alias && !node->symbol.alias) + { + error ("node is alias but not implicit alias"); + error_found = true; + } + if (node->symbol.alias && !node->symbol.definition + && !lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) + { + error ("node is alias but not definition"); + error_found = true; + } if (node->symbol.same_comdat_group) { symtab_node n = node->symbol.same_comdat_group; @@ -757,6 +776,7 @@ symtab_used_from_object_file_p (symtab_node node) /* 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) { @@ -796,6 +816,17 @@ symtab_make_decl_local (tree decl) SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl); } +/* Return availability of NODE. */ + +enum availability +symtab_node_availability (symtab_node node) +{ + if (is_a <cgraph_node> (node)) + return cgraph_function_body_availability (cgraph (node)); + else + return cgraph_variable_initializer_availability (varpool (node)); +} + /* Given NODE, walk the alias chain to return the symbol NODE is alias of. If NODE is not an alias, return NODE. When AVAILABILITY is non-NULL, get minimal availability in the chain. */ @@ -804,12 +835,7 @@ symtab_node symtab_alias_ultimate_target (symtab_node node, enum availability *availability) { if (availability) - { - if (is_a <cgraph_node> (node)) - *availability = cgraph_function_body_availability (cgraph (node)); - else - *availability = cgraph_variable_initializer_availability (varpool (node)); - } + *availability = symtab_node_availability (node); while (node) { if (node->symbol.alias && node->symbol.analyzed) @@ -818,11 +844,7 @@ symtab_alias_ultimate_target (symtab_node node, enum availability *availability) return node; if (node && availability) { - enum availability a; - if (is_a <cgraph_node> (node)) - a = cgraph_function_body_availability (cgraph (node)); - else - a = cgraph_variable_initializer_availability (varpool (node)); + enum availability a = symtab_node_availability (node); if (a < *availability) *availability = a; } @@ -831,4 +853,93 @@ symtab_alias_ultimate_target (symtab_node node, enum availability *availability) *availability = AVAIL_NOT_AVAILABLE; return NULL; } + +/* C++ FE sometimes change linkage flags after producing same body aliases. + + FIXME: C++ produce implicit aliases for virtual functions and vtables that + are obviously equivalent. The way it is doing so is however somewhat + kludgy and interferes with the visibility code. As a result we need to + copy the visibility from the target to get things right. */ + +void +fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target) +{ + if (is_a <cgraph_node> (node)) + { + DECL_DECLARED_INLINE_P (node->symbol.decl) + = DECL_DECLARED_INLINE_P (target->symbol.decl); + DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl) + = DECL_DISREGARD_INLINE_LIMITS (target->symbol.decl); + } + /* FIXME: It is not really clear why those flags should not be copied for + functions, too. */ + else + { + DECL_WEAK (node->symbol.decl) = DECL_WEAK (target->symbol.decl); + DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl); + DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (target->symbol.decl); + } + DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (target->symbol.decl); + if (TREE_PUBLIC (node->symbol.decl)) + { + DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl); + DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (target->symbol.decl); + DECL_COMDAT_GROUP (node->symbol.decl) + = DECL_COMDAT_GROUP (target->symbol.decl); + if (DECL_ONE_ONLY (target->symbol.decl) + && !node->symbol.same_comdat_group) + symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target); + } + node->symbol.externally_visible = target->symbol.externally_visible; +} + +/* Add reference recording that NODE is alias of TARGET. + The function can fail in the case of aliasing cycles; in this case + it returns false. */ + +bool +symtab_resolve_alias (symtab_node node, symtab_node target) +{ + symtab_node n; + + gcc_assert (!node->symbol.analyzed + && !vec_safe_length (node->symbol.ref_list.references)); + + /* Never let cycles to creep into the symbol table alias references; + those will make alias walkers to be infinite. */ + for (n = target; n && n->symbol.alias; + n = n->symbol.analyzed ? symtab_alias_target (n) : NULL) + if (n == node) + { + if (is_a <cgraph_node> (node)) + error ("function %q+D part of alias cycle", node->symbol.decl); + else if (is_a <varpool_node> (node)) + error ("variable %q+D part of alias cycle", node->symbol.decl); + else + gcc_unreachable (); + node->symbol.alias = false; + return false; + } + + /* "analyze" the node - i.e. mark the reference. */ + node->symbol.definition = true; + node->symbol.alias = true; + node->symbol.analyzed = true; + ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); + + /* Alias targets become reudndant after alias is resolved into an reference. + We do not want to keep it around or we would have to mind updating them + when renaming symbols. */ + node->symbol.alias_target = NULL; + DECL_ATTRIBUTES (node->symbol.decl) + = remove_attribute ("alias", DECL_ATTRIBUTES (node->symbol.decl)); + + if (node->symbol.cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION) + fixup_same_cpp_alias_visibility (node, target); + + /* If alias has address taken, so does the target. */ + if (node->symbol.address_taken) + symtab_alias_ultimate_target (target, NULL)->symbol.address_taken = true; + return true; +} #include "gt-symtab.h" |