aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGabor Loki <loki@gcc.gnu.org>2008-03-05 10:15:45 +0000
committerGabor Loki <loki@gcc.gnu.org>2008-03-05 10:15:45 +0000
commit1da266feea1a26357fa5522803e8c08f3ac6a5d8 (patch)
treeb2a0902127232292cc6e3b703166fce6e81efdcf /gcc
parentf0f00f130d6ab8f53d69d7c7fa1e9ad3ab87cfda (diff)
downloadgcc-1da266feea1a26357fa5522803e8c08f3ac6a5d8.zip
gcc-1da266feea1a26357fa5522803e8c08f3ac6a5d8.tar.gz
gcc-1da266feea1a26357fa5522803e8c08f3ac6a5d8.tar.bz2
re PR rtl-optimization/33009 (-frtl-abstract-sequences causes an infinite loop)
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. PR testsuite/33009 * gcc.c-torture/compile/pr11832.c: Check -frtl-abstract-sequences. * gcc.c-torture/compile/pr33009.c: Likewise. From-SVN: r132893
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/rtl-factoring.c30
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr11832.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33009.c36
5 files changed, 105 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dc55d3b..22e5ce0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/rtl-factoring.c b/gcc/rtl-factoring.c
index cf07db9..20e9cf2 100644
--- a/gcc/rtl-factoring.c
+++ b/gcc/rtl-factoring.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4be88d7..8341b28 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..a4c3eec
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr11832.c
@@ -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
index 0000000..781e1fe
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33009.c
@@ -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;
+}