Fix partitioning of aliases
Richard Guenther
rguenther@suse.de
Tue Apr 10 10:52:00 GMT 2012
On Mon, 9 Apr 2012, Jan Hubicka wrote:
> Hi,
> this patch fixes several different ICEs related to handling aliases in WHOPR
> partitioning. It took me over week debug this, but when variable alias
> is added to a boundary and its destination is not added, we get queue of
> unforutnate events where the destinatoin gets analyzed and added at ltrans time
> resulting in interesting miscompilation seen at Mozilla with some vtables.
> The problem is that constructor won't get streamed when the declaration is
> not in varpool at partitioning time and thus once the variable is re-added
> it has zero constructor.
> Of course the problem manifests itself in various weird ways depending
> on ordering of linker command maing it very difficult to reduce anything.
>
> While working on this I also noticed that PR 52634 is about related problem
> where aliases are incorectly partitioned into multiple partitions.
> The patch also fixes the varpool ICEs mentioned in the other two PRs.
> I failed to produce testcase version of PR52722 testcase, since it does not
> link now either, but it won't ICE.
>
> I will commit the patch and wait for some time, but I would like to backport
> it to 4.7, since it solves quite nasty misoptimization problem.
Yeah, it looks fine to me.
> At mainline after this patch i would like to follow with series of cleanups
> and API changes I have in queue for symtab work.
Thanks,
Richard.
> Honza
>
> PR lto/52722
> PR lto/51765
> PR lto/52634
> * lto-cgraph.c (compute_ltrans_boundary): When alias is in the boundary,
> add its target too.
> * lto.c (add_references_to_partition): Add also aliased nodes.
> (add_cgraph_node_to_partition,
> add_varpool_node_to_partition): Work on nodes, not functions/variables;
> when adding alias, add also the aliased object.
> * gcc.dg/lto/pr52634_1.c: New testcase.
> * gcc.dg/lto/pr52634_0.c: New testcase.
> Index: lto-cgraph.c
> ===================================================================
> *** lto-cgraph.c (revision 185767)
> --- lto-cgraph.c (working copy)
> *************** compute_ltrans_boundary (struct lto_out_
> *** 799,804 ****
> --- 799,806 ----
> lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode);
> add_references (encoder, varpool_encoder, &vnode->ref_list);
> }
> + else if (vnode->alias || vnode->alias_of)
> + add_references (encoder, varpool_encoder, &vnode->ref_list);
> }
>
> /* Go over all the nodes again to include callees that are not in
> Index: lto/lto.c
> ===================================================================
> *** lto/lto.c (revision 185767)
> --- lto/lto.c (working copy)
> *************** free_ltrans_partitions (void)
> *** 1444,1450 ****
> VEC_free (ltrans_partition, heap, ltrans_partitions);
> }
>
> ! /* See all references that go to comdat objects and bring them into partition too. */
> static void
> add_references_to_partition (ltrans_partition part, struct ipa_ref_list *refs)
> {
> --- 1444,1451 ----
> VEC_free (ltrans_partition, heap, ltrans_partitions);
> }
>
> ! /* See all references that go to comdat objects and bring them into partition too.
> ! Also see all aliases of the newly added entry and bring them, too. */
> static void
> add_references_to_partition (ltrans_partition part, struct ipa_ref_list *refs)
> {
> *************** add_references_to_partition (ltrans_part
> *** 1453,1467 ****
> for (i = 0; ipa_ref_list_reference_iterate (refs, i, ref); i++)
> {
> if (ref->refered_type == IPA_REF_CGRAPH
> ! && DECL_COMDAT (cgraph_function_node (ipa_ref_node (ref), NULL)->decl)
> && !cgraph_node_in_set_p (ipa_ref_node (ref), part->cgraph_set))
> add_cgraph_node_to_partition (part, ipa_ref_node (ref));
> else
> if (ref->refered_type == IPA_REF_VARPOOL
> ! && DECL_COMDAT (ipa_ref_varpool_node (ref)->decl)
> ! && !varpool_node_in_set_p (ipa_ref_varpool_node (ref), part->varpool_set))
> add_varpool_node_to_partition (part, ipa_ref_varpool_node (ref));
> }
> }
>
> /* Worker for add_cgraph_node_to_partition. */
> --- 1454,1498 ----
> for (i = 0; ipa_ref_list_reference_iterate (refs, i, ref); i++)
> {
> if (ref->refered_type == IPA_REF_CGRAPH
> ! && (DECL_COMDAT (cgraph_function_node (ipa_ref_node (ref),
> ! NULL)->decl)
> ! || (ref->use == IPA_REF_ALIAS
> ! && lookup_attribute
> ! ("weakref", DECL_ATTRIBUTES (ipa_ref_node (ref)->decl))))
> && !cgraph_node_in_set_p (ipa_ref_node (ref), part->cgraph_set))
> add_cgraph_node_to_partition (part, ipa_ref_node (ref));
> else
> if (ref->refered_type == IPA_REF_VARPOOL
> ! && (DECL_COMDAT (ipa_ref_varpool_node (ref)->decl)
> ! || (ref->use == IPA_REF_ALIAS
> ! && lookup_attribute
> ! ("weakref",
> ! DECL_ATTRIBUTES (ipa_ref_varpool_node (ref)->decl))))
> ! && !varpool_node_in_set_p (ipa_ref_varpool_node (ref),
> ! part->varpool_set))
> add_varpool_node_to_partition (part, ipa_ref_varpool_node (ref));
> }
> + for (i = 0; ipa_ref_list_refering_iterate (refs, i, ref); i++)
> + {
> + if (ref->refering_type == IPA_REF_CGRAPH
> + && ref->use == IPA_REF_ALIAS
> + && !cgraph_node_in_set_p (ipa_ref_refering_node (ref),
> + part->cgraph_set)
> + && !lookup_attribute ("weakref",
> + DECL_ATTRIBUTES
> + (ipa_ref_refering_node (ref)->decl)))
> + add_cgraph_node_to_partition (part, ipa_ref_refering_node (ref));
> + else
> + if (ref->refering_type == IPA_REF_VARPOOL
> + && ref->use == IPA_REF_ALIAS
> + && !varpool_node_in_set_p (ipa_ref_refering_varpool_node (ref),
> + part->varpool_set)
> + && !lookup_attribute ("weakref",
> + DECL_ATTRIBUTES
> + (ipa_ref_refering_varpool_node (ref)->decl)))
> + add_varpool_node_to_partition (part,
> + ipa_ref_refering_varpool_node (ref));
> + }
> }
>
> /* Worker for add_cgraph_node_to_partition. */
> *************** add_cgraph_node_to_partition (ltrans_par
> *** 1501,1509 ****
> cgraph_node_set_iterator csi;
> struct cgraph_node *n;
>
> - /* We always decide on functions, not associated thunks and aliases. */
> - node = cgraph_function_node (node, NULL);
> -
> /* If NODE is already there, we have nothing to do. */
> csi = cgraph_node_set_find (part->cgraph_set, node);
> if (!csi_end_p (csi))
> --- 1532,1537 ----
> *************** add_cgraph_node_to_partition (ltrans_par
> *** 1522,1528 ****
> --- 1550,1563 ----
> && !cgraph_node_in_set_p (e->callee, part->cgraph_set))
> add_cgraph_node_to_partition (part, e->callee);
>
> + /* The only way to assemble non-weakref alias is to add the aliased object into
> + the unit. */
> add_references_to_partition (part, &node->ref_list);
> + n = cgraph_function_node (node, NULL);
> + if (n != node
> + && !lookup_attribute ("weakref",
> + DECL_ATTRIBUTES (node->decl)))
> + add_cgraph_node_to_partition (part, n);
>
> if (node->same_comdat_group)
> for (n = node->same_comdat_group; n != node; n = n->same_comdat_group)
> *************** static void
> *** 1535,1542 ****
> add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode)
> {
> varpool_node_set_iterator vsi;
> !
> ! vnode = varpool_variable_node (vnode, NULL);
>
> /* If NODE is already there, we have nothing to do. */
> vsi = varpool_node_set_find (part->varpool_set, vnode);
> --- 1570,1576 ----
> add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode)
> {
> varpool_node_set_iterator vsi;
> ! struct varpool_node *v;
>
> /* If NODE is already there, we have nothing to do. */
> vsi = varpool_node_set_find (part->varpool_set, vnode);
> *************** add_varpool_node_to_partition (ltrans_pa
> *** 1554,1559 ****
> --- 1588,1601 ----
> }
> vnode->aux = (void *)((size_t)vnode->aux + 1);
>
> + /* The only way to assemble non-weakref alias is to add the aliased object into
> + the unit. */
> + v = varpool_variable_node (vnode, NULL);
> + if (v != vnode
> + && !lookup_attribute ("weakref",
> + DECL_ATTRIBUTES (vnode->decl)))
> + add_varpool_node_to_partition (part, v);
> +
> add_references_to_partition (part, &vnode->ref_list);
>
> if (vnode->same_comdat_group
> Index: testsuite/gcc.dg/lto/pr52634_1.c
> ===================================================================
> --- testsuite/gcc.dg/lto/pr52634_1.c (revision 0)
> +++ testsuite/gcc.dg/lto/pr52634_1.c (revision 0)
> @@ -0,0 +1,2 @@
> +int cfliteKeyCallBacks = 5;
> +extern int cfliteValueCallBacks __attribute__((alias("cfliteKeyCallBacks")));
> Index: testsuite/gcc.dg/lto/pr52634_0.c
> ===================================================================
> --- testsuite/gcc.dg/lto/pr52634_0.c (revision 0)
> +++ testsuite/gcc.dg/lto/pr52634_0.c (revision 0)
> @@ -0,0 +1,5 @@
> +/* { dg-lto-do link } */
> +/* { dg-lto-options {{-flto -r -nostdlib -flto-partition=1to1}} */
> +extern int cfliteValueCallBacks;
> +void baz (int *);
> +int main () { baz(&cfliteValueCallBacks); }
>
>
--
Richard Guenther <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer
More information about the Gcc-patches
mailing list