This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: patch to solve PR49936


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;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]