This is the mail archive of the
mailing list for the GCC project.
Re: Code bloat due to silly IRA cost model?
Segher Boessenkool <email@example.com> writes:
> On Fri, Dec 13, 2019 at 04:22:11PM +0000, Richard Sandiford wrote:
>> Segher Boessenkool <firstname.lastname@example.org> writes:
>> > On Fri, Dec 13, 2019 at 12:45:47PM +0000, Richard Sandiford wrote:
>> >> combine's to blame for the fact that we have two pseudo registers rather
>> >> than one. See the comments about the avr-elf results in:
>> >> https://gcc.gnu.org/ml/gcc-patches/2019-11/msg02150.html
>> >> for more details.
>> > It's not combine's fault if register allocation does a bad job. And we
>> > should *not* generate worse code in combine just because it exposes a
>> > problem in RA (with 2-2 and make_more_copies we generate better code on
>> > average, on all targets I tested, 50 or so).
>> > If having two pseudos here is not an advantage, then RA should optimise
>> > one away. It does usually, why not here?
>> I didn't say it was combine's fault that RA was bad. I said it was
>> combine's fault that we have two pseudos rather than one.
> But that is not a fault, that is on purpose.
> Before this change, combine would forward hard registers into pseudos
> greedily. RA can do a better job than that.
I don't think anyone's disputing that. You quoted the initial text
above out of context. Johann had asked why the RA even needed to do
anything for the posted testcase, where we have the equivalent of
"foo (bar ())", bar returns a value in register X and foo takes an
argument in register X. I was trying to explain that we still need:
(set pseudo X)
(set X pseudo)
in order to avoid spill failures in all but trivial cases, and that we
rely on the RA to make a good allocation choice for the pseudo. So I
think what you said above is basically explaining back to me what I'd
said in the context that was snipped.
But we only need one temporary pseudo register to avoid the spill
failures, whereas in Johann's case the RA sees two:
(set pseudo2 X)
(set pseudo pseudo2)
(set X pseudo2)
My point was the extra pseudo<-pseudo2 move is created by combine for
its own internal purposes and pseudo2 isn't something *the RA* needs to
avoid spill failures. But in this case combine fails to fold the extra
move with anything and so the move "leaks out" to later passes, including
RA. The snipped context linked to the message where we'd discussed this,
including why combine fails to restore the original X<-pseudo<-X chain
for avr-elf. It also shows that avr-elf code improved significantly
if we *did* restore that original chain (which the new combine pass
happened to do, although that just fell out in the wash rather than
being a specific aim).
In a perfect world, we could keep adding more and more pseudos to a
move chain without affecting the output of the RA. But it's not too
surprising if that isn't always true in practice. After all, the
point of adding pseudo2 in the first place is that *combine* handles
pseudo<-pseudo2<-X differently from just pseudo<-X. ;-)
> If you found a case where
> RA does not do a good job, let's fix that?
> (And combine does get rid of two pseudos, if that is a good idea to do.
> If instructions do not properly combine, it can not, of course).