Commit 1da266fe by Gabor Loki

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
parent f0f00f13
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> 2008-03-04 Geoff Keating <geoffk@apple.com>
* fold-const.c (tree_single_nonnegative_warnv_p): Fix mixed * fold-const.c (tree_single_nonnegative_warnv_p): Fix mixed
......
/* RTL factoring (sequence abstraction). /* 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. This file is part of GCC.
...@@ -551,8 +551,8 @@ clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length) ...@@ -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); df_simulate_artificial_refs_at_end (bb, &live);
/* Propagate until INSN if found. */ /* Propagate until INSN if found. */
for (x = BB_END (bb); x != insn;) for (x = BB_END (bb); x != insn; x = PREV_INSN (x))
df_simulate_one_insn_backwards (bb, insn, &live); df_simulate_one_insn_backwards (bb, x, &live);
/* Clear registers live after INSN. */ /* Clear registers live after INSN. */
renumbered_reg_set_to_hard_reg_set (&hlive, &live); 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) ...@@ -562,7 +562,7 @@ clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
for (i = 0; i < length;) for (i = 0; i < length;)
{ {
rtx prev = PREV_INSN (x); 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)) if (INSN_P (x))
{ {
...@@ -949,6 +949,17 @@ gen_symbol_ref_rtx_for_label (const_rtx label) ...@@ -949,6 +949,17 @@ gen_symbol_ref_rtx_for_label (const_rtx label)
return sym; 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 /* Ensures that INSN is the last insn in its block and returns the block label
of the next block. */ of the next block. */
...@@ -959,7 +970,7 @@ block_label_after (rtx insn) ...@@ -959,7 +970,7 @@ block_label_after (rtx insn)
if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR)) if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
return block_label (bb->next_bb); return block_label (bb->next_bb);
else 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 /* Ensures that the last insns of the best pattern and its matching sequences
...@@ -1008,8 +1019,9 @@ split_pattern_seq (void) ...@@ -1008,8 +1019,9 @@ split_pattern_seq (void)
/* Emit an indirect jump via the link register after the sequence acting /* 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. */ 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), if (!find_reg_note (BB_END (bb), REG_NORETURN, NULL))
BB_END (bb)); retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
BB_END (bb));
emit_barrier_after (BB_END (bb)); emit_barrier_after (BB_END (bb));
/* Replace all outgoing edges with a new one to the block of RETLABEL. */ /* Replace all outgoing edges with a new one to the block of RETLABEL. */
...@@ -1025,7 +1037,7 @@ split_pattern_seq (void) ...@@ -1025,7 +1037,7 @@ split_pattern_seq (void)
for (; i < sb->length; i++) for (; i < sb->length; i++)
insn = prev_insn_in_block (insn); 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 /* Emit an insn saving the return address to the link register before the
...@@ -1067,7 +1079,7 @@ erase_matching_seqs (void) ...@@ -1067,7 +1079,7 @@ erase_matching_seqs (void)
/* Delete the insns of the sequence. */ /* Delete the insns of the sequence. */
for (i = 0; i < sb->length; i++) for (i = 0; i < sb->length; i++)
insn = prev_insn_in_block (insn); 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 /* Emit an insn saving the return address to the link register
before the deleted sequence. */ before the deleted sequence. */
......
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> 2008-03-05 Victor Kaplansky <victork@gcc.gnu.org>
PR 31341 PR 31341
/* { 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;
}
}
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment