From: loki Date: Wed, 5 Mar 2008 10:15:45 +0000 (+0000) Subject: 2008-03-05 Gabor Loki X-Git-Tag: upstream/4.9.2~43414 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a08778a200c37877029d20fe6a974b5798710b78;p=platform%2Fupstream%2Flinaro-gcc.git 2008-03-05 Gabor Loki 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 --- 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 + + 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 * 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 + + PR 33009 + * gcc.c-torture/compile/pr11832.c: Check -frtl-abstract-sequences. + * gcc.c-torture/compile/pr33009.c: Likewise. + 2008-03-05 Victor Kaplansky 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; +}