OSDN Git Service

PR middle-end/44071
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 May 2010 18:17:43 +0000 (18:17 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 May 2010 18:17:43 +0000 (18:17 +0000)
* cfglayout.c (fixup_reorder_chain): Allow asm goto to have
no fallthru edge.
* cfgcleanup.c (try_optimize_cfg): When in cfglayout mode
optimizing away empty bb with no successors, move over its
footer chain to fallthru predecessor.
* cfgrtl.c (patch_jump_insn): Update also REG_LABEL_OPERAND.
(rtl_split_edge): For asm goto call patch_jump_insn even if
splitting fallthru edge.

* c-c++-common/asmgoto-4.c: New test.
* gcc.target/i386/pr44071.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159288 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/cfglayout.c
gcc/cfgrtl.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asmgoto-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr44071.c [new file with mode: 0644]

index 16f56b8..24f210b 100644 (file)
@@ -1,5 +1,15 @@
 2010-05-11  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/44071
+       * cfglayout.c (fixup_reorder_chain): Allow asm goto to have
+       no fallthru edge.
+       * cfgcleanup.c (try_optimize_cfg): When in cfglayout mode
+       optimizing away empty bb with no successors, move over its
+       footer chain to fallthru predecessor.
+       * cfgrtl.c (patch_jump_insn): Update also REG_LABEL_OPERAND.
+       (rtl_split_edge): For asm goto call patch_jump_insn even if
+       splitting fallthru edge.
+
        PR c++/44059
        * config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use qnu_unique_object
        even for DECL_ONE_ONLY DECL_ARTIFICIAL !TREE_READONLY decls.
index dc6c245..75f5651 100644 (file)
@@ -1999,6 +1999,25 @@ try_optimize_cfg (int mode)
                      && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
                {
                  c = b->prev_bb;
+                 if ((mode & CLEANUP_CFGLAYOUT)
+                     && EDGE_COUNT (b->preds) > 0
+                     && b->il.rtl->footer
+                     && BARRIER_P (b->il.rtl->footer))
+                   {
+                     edge e;
+                     edge_iterator ei;
+
+                     FOR_EACH_EDGE (e, ei, b->preds)
+                       if (e->flags & EDGE_FALLTHRU)
+                         {
+                           if (e->src->il.rtl->footer == NULL)
+                             {
+                               e->src->il.rtl->footer = b->il.rtl->footer;
+                               b->il.rtl->footer = NULL;
+                             }
+                           break;
+                         }
+                   }
                  delete_basic_block (b);
                  if (!(mode & CLEANUP_CFGLAYOUT))
                    changed = true;
index 9d23b16..7ba289f 100644 (file)
@@ -1,5 +1,5 @@
 /* Basic block reordering routines for the GNU compiler.
-   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -861,8 +861,11 @@ fixup_reorder_chain (void)
            }
          else if (extract_asm_operands (PATTERN (bb_end_insn)) != NULL)
            {
-             /* If the old fallthru is still next, nothing to do.  */
-             if (bb->aux == e_fall->dest
+             /* If the old fallthru is still next or if
+                asm goto doesn't have a fallthru (e.g. when followed by
+                __builtin_unreachable ()), nothing to do.  */
+             if (! e_fall
+                 || bb->aux == e_fall->dest
                  || e_fall->dest == EXIT_BLOCK_PTR)
                continue;
 
index 7fb1873..abdbf9d 100644 (file)
@@ -994,6 +994,9 @@ patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
              && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
            add_reg_note (insn, REG_LABEL_TARGET, new_label);
        }
+      while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
+            != NULL_RTX)
+       XEXP (note, 0) = new_label;
     }
   else
     {
@@ -1407,7 +1410,22 @@ rtl_split_edge (edge edge_in)
       gcc_assert (redirected);
     }
   else
-    redirect_edge_succ (edge_in, bb);
+    {
+      if (edge_in->src != ENTRY_BLOCK_PTR)
+       {
+         /* For asm goto even splitting of fallthru edge might
+            need insn patching, as other labels might point to the
+            old label.  */
+         rtx last = BB_END (edge_in->src);
+         if (last
+             && JUMP_P (last)
+             && edge_in->dest != EXIT_BLOCK_PTR
+             && extract_asm_operands (PATTERN (last)) != NULL_RTX
+             && patch_jump_insn (last, before, bb))
+           df_set_bb_dirty (edge_in->src);
+       }
+      redirect_edge_succ (edge_in, bb);
+    }
 
   return bb;
 }
index 8a74fd1..ee0fab8 100644 (file)
@@ -1,5 +1,9 @@
 2010-05-11  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/44071
+       * c-c++-common/asmgoto-4.c: New test.
+       * gcc.target/i386/pr44071.c: New test.
+
        PR c++/44062
        * c-c++-common/Wunused-var-7.c: New test.
        * g++.dg/warn/Wunused-var-9.C: New test.
diff --git a/gcc/testsuite/c-c++-common/asmgoto-4.c b/gcc/testsuite/c-c++-common/asmgoto-4.c
new file mode 100644 (file)
index 0000000..4532bf1
--- /dev/null
@@ -0,0 +1,44 @@
+/* PR middle-end/44071 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+static inline int
+f1 (void)
+{
+  asm goto ("" : : : : l1, l2);
+  __builtin_unreachable ();
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+int
+b1 (int x)
+{
+  if (f1 () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}
+
+static inline int
+f2 (void)
+{
+  asm goto ("" : : : : l1, l2);
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+int
+b2 (int x)
+{
+  if (f2 () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr44071.c b/gcc/testsuite/gcc.target/i386/pr44071.c
new file mode 100644 (file)
index 0000000..514c5e2
--- /dev/null
@@ -0,0 +1,103 @@
+/* PR middle-end/44071 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+static inline int
+f1 (void)
+{
+  asm goto ("jmp %l[l1]" : : : : l1, l2);
+  __builtin_unreachable ();
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+__attribute__((noinline)) int
+b1 (int x)
+{
+  if (f1 () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}
+
+static inline int
+f2 (void)
+{
+  asm goto ("jmp %l[l2]" : : : : l1, l2);
+  __builtin_unreachable ();
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+__attribute__((noinline)) int
+b2 (int x)
+{
+  if (f2 () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}
+
+static inline int
+f3 (void)
+{
+  asm goto ("jmp %l[l1]" : : : : l1, l2);
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+__attribute__((noinline)) int
+b3 (int x)
+{
+  if (f3 () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}
+
+static inline int
+f4 (void)
+{
+  asm goto ("jmp %l[l2]" : : : : l1, l2);
+ l1:
+  return 1;
+ l2:
+  return 0;
+}
+
+__attribute__((noinline)) int
+b4 (int x)
+{
+  if (f4 () || x == 6)
+    x = 1;
+  else
+    x = 2;
+  return x;
+}
+
+extern void abort (void);
+
+int
+main (void)
+{
+  int x;
+  asm ("" : "=r" (x) : "0" (0));
+  if (b1 (x) != 1 || b1 (x + 6) != 1)
+    abort ();
+  if (b2 (x) != 2 || b2 (x + 6) != 1)
+    abort ();
+  if (b3 (x) != 1 || b3 (x + 6) != 1)
+    abort ();
+  if (b4 (x) != 2 || b4 (x + 6) != 1)
+    abort ();
+  return 0;
+}