This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: bug fix for egcs/gcc/reload1.c
- To: wilson at cygnus dot com
- Subject: Re: bug fix for egcs/gcc/reload1.c
- From: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Date: Fri, 2 Oct 1998 16:57:50 +0100 (BST)
- Cc: egcs-patches at cygnus dot com
It turned out that it is crucial to clear after_call immediately when
the return register is copied in a single piece. With the original
patch I got failures for SH -m1 -O0 when compiling execute/921029-1.c
and execute/conversion.c , respectively.
Here is a refined patch:
Fri Oct 2 16:54:08 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* reload1.c (calculate_needs_all_insns, reload_as_needed):
Don't clear after_call for a CLOBBER.
Keep track of how many hard registers need to be copied from
after_call, and don't clear after_call before we have seen
that much copies, or we see a different instruction.
*** reload1.c-1998100116 Thu Oct 1 16:15:50 1998
--- reload1.c Fri Oct 2 16:47:07 1998
*************** calculate_needs_all_insns (first, global
*** 1443,1448 ****
--- 1443,1449 ----
rtx insn;
int something_changed = 0;
rtx after_call = 0;
+ int after_call_nregs;
/* Keep track of which basic blocks are needing the reloads. */
int this_block = 0;
*************** calculate_needs_all_insns (first, global
*** 1481,1501 ****
if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
{
if (GET_CODE (PATTERN (insn)) == SET)
! after_call = SET_DEST (PATTERN (insn));
else if (GET_CODE (PATTERN (insn)) == PARALLEL
&& GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
else
after_call = 0;
}
else if (SMALL_REGISTER_CLASSES && after_call != 0
&& !(GET_CODE (PATTERN (insn)) == SET
&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
&& GET_CODE (PATTERN (insn)) != USE)
{
if (reg_referenced_p (after_call, PATTERN (insn)))
! avoid_return_reg = after_call;
! after_call = 0;
}
/* If needed, eliminate any eliminable registers. */
--- 1482,1525 ----
if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
{
if (GET_CODE (PATTERN (insn)) == SET)
! {
! after_call = SET_DEST (PATTERN (insn));
! after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! GET_MODE (after_call));
! }
else if (GET_CODE (PATTERN (insn)) == PARALLEL
&& GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! {
! after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
! after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! GET_MODE (after_call));
! }
else
after_call = 0;
}
else if (SMALL_REGISTER_CLASSES && after_call != 0
&& !(GET_CODE (PATTERN (insn)) == SET
&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
+ && GET_CODE (PATTERN (insn)) != CLOBBER
&& GET_CODE (PATTERN (insn)) != USE)
{
if (reg_referenced_p (after_call, PATTERN (insn)))
! {
! avoid_return_reg = after_call;
! if (! --after_call_nregs)
! after_call = 0;
! else
! {
! /* If INSN copies the return register in a single chunk,
! clear after_call now. */
! rtx set = single_set (insn);
! if (set && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
! == GET_MODE_SIZE (GET_MODE (after_call))))
! after_call = 0;
! }
! }
! else
! after_call = 0;
}
/* If needed, eliminate any eliminable registers. */
*************** reload_as_needed (first, live_known)
*** 4111,4116 ****
--- 4135,4141 ----
int this_block = 0;
rtx x;
rtx after_call = 0;
+ int after_call_nregs;
bzero ((char *) spill_reg_rtx, sizeof spill_reg_rtx);
bzero ((char *) spill_reg_store, sizeof spill_reg_store);
*************** reload_as_needed (first, live_known)
*** 4181,4201 ****
if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
{
if (GET_CODE (PATTERN (insn)) == SET)
! after_call = SET_DEST (PATTERN (insn));
else if (GET_CODE (PATTERN (insn)) == PARALLEL
&& GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
else
after_call = 0;
}
else if (SMALL_REGISTER_CLASSES && after_call != 0
&& !(GET_CODE (PATTERN (insn)) == SET
&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
&& GET_CODE (PATTERN (insn)) != USE)
{
if (reg_referenced_p (after_call, PATTERN (insn)))
! avoid_return_reg = after_call;
! after_call = 0;
}
/* If this is a USE and CLOBBER of a MEM, ensure that any
--- 4206,4249 ----
if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
{
if (GET_CODE (PATTERN (insn)) == SET)
! {
! after_call = SET_DEST (PATTERN (insn));
! after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! GET_MODE (after_call));
! }
else if (GET_CODE (PATTERN (insn)) == PARALLEL
&& GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! {
! after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
! after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! GET_MODE (after_call));
! }
else
after_call = 0;
}
else if (SMALL_REGISTER_CLASSES && after_call != 0
&& !(GET_CODE (PATTERN (insn)) == SET
&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
+ && GET_CODE (PATTERN (insn)) != CLOBBER
&& GET_CODE (PATTERN (insn)) != USE)
{
if (reg_referenced_p (after_call, PATTERN (insn)))
! {
! avoid_return_reg = after_call;
! if (! --after_call_nregs)
! after_call = 0;
! else
! {
! /* If INSN copies the return register in a single chunk,
! clear after_call now. */
! rtx set = single_set (insn);
! if (set && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
! == GET_MODE_SIZE (GET_MODE (after_call))))
! after_call = 0;
! }
! }
! else
! after_call = 0;
}
/* If this is a USE and CLOBBER of a MEM, ensure that any