Hi Vlad, Vladimir Makarov <vmaka...@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 <vmaka...@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; }