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>
 
 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.
        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;
                      && 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;
                  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.
 /* 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.
    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)
            {
            }
          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;
 
                  || 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);
        }
              && !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
     {
     }
   else
     {
@@ -1407,7 +1410,22 @@ rtl_split_edge (edge edge_in)
       gcc_assert (redirected);
     }
   else
       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;
 }
 
   return bb;
 }
index 8a74fd1..ee0fab8 100644 (file)
@@ -1,5 +1,9 @@
 2010-05-11  Jakub Jelinek  <jakub@redhat.com>
 
 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.
        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;
+}