From 232c9ac708e2f44320f0dfe19235493c3d0de553 Mon Sep 17 00:00:00 2001 From: hubicka Date: Tue, 11 Jan 2011 17:29:52 +0000 Subject: PR lto/45721 PR lto/45375 * tree.h (symbol_alias_set_t): Move typedef here from varasm.c (symbol_alias_set_destroy, symbol_alias_set_contains, propagate_aliases_backward): Declare. * lto-streamer-out.c (struct sets): New sturcture. (trivally_defined_alias): New function. (output_alias_pair_p): Rewrite. (output_unreferenced_globals): Fix output of alias pairs. (produce_symtab): Likewise. * ipa.c (function_and_variable_visibility): Set weak alias destination as needed in lto. * varasm.c (symbol_alias_set_t): Remove. (symbol_alias_set_destroy): Export. (propagate_aliases_forward, propagate_aliases_backward): New functions based on ... (compute_visible_aliases): ... this one; remove. (trivially_visible_alias): New (trivially_defined_alias): New. (remove_unreachable_alias_pairs): Rewrite. (finish_aliases_1): Reorganize code checking if alias is defined. * passes.c (rest_of_decl_compilation): Do not call assemble_alias when in LTO mode. * lto.c (partition_cgraph_node_p, partition_varpool_node_p): Weakrefs are not partitioned. * testsuite/gcc.dg/lto/pr45721_1.c: New file. * testsuite/gcc.dg/lto/pr45721_0.c: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168666 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/lto-streamer-out.c | 87 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 14 deletions(-) (limited to 'gcc/lto-streamer-out.c') diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 82c2f6feae5..7c0029334fd 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -2007,6 +2007,13 @@ output_function (struct cgraph_node *node) } +/* Used to pass data to trivally_defined_alias callback. */ +struct sets { + cgraph_node_set set; + varpool_node_set vset; +}; + + /* Return true if alias pair P belongs to the set of cgraph nodes in SET. If P is a an alias for a VAR_DECL, it can always be emitted. However, for FUNCTION_DECL aliases, we should only output the pair @@ -2016,16 +2023,51 @@ output_function (struct cgraph_node *node) the file processed by LTRANS. */ static bool -output_alias_pair_p (alias_pair *p, cgraph_node_set set, varpool_node_set vset) +trivally_defined_alias (tree decl ATTRIBUTE_UNUSED, + tree target, void *data) { - if (TREE_CODE (p->decl) == VAR_DECL) - return varpool_node_in_set_p (varpool_node_for_asm (p->target), vset); + struct sets *set = (struct sets *) data; + struct cgraph_node *fnode = NULL; + struct varpool_node *vnode = NULL; - /* Check if the assembler name for P->TARGET has its cgraph node in SET. */ - gcc_assert (TREE_CODE (p->decl) == FUNCTION_DECL); - return cgraph_node_in_set_p (cgraph_node_for_asm (p->target), set); + fnode = cgraph_node_for_asm (target); + if (fnode) + return cgraph_node_in_set_p (fnode, set->set); + vnode = varpool_node_for_asm (target); + return vnode && varpool_node_in_set_p (vnode, set->vset); } +/* Return true if alias pair P should be output in the current + partition contains cgrpah nodes SET and varpool nodes VSET. + DEFINED is set of all aliases whose targets are defined in + the partition. + + Normal aliases are output when they are defined, while WEAKREF + aliases are output when they are used. */ + +static bool +output_alias_pair_p (alias_pair *p, symbol_alias_set_t *defined, + cgraph_node_set set, varpool_node_set vset) +{ + struct cgraph_node *node; + struct varpool_node *vnode; + + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) + { + if (TREE_CODE (p->decl) == VAR_DECL) + { + vnode = varpool_get_node (p->decl); + return (vnode + && referenced_from_this_partition_p (&vnode->ref_list, set, vset)); + } + node = cgraph_get_node (p->decl); + return (node + && (referenced_from_this_partition_p (&node->ref_list, set, vset) + || reachable_from_this_partition_p (node, set))); + } + else + return symbol_alias_set_contains (defined, p->decl); +} /* Output any unreferenced global symbol defined in SET, alias pairs and labels. */ @@ -2037,6 +2079,11 @@ output_unreferenced_globals (cgraph_node_set set, varpool_node_set vset) alias_pair *p; unsigned i; struct varpool_node *vnode; + symbol_alias_set_t *defined; + struct sets setdata; + + setdata.set = set; + setdata.vset = vset; ob = create_output_block (LTO_section_static_initializer); ob->cgraph_node = NULL; @@ -2070,15 +2117,20 @@ output_unreferenced_globals (cgraph_node_set set, varpool_node_set vset) output_zero (ob); + /* We really need to propagate in both directoins: + for normal aliases we propagate from first defined alias to + all aliases defined based on it. For weakrefs we propagate in + the oposite direction. */ + defined = propagate_aliases_backward (trivally_defined_alias, &setdata); + /* Emit the alias pairs for the nodes in SET. */ FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) - { - if (output_alias_pair_p (p, set, vset)) - { - lto_output_tree_ref (ob, p->decl); - lto_output_tree_ref (ob, p->target); - } - } + if (output_alias_pair_p (p, defined, set, vset)) + { + lto_output_tree_ref (ob, p->decl); + lto_output_tree_ref (ob, p->target); + } + symbol_alias_set_destroy (defined); output_zero (ob); @@ -2476,6 +2528,11 @@ produce_symtab (struct output_block *ob, lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder; int i; alias_pair *p; + struct sets setdata; + symbol_alias_set_t *defined; + + setdata.set = set; + setdata.vset = vset; lto_begin_section (section_name, false); free (section_name); @@ -2553,9 +2610,11 @@ produce_symtab (struct output_block *ob, } /* Write all aliases. */ + defined = propagate_aliases_backward (trivally_defined_alias, &setdata); FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) - if (output_alias_pair_p (p, set, vset)) + if (output_alias_pair_p (p, defined, set, vset)) write_symbol (cache, &stream, p->decl, seen, true); + symbol_alias_set_destroy (defined); lto_write_stream (&stream); pointer_set_destroy (seen); -- cgit v1.2.1