This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
mn10300-elf reload problem (enabled by subreg byte?)
- To: gcc-patches at gcc dot gnu dot org
- Subject: mn10300-elf reload problem (enabled by subreg byte?)
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 09 Apr 2001 08:56:35 -0300
- Organization: GCC Team, Red Hat
While building mn10300-elf's libstdc++-v3 (main multilib variant)
after the SUBREG_BYTE patch went it, subreg_hard_regno(), as called by
alter_subreg_regno(), would abort() in the following insn:
(set (reg:QI d1) (subreg:QI (reg:SI a3)))
because HARD_REGNO_MODE_OK is false for a3 and QImode unless
TARGET_AM33.
The pseudo that was assigned to a3 had many uses in SImode, so, even
though its preferred class was DATA_REGS, the alternate register class
was DATA_OR_ADDRESS_REGS. Presumably, REGISTER_MOVE_COST could be
increased between DATA_REGS and other classes when moving subword
modes, but it would probably still be possible to construct a case in
which global alloc would assign such a pseudo to an address register,
and reload would have to fix it up.
Here's a patch that arranges for reload to detect the invalid hard
register use within the SUBREG, and push a reload so that it's fixed
up. With this patch, mn10300-elf builds libstdc++-v3 to completion.
Ok to install?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* reload.c (find_reloads_toplev): Reload hard REG into a regclass
that can hold a value in the mode of the containing SUBREG.
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload.c,v
retrieving revision 1.144
diff -u -p -r1.144 reload.c
--- gcc/reload.c 2001/04/03 15:05:23 1.144
+++ gcc/reload.c 2001/04/09 11:46:23
@@ -4410,6 +4410,30 @@ find_reloads_toplev (x, opnum, type, ind
|| num_not_at_initial_offset))))
x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
insn);
+
+ /* If a pseudo was assigned to a hardware register for which the
+ SUBREG mode isn't valid, reload it into some register that
+ can hold that mode. */
+ else if (regno < FIRST_PSEUDO_REGISTER
+ && ! HARD_REGNO_MODE_OK (regno, GET_MODE (x)))
+ {
+ enum machine_mode subreg_mode = GET_MODE (SUBREG_REG (x));
+ enum machine_mode needed_mode = GET_MODE (x);
+
+ if (is_set_dest)
+ push_reload (NULL_RTX, SUBREG_REG (x), NULL_RTX, &SUBREG_REG (x),
+ find_valid_class (needed_mode,
+ SUBREG_BYTE (x)
+ / GET_MODE_SIZE (subreg_mode)),
+ VOIDmode, subreg_mode, 0, 0, opnum, type);
+ else
+ push_reload (SUBREG_REG (x), NULL_RTX, &SUBREG_REG (x), NULL_PTR,
+ find_valid_class (needed_mode,
+ SUBREG_BYTE (x)
+ / GET_MODE_SIZE (subreg_mode)),
+ subreg_mode, VOIDmode, 0, 0, opnum, type);
+ }
+
}
else if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM
&& (GET_MODE_SIZE (GET_MODE (x))
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me