diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-11 17:29:52 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-11 17:29:52 +0000 |
commit | 232c9ac708e2f44320f0dfe19235493c3d0de553 (patch) | |
tree | 8a0441a53aaf0333716ca7449a404e95b3435f3e /gcc/lto-streamer-out.c | |
parent | 25fe7e3d8b1d614dc09ee33436ada6dcd4047282 (diff) | |
download | gcc-232c9ac708e2f44320f0dfe19235493c3d0de553.tar.gz |
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
Diffstat (limited to 'gcc/lto-streamer-out.c')
-rw-r--r-- | gcc/lto-streamer-out.c | 87 |
1 files changed, 73 insertions, 14 deletions
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); |