OSDN Git Service

2008-03-05 Gabor Loki <loki@gcc.gnu.org>
authorloki <loki@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Mar 2008 10:15:45 +0000 (10:15 +0000)
committerloki <loki@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Mar 2008 10:15:45 +0000 (10:15 +0000)
PR gcc/33009
* rtl-factoring.c (clear_regs_live_in_seq): Fix backward steps.
(split_block_and_df_analyze): New. Split basic block and rebuild
dataflow.
(block_label_after): Use SPLIT_BLOCK_AND_DF_ANALYZE instead of
SPLIT_BLOCK.
(split_pattern_seq): Likewise.
(erase_matching_seqs): Likewise.
(split_pattern_seq): Skip return insn in case of REG_NORETURN note.

PR testsuite/33009
* gcc.c-torture/compile/pr11832.c: Check -frtl-abstract-sequences.
* gcc.c-torture/compile/pr33009.c: Likewise.

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

gcc/ChangeLog
gcc/rtl-factoring.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr11832.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr33009.c [new file with mode: 0644]

index dc55d3b..22e5ce0 100644 (file)
@@ -1,3 +1,15 @@
+2008-03-05  Gabor Loki  <loki@gcc.gnu.org>
+
+       PR gcc/33009
+       * rtl-factoring.c (clear_regs_live_in_seq): Fix backward steps.
+       (split_block_and_df_analyze): New. Split basic block and rebuild
+       dataflow.
+       (block_label_after): Use SPLIT_BLOCK_AND_DF_ANALYZE instead of
+       SPLIT_BLOCK.
+       (split_pattern_seq): Likewise.
+       (erase_matching_seqs): Likewise.
+       (split_pattern_seq): Skip return insn in case of REG_NORETURN note.
+
 2008-03-04  Geoff Keating  <geoffk@apple.com>
 
        * fold-const.c (tree_single_nonnegative_warnv_p): Fix mixed
index cf07db9..20e9cf2 100644 (file)
@@ -1,5 +1,5 @@
 /* RTL factoring (sequence abstraction).
-   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -551,8 +551,8 @@ clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
   df_simulate_artificial_refs_at_end (bb, &live);
 
   /* Propagate until INSN if found.  */
-  for (x = BB_END (bb); x != insn;)
-    df_simulate_one_insn_backwards (bb, insn, &live);
+  for (x = BB_END (bb); x != insn; x = PREV_INSN (x))
+    df_simulate_one_insn_backwards (bb, x, &live);
 
   /* Clear registers live after INSN.  */
   renumbered_reg_set_to_hard_reg_set (&hlive, &live);
@@ -562,7 +562,7 @@ clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
   for (i = 0; i < length;)
     {
       rtx prev = PREV_INSN (x);
-      df_simulate_one_insn_backwards (bb, insn, &live);
+      df_simulate_one_insn_backwards (bb, x, &live);
 
       if (INSN_P (x))
         {
@@ -949,6 +949,17 @@ gen_symbol_ref_rtx_for_label (const_rtx label)
   return sym;
 }
 
+/* Splits basic block at the requested insn and rebuilds dataflow.  */
+
+static basic_block
+split_block_and_df_analyze (basic_block bb, rtx insn)
+{
+  basic_block next;
+  next = split_block (bb, insn)->dest;
+  df_analyze ();
+  return next;
+}
+
 /* Ensures that INSN is the last insn in its block and returns the block label
    of the next block.  */
 
@@ -959,7 +970,7 @@ block_label_after (rtx insn)
   if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
     return block_label (bb->next_bb);
   else
-    return block_label (split_block (bb, insn)->dest);
+    return block_label (split_block_and_df_analyze (bb, insn));
 }
 
 /* Ensures that the last insns of the best pattern and its matching sequences
@@ -1008,8 +1019,9 @@ split_pattern_seq (void)
 
   /* Emit an indirect jump via the link register after the sequence acting
      as the return insn.  Also emit a barrier and update the basic block.  */
-  retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
-                                 BB_END (bb));
+  if (!find_reg_note (BB_END (bb), REG_NORETURN, NULL))
+    retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
+                                   BB_END (bb));
   emit_barrier_after (BB_END (bb));
 
   /* Replace all outgoing edges with a new one to the block of RETLABEL.  */
@@ -1025,7 +1037,7 @@ split_pattern_seq (void)
       for (; i < sb->length; i++)
         insn = prev_insn_in_block (insn);
 
-      sb->label = block_label (split_block (bb, insn)->dest);
+      sb->label = block_label (split_block_and_df_analyze (bb, insn));
     }
 
   /* Emit an insn saving the return address to the link register before the
@@ -1067,7 +1079,7 @@ erase_matching_seqs (void)
           /* Delete the insns of the sequence.  */
           for (i = 0; i < sb->length; i++)
             insn = prev_insn_in_block (insn);
-          delete_basic_block (split_block (bb, insn)->dest);
+          delete_basic_block (split_block_and_df_analyze (bb, insn));
 
           /* Emit an insn saving the return address to the link register
              before the deleted sequence.  */
index 4be88d7..8341b28 100644 (file)
@@ -1,3 +1,9 @@
+2007-03-05  Gabor Loki  <loki@gcc.gnu.org>
+
+       PR 33009
+       * gcc.c-torture/compile/pr11832.c: Check -frtl-abstract-sequences.
+       * gcc.c-torture/compile/pr33009.c: Likewise.
+
 2008-03-05  Victor Kaplansky  <victork@gcc.gnu.org>
 
        PR 31341
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr11832.c b/gcc/testsuite/gcc.c-torture/compile/pr11832.c
new file mode 100644 (file)
index 0000000..a4c3eec
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-frtl-abstract-sequences" } */
+
+int a, b, e;
+unsigned char *c;
+void foo()
+{
+  int d = 13;
+  b = -1;   
+  switch (e) {
+    case 1:
+      b++; c[b] = (unsigned char)d;
+      break;
+    case 2:
+      b++; c[b] = (unsigned char)d;
+      b++; c[b] = (unsigned char)d;
+      break;
+    case 3:
+      b++; c[b] = (unsigned char)d;
+      b++; c[b] = (unsigned char)d;
+      b++; c[b] = (unsigned char)d;
+      break;
+    default:
+      a = 1;
+      b++; c[b] = (unsigned char)d;
+      b++; c[b] = (unsigned char)d;
+      b++; c[b] = (unsigned char)d;
+      b++; c[b] = (unsigned char)d;
+  }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33009.c b/gcc/testsuite/gcc.c-torture/compile/pr33009.c
new file mode 100644 (file)
index 0000000..781e1fe
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-frtl-abstract-sequences" } */
+
+char *progName;
+int bar0 (char *, ...);
+void bar1 (char *);
+void exit (int);
+
+
+#define SAME \
+ bar0 ("%s: Bad flag `%s'\n", argv[i], argv[i] );\
+ bar1 ( progName ); \
+ exit ( 1 );
+
+
+int foo ( int argc, char *argv[] )
+{
+    int i;
+    for (i = 0; i < argc; i++) {
+       switch (argv[i][0]) {
+       case 'c':
+           break;
+       default: 
+       
+           SAME
+           
+           break;
+       }
+    }
+    for (i = 0; i < argc; i++) {
+    
+       SAME
+       
+    }
+    return 0;
+}