On Thu, Jul 08, 2021 at 08:26:45PM -0500, Peter Bergner wrote:
> On 7/8/21 6:28 PM, Segher Boessenkool wrote:
> >>          int index = WORDS_BIG_ENDIAN ? i : nvecs - 1 - i;
> >> -        rtx dst_i = gen_rtx_REG (reg_mode, reg + index);
> >> -        emit_insn (gen_rtx_SET (dst_i, XVECEXP (src, 0, i)));
> >> +        int index_next = WORDS_BIG_ENDIAN ? index + 1 : index - 1;
> > 
> > What does index_next mean?  The machine instructions do the same thing
> > in any endianness.
> 
> Yeah, I'm bad at coming up with names! :-)   So "index" is the index
> into XVECEXP (src, 0, ...) which is the operand that is to be assigned
> to regno.  "index_next" is the index into XVECEXP (src, 0, ...) which is
> the operand to be assigned to regno + 1 (ie, the next register of the
> even/odd register pair).  Whether the "next index" is index+1 or index-1
> is dependent on LE versus BE.

I would just call it "index1", or even "j" and "k" instead of "index"
and "index_next" :-)  "next" can put people on the wrong track (it did
me :-) )

> >> +        /* If we are loading an even VSX register and our memory location
> >> +           is adjacent to the next register's memory location (if any),
> >> +           then we can load them both with one LXVP instruction.  */
> >> +        if ((regno & 1) == 0
> >> +            && VSX_REGNO_P (regno)
> >> +            && MEM_P (XVECEXP (src, 0, index))
> >> +            && MEM_P (XVECEXP (src, 0, index_next)))
> >> +          {
> >> +            rtx base = WORDS_BIG_ENDIAN ? XVECEXP (src, 0, index)
> >> +                                        : XVECEXP (src, 0, index_next);
> >> +            rtx next = WORDS_BIG_ENDIAN ? XVECEXP (src, 0, index_next)
> >> +                                        : XVECEXP (src, 0, index);
> > 
> > Please get rid of index_next, if you still have to do different code for
> > LE here -- it doesn't make the code any clearer (in fact I cannot follow
> > it at all anymore :-( )
> 
> We do need different code for LE versus BE.  So you want something like
> 
>   if (WORDS_BIG_ENDIAN) {...} else {...}
> 
> ...instead?  I can try that to see if the code is easier to read.

Yes exactly.  It will more directly say what it does, and there is no
"index_next" abstraction the reader has to absorb first.

> > So this converts pairs of lxv to an lxvp in only a very limited case,
> > right?  Can we instead do it more generically?  And what about stxvp?
> 
> Doing it more generically is my next TODO and that will cover both
> lxvp and stxvp.

Ah cool :-)

> My thought was to write a simple pass run at about
> the same time as our swap optimization pass to look for adjacent
> lxv's and stxv's and convert them into lxvp and stxvp.

So, very early, as soon as DF is set up.  Makes sense.

> However, that
> won't catch the above case, since the assemble/build pattern is not
> split until very late, so we still want the above change.

You probably should also have a peephole (whether you do it like here or
not :-) )

> Also, given the new pass will be more complicated than the above code,
> it will be a GCC 12 only change.

/nod

> Let me make the changes you want and I'll repost with what I come up with.

Thanks!  And thanks for the explanation.


Segher

Reply via email to