This is the mail archive of the 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: IRA preferencing issues

> Matthew Fortune wrote:
> Wilco Dijkstra <> writes:
> > While investigating why the IRA preferencing algorithm often chooses
> > incorrect preferences from the costs, I noticed this thread:
> >
> >
> > I am seeing the exact same issue on AArch64 - during the final
> > preference selection ira-costs takes the union of any register classes
> > that happen to have equal cost. As a result many registers get ALL_REGS
> > as the preferred register eventhough its cost is much higher than either
> > GENERAL_REGS or FP_REGS. So we end up with lots of scalar SIMD
> > instructions and expensive int<->FP moves in integer code when register
> > pressure is high. When the preference is computed correctly as in the
> > proposed patch (choosing the first class with lowest cost, ie.
> > GENERAL_REGS) the resulting code is much more efficient, and there are
> > no spurious SIMD instructions.
> >
> > Choosing a preferred class when it doesn't have the lowest cost is
> > clearly incorrect. So is there a good reason why the proposed patch
> > should not be applied? I actually wonder why we'd ever need to do a
> > union - if there are 2 classes with equal cost, you'd use the 2nd as the
> > alternative class.
> >
> > The other question I had is whether there is a good way to get improve
> > the preference in cases like this and avoid classes with equal cost
> > altogether. The costs are clearly not equal: scalar SIMD instructions
> > have higher latency and require extra int<->FP moves. It is possible to
> > mark variants in the MD patterns using '?' to discourage them but that
> > seems like a hack, just like '*'. Is there a general way to say that
> > GENERAL_REGS is preferred over FP_REGS for SI/DI mode?
> MIPS has the same problem here and we have been looking at ways to address
> it purely via costings rather than changing IRA. What we have done so
> far is to make the cost of a move from GENERAL_REGS to FP_REGS more
> expensive than memory if the move has an integer mode. The goal for MIPS
> is to never allocate an FP register to an integer mode unless it was
> absolutely necessary owing to an integer to fp conversion where the
> integer has to be put in an FP register. Ideally I'd like a guarantee
> that FP registers will never be used unless a floating point type is
> present in the source but I haven't found a way to do that given the
> FP-int conversion issue requiring SImode to be allowed in FP regs.

I adjusted the costs like that already on AArch64 but while this reduced 
the crazy spilling of integer values to FP registers and visa versa, it 
doesn't fix it completely. However it should not be necessary to lie about
the move cost and use an unrealistically high value to get decent code...

There are other issues in ira-costs that cause preferences to be incorrect:
you'll find that after you increase the move costs that explicit int<->fp
moves start to go via memory due to memory cost being hardcoded as 1 if an
instruction pattern contains 'm' somewhere - oops... I also posted a patch 
that fixes the preference for new registers created by live-range splitting.

> The patch for MIPS is not submitted yet but has eliminated the final
> two uses of FP registers when building the whole Linux kernel with
> hard-float enabled. I am however still not confident enough to say
> you can build integer only code with hard-float and never touch an FP
> register.

Correct, as long as the preference calculations are not correct and there
is no good way to influence the costs reliably, GCC will continue to use
FP registers in cases when it shouldn't. It's obvious that integer
operations should prefer integer registers and FP operations FP registers,
so why is there no easy way to tell GCC?!?

> Since there are multiple architectures suffering from this I guess we
> should look at properly addressing it in generic code.



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