This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: scratch registers for peephole2
- To: rearnsha at arm dot com
- Subject: Re: scratch registers for peephole2
- From: Denis Chertykov <denisc at overta dot ru>
- Date: 06 Jan 2001 13:33:16 +0300
- Cc: gcc at gcc dot gnu dot org, <marekm at linux dot org dot pl>, <rth at redhat dot com>
- References: <200101051956.TAA10943@cam-mail2.cambridge.arm.com>
Richard Earnshaw <rearnsha@arm.com> writes:
> I've deleted the original mail, but I seem to recall that the AVR port was
> having problems with scratch registers being used in peephole2 that were
> not unsafe. Looking at the code in recog.c, it would appear that there is
> potentially a similar problem on the ARM with the return register (which
> is treated as a call-clobbered reg, but can contain real data).
The avr port have this problem only with interrupt or signal
functions.
void foo() __attribute__ ((interrupt));
void foo()
{
*vp = v >> 6;
}
In such functions avr port must save/restore all used registers.
`peep2_find_free_register' can choose register from the
CALL_USED_REGISTERS it's normal for ordinar functions, but it's wrong
for AVR "interrupt" and "signal" functions.
We resolve this problem:
(define_peephole2
[(match_scratch:QI 2 "d")
(set (match_operand:QI 0 "register_operand" "")
(match_operand:QI 1 "immediate_operand" ""))]
"(operands[1] != const0_rtx
&& test_hard_reg_class (NO_LD_REGS, operands[0]))"
[(parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))])]
"if (!avr_peep2_scratch_safe (operands[2]))
FAIL; /* <--------------- */ ")
int
avr_peep2_scratch_safe (scratch)
rtx scratch;
{
if ((interrupt_function_p (current_function_decl)
|| signal_function_p (current_function_decl))
&& leaf_function_p ())
{
int first_reg = true_regnum (scratch);
int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
int reg;
for (reg = first_reg; reg <= last_reg; reg++)
{
if (!regs_ever_live[reg])
return 0;
}
}
return 1;
}
> >>> /* The target may have further reasons for rejecting the register.
> */
> >>> if (! REGNO_OK_FOR_PEEPHOLE2 (regno))
> >>> continue;
>
> I'd be inclined to make this macro unconditional, any port using peephole2
> should define it (it can be 1 if all registers are safe).
Your solution more smart.
Because avr port can reject unsaved registers and agree with the saved
registers if they exists.
Richard Henderson writes:
> Maybe, but your problem on arm with the return register is not,
> repeat NOT here. It is that you havn't represented that the
> register is live either through rtl or through EPILOGUE_USES.
I don't know anything about arm specific problems. But, for avr your
solution is better than we have.
Denis.