This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: patch to solve PR49936
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Vladimir Makarov <vmakarov at redhat dot com>
- Cc: "gcc-patches\ at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 20 Aug 2011 11:13:40 +0100
- Subject: Re: patch to solve PR49936
- References: <4E4EE1A3.7010103@redhat.com>
Hi Vlad,
Vladimir Makarov <vmakarov@redhat.com> writes:
> The following patch makes gcc4.7 behaving as gcc4.6 for the case
> described on http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49936.
>
> The patch was successfully bootstrapped on x86_64 and ppc64.
>
> Committed as rev 177916.
>
> 2011-08-19 Vladimir Makarov <vmakarov@redhat.com>
>
> PR rtl-optimization/49936
> * ira.c (ira_init_register_move_cost): Ignore too small subclasses
> for calculation of max register move costs.
Thanks for the patch. The allocno class costs for MIPS look
much better now.
However, the patch seems to expose a latent problem with the use of
ira_reg_class_max_nregs. We set the number of allocno objects based
on the ira_reg_class_max_nregs of the allocno class, but often
expect that to be the same as the ira_reg_class_max_nregs of the
pressure class. I can't see anything in the calculation of the
pressure classes to enforce that though.
In current trunk, this shows up as a failure to build libgcc
on mips64-linux-gnu. We abort on:
pclass = ira_pressure_class_translate[ALLOCNO_CLASS (a)];
nregs = ira_reg_class_max_nregs[pclass][ALLOCNO_MODE (a)];
gcc_assert (nregs == n);
in ira-lives.c:mark_pseudo_regno_subword_live for the attached
testcase, compiled with -O2 -mabi=64.
In this case it's a MIPS backend bug. The single pressure class
for MIPS is ALL_REGS, and CLASS_MAX_NREGS (ALL_REGS, TImode)
is returning 4, based on the fact that ALL_REGS includes the
floating-point condition codes. (CCmode is hard-wired to 4 bytes,
so for CCV2 and CCV4, the correct number of registers is the size
of the mode divided by 4.) Since floating-point condition codes
can't store TImode, the backend should be ignoring them and
returning 2 instead. I'm testing a fix for that now.
However, there are other situations where different register banks
really do need different numbers of registers to store the same thing.
E.g. MIPS has a mode in which the core registers are 32 bits but the
floating-point registers are 64 bits. Thus:
CLASS_MAX_NREGS (GR_REGS, DFmode) == 2
CLASS_MAX_NREGS (FP_REGS, DFmode) == 1
CLASS_MAX_NREGS (ALL_REGS, DFmode) == 2
Moves between GR_REGS and FP_REGS are cheaper than moves between memory
-- MIPS32r2 provides special move instructions -- so the two classes
still end up in the same pressure class.
Richard
typedef int DItype __attribute__((mode(DI)));
typedef int TItype __attribute__((mode(TI)));
DItype
__mulvdi3 (DItype a, DItype b)
{
const TItype w = (TItype) a * (TItype) b;
if ((DItype) (w >> (8 * 8)) != (DItype) w >> ((8 * 8) - 1))
abort ();
return w;
}