re PR middle-end/63186 (Undefined .L* symbols because of fnsplit)
authorJan Hubicka <hubicka@ucw.cz>
Thu, 11 Sep 2014 06:46:23 +0000 (08:46 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 11 Sep 2014 06:46:23 +0000 (06:46 +0000)
PR tree-optimization/63186
* ipa-split.c (test_nonssa_use): Skip nonforced labels.
(mark_nonssa_use): Likewise.
(verify_non_ssa_vars): Verify all header blocks for label
definitions.

* gcc.dg/pr63186.c: New testcase.

From-SVN: r215149

gcc/ChangeLog
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr63186.c [new file with mode: 0644]

index a6b52583bae7f8809fb6b9a6e39e5ca2230a89f5..242704859b927a807fa0ff3880dd390cc40c9e74 100644 (file)
@@ -1,3 +1,11 @@
+2014-09-10  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR tree-optimization/63186
+       * ipa-split.c (test_nonssa_use): Skip nonforced labels.
+       (mark_nonssa_use): Likewise.
+       (verify_non_ssa_vars): Verify all header blocks for label
+       definitions.
+
 2014-09-11  Alexander Ivchenko  <alexander.ivchenko@intel.com>
            Maxim Kuznetsov  <maxim.kuznetsov@intel.com>
            Anna Tikhonova  <anna.tikhonova@intel.com>
index 3762d6a46f7f52ea39cb9bf4f188c3c7f7cdca86..fde436538f53897dd6555d54999a8269ad8f244c 100644 (file)
@@ -167,7 +167,11 @@ test_nonssa_use (gimple, tree t, tree, void *data)
       || (TREE_CODE (t) == VAR_DECL
          && auto_var_in_fn_p (t, current_function_decl))
       || TREE_CODE (t) == RESULT_DECL
-      || TREE_CODE (t) == LABEL_DECL)
+        /* Normal labels are part of CFG and will be handled gratefuly.
+           Forced labels however can be used directly by statements and
+           need to stay in one partition along with their uses.  */
+      || (TREE_CODE (t) == LABEL_DECL
+         && FORCED_LABEL (t)))
     return bitmap_bit_p ((bitmap)data, DECL_UID (t));
 
   /* For DECL_BY_REFERENCE, the return value is actually a pointer.  We want
@@ -213,6 +217,7 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
   edge e;
   edge_iterator ei;
   bool ok = true;
+  basic_block bb;
 
   FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
     if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
@@ -225,8 +230,8 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
   while (!worklist.is_empty ())
     {
       gimple_stmt_iterator bsi;
-      basic_block bb = worklist.pop ();
 
+      bb = worklist.pop ();
       FOR_EACH_EDGE (e, ei, bb->preds)
        if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
            && bitmap_set_bit (seen, e->src->index))
@@ -250,10 +255,10 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
          if (gimple_code (stmt) == GIMPLE_LABEL
              && test_nonssa_use (stmt, gimple_label_label (stmt),
                                  NULL_TREE, non_ssa_vars))
-         {
-           ok = false;
-           goto done;
-         }
+           {
+             ok = false;
+             goto done;
+           }
        }
       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
        {
@@ -286,6 +291,27 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
            }
        }
     }
+
+  /* Verify that the rest of function does not define any label
+     used by the split part.  */
+  FOR_EACH_BB_FN (bb, cfun)
+    if (!bitmap_bit_p (current->split_bbs, bb->index)
+       && !bitmap_bit_p (seen, bb->index))
+      {
+        gimple_stmt_iterator bsi;
+        for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+         if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL
+             && test_nonssa_use (gsi_stmt (bsi),
+                                 gimple_label_label (gsi_stmt (bsi)),
+                                 NULL_TREE, non_ssa_vars))
+           {
+             ok = false;
+             goto done;
+           }
+         else if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL)
+           break;
+      }
+    
 done:
   BITMAP_FREE (seen);
   worklist.release ();
@@ -735,7 +761,8 @@ mark_nonssa_use (gimple, tree t, tree, void *data)
   if ((TREE_CODE (t) == VAR_DECL
        && auto_var_in_fn_p (t, current_function_decl))
       || TREE_CODE (t) == RESULT_DECL
-      || TREE_CODE (t) == LABEL_DECL)
+      || (TREE_CODE (t) == LABEL_DECL
+         && FORCED_LABEL (t)))
     bitmap_set_bit ((bitmap)data, DECL_UID (t));
 
   /* For DECL_BY_REFERENCE, the return value is actually a pointer.  We want
index 197297a75438cd6f010f43fd94fbf19a58d3f99c..1432e77f73f0bc70f3435424b6c0681a1deb4fb9 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-10  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR tree-optimization/63186
+       * gcc.dg/pr63186.c: New testcase.
+
 2014-09-10  Xinliang David Li  <davidxl@google.com>
 
        PR target/63209
diff --git a/gcc/testsuite/gcc.dg/pr63186.c b/gcc/testsuite/gcc.dg/pr63186.c
new file mode 100644 (file)
index 0000000..b364875
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+void *a;
+int b, c, d;
+
+void
+bar ()
+{
+  switch (c)
+    {
+    case 0:
+    lab:
+      __asm__ ("");
+      return;
+    default:
+      break;
+    }
+  b = 0;
+  d = 0;
+  a = &&lab;
+}
+
+void
+foo ()
+{
+  bar ();
+}
+main()
+{
+}