diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-21 22:32:39 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-21 22:32:39 +0000 |
commit | cf86e5cee072b19c09ee8e8c11726e71d23bed26 (patch) | |
tree | a02be706edc515e25b0af6853ce327ff8283cda9 | |
parent | db019aef86f8fd438b1e6c8d11411f4df6a0bf4d (diff) | |
download | gcc-cf86e5cee072b19c09ee8e8c11726e71d23bed26.tar.gz |
PR rtl-optimization/29329
* combine.c (replaced_rhs_insn): Rename to i2mod.
(replaced_rhs_value): Rename to i2mod_new_rhs.
(i2mod_old_rhs): New global variable.
(combine_instructions): Adjust for above change. Save a copy of
the old RHS into i2mod_old_rhs when the contents of a REG_EQUAL
note are substituted in the second instruction.
(distribute_notes) <REG_DEAD>: Adjust for above change. Do not
ditch the note if it pertains to the second eliminated register
and this register is mentioned in i2mod_old_rhs.
Revert:
2006-09-12 Eric Botcazou <ebotcazou@libertysurf.fr>
* combine.c (distribute_notes) <REG_DEAD>: Do not consider SETs past
the insn to which the note was originally attached.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121037 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/combine.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20070121.c | 18 |
4 files changed, 71 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a201681e4dc..da8bbf58caf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2007-01-21 Eric Botcazou <ebotcazou@libertysurf.fr> + + PR rtl-optimization/29329 + * combine.c (replaced_rhs_insn): Rename to i2mod. + (replaced_rhs_value): Rename to i2mod_new_rhs. + (i2mod_old_rhs): New global variable. + (combine_instructions): Adjust for above change. Save a copy of + the old RHS into i2mod_old_rhs when the contents of a REG_EQUAL + note are substituted in the second instruction. + (distribute_notes) <REG_DEAD>: Adjust for above change. Do not + ditch the note if it pertains to the second eliminated register + and this register is mentioned in i2mod_old_rhs. + + Revert: + 2006-09-12 Eric Botcazou <ebotcazou@libertysurf.fr> + + * combine.c (distribute_notes) <REG_DEAD>: Do not consider SETs past + the insn to which the note was originally attached. + 2007-01-21 Jan Hubicka <jh@suse.cz> * ipa-inline.c (inlining_mode): Comment, move up. diff --git a/gcc/combine.c b/gcc/combine.c index 32117bee219..aa1e2ce2034 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -123,16 +123,22 @@ static int combine_successes; static int total_attempts, total_merges, total_extras, total_successes; -/* Sometimes combine tries to replace the right hand side of an insn - with the value of a REG_EQUAL note. This is the insn that has been - so modified, or null if none. */ +/* combine_instructions may try to replace the right hand side of the + second instruction with the value of an associated REG_EQUAL note + before throwing it at try_combine. That is problematic when there + is a REG_DEAD note for a register used in the old right hand side + and can cause distribute_notes to do wrong things. This is the + second instruction if it has been so modified, null otherwise. */ -static rtx replaced_rhs_insn; +static rtx i2mod; -/* When REPLACED_RHS_INSN is nonnull, this is a copy of the new right - hand side. */ +/* When I2MOD is nonnull, this is a copy of the old right hand side. */ -static rtx replaced_rhs_value; +static rtx i2mod_old_rhs; + +/* When I2MOD is nonnull, this is a copy of the new right hand side. */ + +static rtx i2mod_new_rhs; /* Vector mapping INSN_UIDs to cuids. The cuids are like uids but increase monotonically always. @@ -932,11 +938,12 @@ combine_instructions (rtx f, unsigned int nregs) be deleted or recognized by try_combine. */ rtx orig = SET_SRC (set); SET_SRC (set) = note; - replaced_rhs_insn = temp; - replaced_rhs_value = copy_rtx (note); - next = try_combine (insn, temp, NULL_RTX, + i2mod = temp; + i2mod_old_rhs = copy_rtx (orig); + i2mod_new_rhs = copy_rtx (note); + next = try_combine (insn, i2mod, NULL_RTX, &new_direct_jump_p); - replaced_rhs_insn = NULL; + i2mod = NULL_RTX; if (next) goto retry; SET_SRC (set) = orig; @@ -12140,8 +12147,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, use of A and put the death note there. */ if (from_insn - && from_insn == replaced_rhs_insn - && !reg_overlap_mentioned_p (XEXP (note, 0), replaced_rhs_value)) + && from_insn == i2mod + && !reg_overlap_mentioned_p (XEXP (note, 0), i2mod_new_rhs)) tem = from_insn; else { @@ -12154,7 +12161,10 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, else if (i2 != 0 && next_nonnote_insn (i2) == i3 && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) place = i2; - else if (rtx_equal_p (XEXP (note, 0), elim_i2) + else if ((rtx_equal_p (XEXP (note, 0), elim_i2) + && !(i2mod + && reg_overlap_mentioned_p (XEXP (note, 0), + i2mod_old_rhs))) || rtx_equal_p (XEXP (note, 0), elim_i1)) break; tem = i3; @@ -12173,14 +12183,12 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, continue; } - /* If TEM is a (reaching) definition of the use to which the - note was attached, see if that is all TEM is doing. If so, - delete TEM. Otherwise, make this into a REG_UNUSED note - instead. Don't delete sets to global register vars. */ - if ((!from_insn - || INSN_CUID (tem) < INSN_CUID (from_insn)) - && (REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER - || !global_regs[REGNO (XEXP (note, 0))]) + /* If the register is being set at TEM, see if that is all + TEM is doing. If so, delete TEM. Otherwise, make this + into a REG_UNUSED note instead. Don't delete sets to + global register vars. */ + if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER + || !global_regs[REGNO (XEXP (note, 0))]) && reg_set_p (XEXP (note, 0), PATTERN (tem))) { rtx set = single_set (tem); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e92e40bcf4f..ff69cda1751 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-01-21 Eric Botcazou <ebotcazou@libertysurf.fr> + + * gcc.c-torture/compile/20070121.c: New test. + 2007-01-21 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/30525 diff --git a/gcc/testsuite/gcc.c-torture/compile/20070121.c b/gcc/testsuite/gcc.c-torture/compile/20070121.c new file mode 100644 index 00000000000..88af8bf6286 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20070121.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/29329 */ +/* Origin: Debian GCC Maintainers <debian-gcc@lists.debian.org> */ +/* Testcase by: Andrew Pinski <pinskia@gmail.com> */ + +struct node234_Tag +{ + int t1; + int kids[4]; + void *elems[3]; +}; + +void *add234_internal(struct node234_Tag *n, int ei) +{ + int j; + for (j = ei; j < 2 && n->elems[j+1];) + j++; + n->kids[j+1] = 0; +} |