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]

Re: hard register reload patch


> > I suggest we keep the rules simple and easy to understand: the only insns
> > which reference hard registers may be moves which copy them into/out of
> > pseudos.
> 
> This is muddy, too.  What is a copy?  On some hardware, signe and/or zero
> extension is part of a move insn.

But not in a move insn between a hard reg and a pseudo of the same mode.

> And yet this rule is too strict because it would disallow using a hard
> register where one is naturally used - where you have and insn that
> can take only one particular register as one of its inputs.  If you accept
> a pseudo in this place, cse/gcse/loop/combine get taken away and create
> code that would need dozens of these one-of-a-kind registers to be live
> simulatanously to avoid lots of reloads.

I can only repeat myself here: I believe you get the same problem if you use
explicit hard register references.

Suppose you have

    (set (reg 22) (... some input ...))

on a SMALL_REGISTER_CLASSES machine.  You need to copy the value out of
reg 22 and into a pseudo as soon as possible.  This means you'll actually
have code that does

    (set (reg 22) (...))
    (set (pseudo X) (reg 22))

Now, if you avoid the explicit hard register reference, you'll have

    (set (pseudo X) (... some input ...))

The output operand will only accept a single register.  In both pieces of
code, the value will not actually live in reg 22 for very long, it will be
copied to pseudo X.  There are two possibilities: either pseudo X is
allocated to reg 22, or it isn't.  In both cases, the generated code should
end up looking the same.  In the first piece of code we did the "output
reload" by hand (it turns into a noop and gets deleted if register allocation
is lucky), and in the second piece of code we would need to generate a
reload.

This is the simple case, where there's only one such insn.  Now consider the
case where we have more than one such insn.  Say the pseudos involved are X
and Y.  Your concern seems to be: what happens if an optimizer makes X and Y
live at the same time?  I believe we get the same end result again.  What
stops the optimizer from enlarging the lifetimes of X and Y in the case where
you have explicit hard register references?  I think there's no reason why
this can't happen.  If it does happen, the task for the register allocators
and reload is the same in both alternatives: allocate X and Y to registers
other than 22, and generate insns copying them out of the register.  The only
difference is who generates the copying insns: either the machine
description (when using explicit hard register references), or reload.

There is one issue which I already mentioned when this originally came up:
in the second alternative, the register allocator will not see that X and Y
conflict with reg 22.  So it might try to allocate one of them to reg 22.
We will spill it, but we should be able to find another hard reg to allocate.
[If not, then some other pseudo must have gotten a hard reg that otherwise
wouldn't have].  I can believe, however, that this mechanism doesn't always
generate optimal results, but it appears to be a deficiency in the register
allocators rather than in reload (or the optimizers).

I'm willing to be proven wrong here if you can point out a glaring error in
my reasoning.  However, as I mentioned, I didn't see any effect on the
average code quality with the testsuite from [our customer].

> >           Hard registers may not live across any other insns.
> 
> They have to - otherwise you can't have function calls which take more than
> one parameter in registers.

Sequences of multiple such hard register loads are obviously OK.  I'm talking
about any other insns.

> > To me, this appears to be what was originally intended, but it's not how all
> > parts of the compiler behave these days.  [I have an unreviewed combiner
> > patch (~ 10 months old) which tries to replace the (convoluted) logic dealing
> > with hard regs and SMALL_REGISTER_CLASSES with code that just enforces these
> > rules.  This patch fixes two compiler aborts when compiling the Linux kernel
> > with -mregparm on the i386.]
> 
> Are these aborts becasue the reload runs out of spill registers?  I suppose
> by patch could fix these problems, too.

Yup, it probably would fix these two cases.  I'm not convinced, however, that
the combiner won't ever extend hard reg lifetimes across an insn that
requires a reload in a single-register class.  If it does, we'll lose
(eventually).

> Moreover, I am not certain that the code you used is sufficiently
> representative of performance and size critical code on the SH to
> make the meansurements meaningful.

I thought it explicitly contained the code where our customer cares about
the code quality?

> > I'd like to see all the RELOAD_FOR_xxx codes go away.  I've got half-done
> > patches to scan the rtl for replacements and thus build a definition/use
> > chain for reloads which should enable us to schedule them precisely with
> > much simpler code than reload_reg_free_xxx/reloads_conflict/etc.  But I'll
> > leave that discussion for another occasion 8)
> 
> How about this: send me a copy now.  If I think it makes sense, I'll see
> how it'll integrate with my patch - then we need not worry to document stuff
> that is going away anyways.  If not, we can discuss it separately.

Give me a few days.  This code is half a year old and doesn't have a chance
of applying to the current tree.  It won't be useful for your patch, I think;
it is very much experimental code and doesn't have the necessary quality to
go into the tree at this point.  It did pass "make check" once on the i386,
but it needs lots of work, even fixing one or two design errors.

Bernd


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