James E Wilson wrote:
Yes, that is what I was suggesting.
It's corrected and tested on ia64 and x86-64. I've attached new version.
Denis.
Index: reload.c
===================================================================
*** reload.c (revision 111135)
--- reload.c (working copy)
*************** static int find_inc_amount (rtx, rtx);
*** 281,286 ****
--- 281,287 ----
static int refers_to_mem_for_reload_p (rtx);
static int refers_to_regno_for_reload_p (unsigned int, unsigned int,
rtx, rtx *);
+ static int reg_inc_found_and_valid_p (unsigned int, unsigned int, rtx);
/* Determine if any secondary reloads are needed for loading (if IN_P is
nonzero) or storing (if IN_P is zero) X to or from a reload register of
*************** find_inc_amount (rtx x, rtx inced)
*** 6941,6949 ****
return 0;
}
/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
! If SETS is nonzero, also consider SETs. REGNO must refer to a hard
! register. */
int
regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
--- 6942,6977 ----
return 0;
}
+ /* Return 1 if registers from REGNO to ENDREGNO are the subjects of a
+ REG_INC note in insn INSN. REGNO must refer to a hard register. */
+
+ static int
+ reg_inc_found_and_valid_p (unsigned int regno ATTRIBUTE_UNUSED,
+ unsigned int endregno ATTRIBUTE_UNUSED,
+ rtx insn ATTRIBUTE_UNUSED)
+ {
+ #ifdef AUTO_INC_DEC
+ rtx link;
+
+ gcc_assert (insn);
+
+ if (! INSN_P (insn))
+ return 0;
+
+ for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+ if (REG_NOTE_KIND (link) == REG_INC)
+ {
+ unsigned int test = (int) REGNO (XEXP (link, 0));
+ if (test >= regno && test < endregno)
+ return 1;
+ }
+ #endif
+ return 0;
+ }
+
/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
! If SETS is 1, also consider SETs. If SETS is 2, enable checking REG_INC.
! REGNO must refer to a hard register. */
int
regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
*************** regno_clobbered_p (unsigned int regno, r
*** 6958,6964 ****
endregno = regno + nregs;
if ((GET_CODE (PATTERN (insn)) == CLOBBER
! || (sets && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (PATTERN (insn), 0)))
{
unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
--- 6986,6992 ----
endregno = regno + nregs;
if ((GET_CODE (PATTERN (insn)) == CLOBBER
! || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (PATTERN (insn), 0)))
{
unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
*************** regno_clobbered_p (unsigned int regno, r
*** 6966,6971 ****
--- 6994,7002 ----
return test >= regno && test < endregno;
}
+ if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, insn))
+ return 1;
+
if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
int i = XVECLEN (PATTERN (insn), 0) - 1;
*************** regno_clobbered_p (unsigned int regno, r
*** 6974,6980 ****
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
if ((GET_CODE (elt) == CLOBBER
! || (sets && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (elt, 0)))
{
unsigned int test = REGNO (XEXP (elt, 0));
--- 7005,7011 ----
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
if ((GET_CODE (elt) == CLOBBER
! || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
&& REG_P (XEXP (elt, 0)))
{
unsigned int test = REGNO (XEXP (elt, 0));
*************** regno_clobbered_p (unsigned int regno, r
*** 6982,6987 ****
--- 7013,7020 ----
if (test >= regno && test < endregno)
return 1;
}
+ if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, elt))
+ return 1;
}
}
Index: reload1.c
===================================================================
*** reload1.c (revision 110905)
--- reload1.c (working copy)
*************** choose_reload_regs (struct insn_chain *c
*** 5780,5786 ****
if (equiv != 0)
{
! if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
--- 5780,5786 ----
if (equiv != 0)
{
! if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
2006-02-16 Denis Nagorny <[EMAIL PROTECTED]>
PR rtl-optimization/25603
* reload.c (reg_inc_found_and_valid_p): New. Check REG_INC note.
(regno_clobbered_p): Use it. Reusing SETS argument for REG_INC case.
* reload1.c (choose_reload_regs): Added call of regno_clobbered_p
with new meaning of SETS.