tertiary reload sanity
Richard Henderson
rth@cygnus.com
Fri Aug 11 02:02:00 GMT 2000
For reasons I was never really clear on, reload might decide to
overlap the scratch register used for reload_in/out patterns
with one of the inputs. I ran across this again today on the
IA-64 port and asked Jim "Why?".
After much digging it turns out the answer is "No reason".
In other words, a quirk of initial implementation sometime before
gcc 2.0, and the first users of reload_in/out either didn't require
non-overlapping scratches (sparc) or, by virtue of the register
classes involved, couldn't have overlap (romp).
We decided that it just didn't ever make sense to not provide
a brand new scratch register. If you didn't need a new scratch,
why would you be asking for one?
Tested on ia64 and alpha ev4 linux.
r~
* reload.c (push_secondary_reload): When invoking a reload_{in,out}
pattern, always allocate a tertiary scratch register.
* config/alpha/alpha.md (reload_inqi): Use a DImode scratch.
(reload_inhi): Likewise.
Index: reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload.c,v
retrieving revision 1.117
diff -c -p -d -r1.117 reload.c
*** reload.c 2000/08/04 20:28:05 1.117
--- reload.c 2000/08/11 08:35:48
*************** push_secondary_reload (in_p, x, opnum, o
*** 375,387 ****
in operand 1. Outputs should have an initial "=", which we must
skip. */
! char insn_letter
! = insn_data[(int) icode].operand[!in_p].constraint[in_p];
! enum reg_class insn_class
! = (insn_letter == 'r' ? GENERAL_REGS
! : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
! if (insn_class == NO_REGS
|| (in_p
&& insn_data[(int) icode].operand[!in_p].constraint[0] != '=')
/* The scratch register's constraint must start with "=&". */
--- 375,387 ----
in operand 1. Outputs should have an initial "=", which we must
skip. */
! char insn_letter, t_letter;
! insn_letter = insn_data[(int) icode].operand[!in_p].constraint[in_p];
! class = (insn_letter == 'r' ? GENERAL_REGS
! : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
!
! if (class == NO_REGS
|| (in_p
&& insn_data[(int) icode].operand[!in_p].constraint[0] != '=')
/* The scratch register's constraint must start with "=&". */
*************** push_secondary_reload (in_p, x, opnum, o
*** 389,406 ****
|| insn_data[(int) icode].operand[2].constraint[1] != '&')
abort ();
! if (reg_class_subset_p (reload_class, insn_class))
! mode = insn_data[(int) icode].operand[2].mode;
! else
! {
! char t_letter = insn_data[(int) icode].operand[2].constraint[2];
! class = insn_class;
! t_mode = insn_data[(int) icode].operand[2].mode;
! t_class = (t_letter == 'r' ? GENERAL_REGS
! : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
! t_icode = icode;
! icode = CODE_FOR_nothing;
! }
}
/* This case isn't valid, so fail. Reload is allowed to use the same
--- 389,400 ----
|| insn_data[(int) icode].operand[2].constraint[1] != '&')
abort ();
! t_letter = insn_data[(int) icode].operand[2].constraint[2];
! t_mode = insn_data[(int) icode].operand[2].mode;
! t_class = (t_letter == 'r' ? GENERAL_REGS
! : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
! t_icode = icode;
! icode = CODE_FOR_nothing;
}
/* This case isn't valid, so fail. Reload is allowed to use the same
*************** push_secondary_reload (in_p, x, opnum, o
*** 410,424 ****
silently generating incorrect code later.
The convention is that secondary input reloads are valid only if the
! secondary_class is different from class. If you have such a case, you
! can not use secondary reloads, you must work around the problem some
! other way.
! Allow this when MODE is not reload_mode and assume that the generated
! code handles this case (it does on the Alpha, which is the only place
! this currently happens). */
! if (in_p && class == reload_class && mode == reload_mode)
abort ();
/* If we need a tertiary reload, see if we have one we can reuse or else
--- 404,417 ----
silently generating incorrect code later.
The convention is that secondary input reloads are valid only if the
! secondary class is different from the reload class. If you have such
! a case, you can not use secondary reloads, you must work around the
! problem some other way.
! Allow this when a tertiary reload is used; i.e. assume that the
! generated code handles this case. */
! if (in_p && class == reload_class && t_class == NO_REGS)
abort ();
/* If we need a tertiary reload, see if we have one we can reuse or else
Index: config/alpha/alpha.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.125
diff -c -p -d -r1.125 alpha.md
*** alpha.md 2000/08/08 22:40:48 1.125
--- alpha.md 2000/08/11 08:35:48
***************
*** 5343,5353 ****
(define_expand "reload_inqi"
[(parallel [(match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "any_memory_operand" "m")
! (match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
"
{
! rtx scratch, seq;
if (GET_CODE (operands[1]) != MEM)
abort ();
--- 5343,5353 ----
(define_expand "reload_inqi"
[(parallel [(match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "any_memory_operand" "m")
! (match_operand:DI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
"
{
! rtx seq;
if (GET_CODE (operands[1]) != MEM)
abort ();
***************
*** 5361,5376 ****
{
rtx addr;
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (REGNO (operands[0]) == REGNO (operands[2]))
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
- else
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
-
addr = get_unaligned_address (operands[1], 0);
! seq = gen_unaligned_loadqi (operands[0], addr, scratch,
gen_rtx_REG (DImode, REGNO (operands[0])));
alpha_set_memflags (seq, operands[1]);
}
--- 5361,5368 ----
{
rtx addr;
addr = get_unaligned_address (operands[1], 0);
! seq = gen_unaligned_loadqi (operands[0], addr, operands[2],
gen_rtx_REG (DImode, REGNO (operands[0])));
alpha_set_memflags (seq, operands[1]);
}
***************
*** 5381,5391 ****
(define_expand "reload_inhi"
[(parallel [(match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "any_memory_operand" "m")
! (match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
"
{
! rtx scratch, seq;
if (GET_CODE (operands[1]) != MEM)
abort ();
--- 5373,5383 ----
(define_expand "reload_inhi"
[(parallel [(match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "any_memory_operand" "m")
! (match_operand:DI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
"
{
! rtx seq;
if (GET_CODE (operands[1]) != MEM)
abort ();
***************
*** 5399,5414 ****
{
rtx addr;
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (REGNO (operands[0]) == REGNO (operands[2]))
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
- else
- scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
-
addr = get_unaligned_address (operands[1], 0);
! seq = gen_unaligned_loadhi (operands[0], addr, scratch,
gen_rtx_REG (DImode, REGNO (operands[0])));
alpha_set_memflags (seq, operands[1]);
}
--- 5391,5398 ----
{
rtx addr;
addr = get_unaligned_address (operands[1], 0);
! seq = gen_unaligned_loadhi (operands[0], addr, operands[2],
gen_rtx_REG (DImode, REGNO (operands[0])));
alpha_set_memflags (seq, operands[1]);
}
More information about the Gcc-patches
mailing list