aboutsummaryrefslogtreecommitdiff
path: root/gcc/symtab.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-06-01 15:08:53 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-06-01 13:08:53 +0000
commit40a7fe1e382e97dda78b7cff9e05bc8e17bc9216 (patch)
tree227ede588b4d6d5d96381098725519f26a853909 /gcc/symtab.c
parent2175988161659537ed19aed873d148ed2d04ed7f (diff)
downloadgcc-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.c133
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"