re PR lto/52722 (ICE in lto_output_varpool_node)
authorJan Hubicka <jh@suse.cz>
Mon, 9 Apr 2012 23:39:11 +0000 (01:39 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 9 Apr 2012 23:39:11 +0000 (23:39 +0000)
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.

From-SVN: r186252

gcc/ChangeLog
gcc/lto-cgraph.c
gcc/lto/lto.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/pr52634_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/pr52634_1.c [new file with mode: 0644]

index a3dd551..e58e86f 100644 (file)
@@ -1,3 +1,15 @@
+2012-04-09  Jan Hubicka  <jh@suse.cz>
+
+       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.
+
 2012-04-09  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/52883
index 5e899bc..f57028d 100644 (file)
@@ -799,6 +799,8 @@ compute_ltrans_boundary (struct lto_out_decl_state *state,
          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 83b5391..26b4065 100644 (file)
@@ -1444,7 +1444,8 @@ free_ltrans_partitions (void)
   VEC_free (ltrans_partition, heap, ltrans_partitions);
 }
 
-/* See all references that go to comdat objects and bring them into partition too.  */
+/* 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)
 {
@@ -1453,15 +1454,45 @@ add_references_to_partition (ltrans_partition part, struct ipa_ref_list *refs)
   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)
+         && (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)
-           && !varpool_node_in_set_p (ipa_ref_varpool_node (ref), part->varpool_set))
+           && (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.  */
@@ -1501,9 +1532,6 @@ add_cgraph_node_to_partition (ltrans_partition part, struct cgraph_node *node)
   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))
@@ -1522,7 +1550,14 @@ add_cgraph_node_to_partition (ltrans_partition part, struct cgraph_node *node)
        && !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)
@@ -1535,8 +1570,7 @@ static void
 add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode)
 {
   varpool_node_set_iterator vsi;
-
-  vnode = varpool_variable_node (vnode, NULL);
+  struct varpool_node *v;
 
   /* If NODE is already there, we have nothing to do.  */
   vsi = varpool_node_set_find (part->varpool_set, vnode);
@@ -1554,6 +1588,14 @@ add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode
     }
   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 dd3df5b..5a0e5ef 100644 (file)
@@ -1,3 +1,11 @@
+2012-04-09  Jan Hubicka  <jh@suse.cz>
+
+       PR lto/52722
+       PR lto/51765
+       PR lto/52634    
+       * gcc.dg/lto/pr52634_1.c: New testcase.
+       * gcc.dg/lto/pr52634_0.c: New testcase.
+
 2012-04-09  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/52883
diff --git a/gcc/testsuite/gcc.dg/lto/pr52634_0.c b/gcc/testsuite/gcc.dg/lto/pr52634_0.c
new file mode 100644 (file)
index 0000000..27e075d
--- /dev/null
@@ -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); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr52634_1.c b/gcc/testsuite/gcc.dg/lto/pr52634_1.c
new file mode 100644 (file)
index 0000000..af4c439
--- /dev/null
@@ -0,0 +1,6 @@
+int cfliteKeyCallBacks = 5;
+extern int cfliteValueCallBacks __attribute__((alias("cfliteKeyCallBacks")));
+void baz(void *ptr)
+{
+  asm volatile (""::"r"(ptr));
+}