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
This commit is contained in:
Gabor Loki 2008-03-05 10:15:45 +00:00
parent f0f00f130d
commit 1da266feea
5 changed files with 105 additions and 9 deletions

View 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

View 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. */

View 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

View File

@ -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;
}
}

View File

@ -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;
}