diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-13 13:29:28 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-13 13:29:28 +0000 |
commit | 522ca5400502ca857adab503693ef095aaf9a1bc (patch) | |
tree | 9e9e3d0b28e42649ff838117757c2528579112bc /gcc/combine.c | |
parent | 8561b0408e1a5e3a2d48d28592e01a53f2e1de0f (diff) | |
download | gcc-522ca5400502ca857adab503693ef095aaf9a1bc.tar.gz |
PR rtl-optimization/58662
* combine.c (try_combine): Take into account death nodes on I2 when
splitting a PARALLEL of two independent SETs. Fix dump message.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203498 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index fcf60cd08aa..13f5e29e3d6 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -3693,29 +3693,42 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0))) && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))))) { + rtx set0 = XVECEXP (newpat, 0, 0); + rtx set1 = XVECEXP (newpat, 0, 1); + /* Normally, it doesn't matter which of the two is done first, but the one that references cc0 can't be the second, and one which uses any regs/memory set in between i2 and i3 can't - be first. */ - if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 1)), - DF_INSN_LUID (i2)) + be first. The PARALLEL might also have been pre-existing in i3, + so we need to make sure that we won't wrongly hoist a SET to i2 + that would conflict with a death note present in there. */ + if (!use_crosses_set_p (SET_SRC (set1), DF_INSN_LUID (i2)) + && !(REG_P (SET_DEST (set1)) + && find_reg_note (i2, REG_DEAD, SET_DEST (set1))) + && !(GET_CODE (SET_DEST (set1)) == SUBREG + && find_reg_note (i2, REG_DEAD, + SUBREG_REG (SET_DEST (set1)))) #ifdef HAVE_cc0 - && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 0)) + && !reg_referenced_p (cc0_rtx, set0) #endif ) { - newi2pat = XVECEXP (newpat, 0, 1); - newpat = XVECEXP (newpat, 0, 0); + newi2pat = set1; + newpat = set0; } - else if (!use_crosses_set_p (SET_SRC (XVECEXP (newpat, 0, 0)), - DF_INSN_LUID (i2)) + else if (!use_crosses_set_p (SET_SRC (set0), DF_INSN_LUID (i2)) + && !(REG_P (SET_DEST (set0)) + && find_reg_note (i2, REG_DEAD, SET_DEST (set0))) + && !(GET_CODE (SET_DEST (set0)) == SUBREG + && find_reg_note (i2, REG_DEAD, + SUBREG_REG (SET_DEST (set0)))) #ifdef HAVE_cc0 - && !reg_referenced_p (cc0_rtx, XVECEXP (newpat, 0, 1)) + && !reg_referenced_p (cc0_rtx, set1) #endif ) { - newi2pat = XVECEXP (newpat, 0, 0); - newpat = XVECEXP (newpat, 0, 1); + newi2pat = set0; + newpat = set1; } else { @@ -4261,9 +4274,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, } /* Update reg_stat[].nonzero_bits et al for any changes that may have - been made to this insn. The order of - set_nonzero_bits_and_sign_copies() is important. Because newi2pat - can affect nonzero_bits of newpat */ + been made to this insn. The order is important, because newi2pat + can affect nonzero_bits of newpat. */ if (newi2pat) note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL); note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL); @@ -4283,7 +4295,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, { if (dump_file) { - fprintf (dump_file, "modifying insn i1 "); + fprintf (dump_file, "modifying insn i0 "); dump_insn_slim (dump_file, i0); } df_insn_rescan (i0); @@ -4321,7 +4333,6 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, /* Set new_direct_jump_p if a new return or simple jump instruction has been created. Adjust the CFG accordingly. */ - if (returnjump_p (i3) || any_uncondjump_p (i3)) { *new_direct_jump_p = 1; |