This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: version 2 patch to fix PR37514
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jeffrey Law <law at redhat dot com>, Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>, Bernd Schmidt <bernds_cb1 at t-online dot de>
- Date: Thu, 27 Nov 2008 16:07:53 -0500
- Subject: RFA: version 2 patch to fix PR37514
The following patch solves a latent reload bug (in reload inheritance)
triggered by IRA. It is a second version (less pessimistic in reload
inheritance optimization) of the patch
The problem is described on
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37514
The patch invalidates reg_last_reload_reg set in previous insns for
INC/DEC if reg_last_reload_reg set is not set for the current insn for
some reasons (e.g. the hard register is used in other insn reloads
besides reload for INC/DEC).
The patch was tested on SH (with -m4 -ml -O3 -fomit-frame-pointer) and
successfully bootstrapped on itanium (another port using INC/DEC heavily).
Ok to commit?
2008-11-25 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/37514
* reload1.c (reload_as_needed): Invalidate reg_last_reload
from previous insns.
Index: reload1.c
===================================================================
--- reload1.c (revision 142061)
+++ reload1.c (working copy)
@@ -4164,6 +4164,7 @@ reload_as_needed (int live_known)
rtx prev = 0;
rtx insn = chain->insn;
rtx old_next = NEXT_INSN (insn);
+ rtx old_prev = PREV_INSN (insn);
/* If we pass a label, copy the offsets from the label information
into the current offsets of each elimination. */
@@ -4388,6 +4389,33 @@ reload_as_needed (int live_known)
SET_REGNO_REG_SET (®_has_output_reload,
REGNO (XEXP (in_reg, 0)));
}
+ else if ((code == PRE_INC || code == PRE_DEC
+ || code == POST_INC || code == POST_DEC))
+ {
+ int in_hard_regno;
+ int in_regno = REGNO (XEXP (in_reg, 0));
+
+ if (reg_last_reload_reg[in_regno] != NULL_RTX)
+ {
+ in_hard_regno = REGNO (reg_last_reload_reg[in_regno]);
+ gcc_assert (TEST_HARD_REG_BIT (reg_reloaded_valid,
+ in_hard_regno));
+ for (x = old_prev ? NEXT_INSN (old_prev) : insn;
+ x != old_next;
+ x = NEXT_INSN (x))
+ if (x == reg_reloaded_insn[in_hard_regno])
+ break;
+ /* If for some reasons, we didn't set up
+ reg_last_reload_reg in this insn,
+ invalidate inheritance from previous
+ insns for the incremented/decremented
+ register. Such registers will be not in
+ reg_has_output_reload. */
+ if (x == old_next)
+ forget_old_reloads_1 (XEXP (in_reg, 0),
+ NULL_RTX, NULL);
+ }
+ }
}
}
/* If a pseudo that got a hard register is auto-incremented,