alpha himode reload problem
Jim Wilson
wilson@cygnus.com
Wed Oct 22 19:01:00 GMT 1997
The problem seems to me with the fact that reload records replacement
addresses within the rtl, rather than substituting on a pattern; ref
reload.c 3713 (find_reloads):
There is not supposed to be any RTL generated during reload, except for
RTL that reload knowingly generates itself, and reload always creates RTL
in such a way that it either doesn't need reloads or will be reloaded
by the replacements.
Since we never create random RTL, we can keep track of the addresses that need
to be stored into, and this is more efficient than searching through the RTL
to looking for stuff after the fact that might need fixing. This also
means we don't have to worry about ambiguous cases, e.g. for instance if a
particular RTL occurs in multiple places, but only some of which need to
modified. This is easy to do if we keep track of addresses to do; much harder
if we try to find them via pattern matching.
This breaks down for your example because of two reasons:
- The alpha movhi pattern creates a new MEM rtx because it doesn't support
HImode loads.
- There is an asm that contains a HImode MEM, and valid asm operands are not
passed through emit_move_insn.
Normally, all HImode MEMs would get fixed during RTL generation, because
they have to pass through movhi, and movhi will rewrite them then. HImode
MEMs should only occur during reload as the result of substitution from
REG_EQUIVs, in which case I suspect the address will always be a constant,
or a stack offset, or something else which will not need to be reloaded.
One way to fix this is to modify the movhi pattern to reload the address
itself if necessary, but this isn't very elegant. If we do adopt this
approach, then we need to fix the mov*i patterns too as necessary.
Another way to fix this is to modify expand_asm_operands to fix the MEM
during RTL generation. This seems more elegant. There is already code to
fix a few cases. We could add a case that handles MEM operands. Unfortunately
I don't see any obvious easy way to write the test. The info we need is
encoded in the mov*i patterns. There isn't any particular test we can
perform to see if the MEM operand needs to be handled differently. We
could perhaps just call emit_move_insn to move the MEM into a temp reg,
and then check to see if we got more than one instruction, and if so, we emit
all the insns and use the temp reg as the actual operand. Of course, that
only works if we wanted a reg operand in the first place. Maybe we need
a flag that indicates whether memory operands are OK, and if not, and we
have a MEM, then we load the MEM into a pseudo and use the pseudo as the
operand. This is much better than waiting until reload to fix the operand,
as we then have a chance to optimize the MEM. This would work for your
example.
FYI Here is an ugly hack I wrote to fix the problem in the alpha.md movhi
pattern. I think the expand_asm_operands fix is much better though.
Index: alpha.md
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.9
diff -p -r1.9 alpha.md
*** alpha.md 1997/10/20 15:50:28 1.9
--- alpha.md 1997/10/23 01:59:06
***************
*** 4183,4188 ****
--- 4183,4199 ----
? gen_rtx (REG, SImode, REGNO (operands[0]))
: gen_reg_rtx (SImode));
+ /* ??? This code creates a new MEM rtx. If we were called during
+ reload, then we must be careful to make sure that the new
+ rtx will not need reloading. */
+ if (reload_in_progress &&
+ ! strict_memory_address_p (SImode, XEXP (operands[1], 0)))
+ {
+ rtx tmp = gen_rtx (REG, Pmode, REGNO (operands[0]));
+ emit_insn (gen_move_insn (tmp, XEXP (operands[1], 0)));
+ XEXP (operands[1], 0) = tmp;
+ }
+
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
Jim
More information about the Gcc
mailing list