summaryrefslogtreecommitdiff
path: root/gcc/lto-streamer-out.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-11 17:29:52 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-11 17:29:52 +0000
commit232c9ac708e2f44320f0dfe19235493c3d0de553 (patch)
tree8a0441a53aaf0333716ca7449a404e95b3435f3e /gcc/lto-streamer-out.c
parent25fe7e3d8b1d614dc09ee33436ada6dcd4047282 (diff)
downloadgcc-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.c87
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);