[RFC] optabs and tree-codes for vector operations
Richard Henderson
rth@redhat.com
Sun Aug 29 22:30:00 GMT 2004
> - "storefloor":
> optab: store_floor_optab
Which is exactly what I was trying to avoid -- two separate sets of optabs.
> Can the builtin be encapsulated within REALIGN_LOAD_EXPR
> ? i.e - have a REALIGN_LOAD_EXPR(v1,v2,addr) that on some targets will be
> expanded to {x=builtin(addr),smthing(v1,v2,x)} and on other targets will be
> expanded directly to {smthing(v1,v2,addr)}?
No. Gimple doesn't work that way.
> Is there an added value for
> exposing it to the vectorizer (for example, could it be used to indicate
> whether the REALIGN_LOAD_EXPR allows software-pipelining when the alignment
> is unknown?)
It'll be much harder to reduce the register pressure by one after the fact.
> If we only care about the low bits of the address we could pass an offset
> rather than an address.
Yes, we could, but again, the whole point is to use one register for both
address and "magic", rather than two registers.
> Do we assume anything about the address - e.g. - is
> the address assumed to be not aligned, or have a known constant
> misalignment?
No.
> The real assumption is not that the data was loaded sequentially from
> memory, but that this utility concatenates the last VS - OFF elements from
> vect1 to the first OFF elements of vect2, right?
Yes.
> Do the semantics of REALIGN_LOAD_EXPR imply that (if it is supported) we
> can always generate the following, for a load from unaligned address addr:
>
> vect1=loadfloor(addr)
> vect2=loadfloor(addr+d)
> vect3=REALIGN_LOAD_EXPR(vect1,vect2,addr)?
Yes.
> How would the vectorizer know if it can software pipeline the first
> loadfloor?
That has nothing to do with the semantics of REALIGN_LOAD_EXPR.
> My thinking was
> that there's no point in breaking the unaligned load into a sequence of
> {loadfloor;loadfloor;REALIGN_LOAD_EXPR} during vectorization if
> REALIGN_LOAD_EXPR doesn't allow software-pipelining. Because then the
> vectorizer has to keep the sequence intact, and it may as well generate a
> "load_from_arbitrary_address" (a LOADU_EXPR or whatever representation
> we'll agree on):
That's true.
I may have lied to you too. I *think* by not splitting up
REALIGN_LOAD_EXPR into separate pieces, you get the right
answer on Alpha as well.
So ignore the pipeline-only-if-misaligned case. It'll either
work, or we'll advertise unaligned load/store only.
> Does this operation encapsulate a store in it, or are we going to use it as
> follows:
> v3 = REALIGN_STORE_EXPR (vect1, vect2, addr)
> storefloor (v3, addr) ?
I was thinking this.
> I assume that REALIGN_STORE_EXPR can take arbitrary vect1 and vect2, and
> that it concatenates last OFF elements of vect1 to first VS - OFF elements
> of vect2 (where OFF is the misalignment of addr); right? (i.e, the only
> difference between REALIGN_LOAD_EXPR and REALIGN_STORE_EXPR is this
> reversing).
Yes.
> To summarize, the suggested building blocks of misalignment support are
> for loads: loadfloor + realign_load, or "load_from_arbitrary_address".
> for stores: realign_store + storefloor, or "store_to_arbitrary_address".
Except for the realigns, I think we can use the same optabs for load
and store.
> [store-scheme2]: (optimized)
> 1. t1 = computation
> 2. x = loadfloor (addr)
> 3. x' = REALIGN_LOAD_EXPR (dontcare, x, addr)
> 4. z = REALIGN_STORE_EXPR (x', t1, addr)
> 5. storefloor (z, addr)
> 6. addr+=VS
> loop_start (iterates one iteration less than original loop)
> 7. t2 = computation
> 8. z = REALIGN_STORE_EXPR (t1, t2, addr)
> 9. storefloor (z, addr) // (part of t2 stored in next iter)
> 10. addr+=VS
> 11. t1 = t2
> loop_end
> 12. y = loadfloor (addr)
> 13. y' = REALIGN_LOAD_EXPR (y, dontcare, addr)
> 14. z = REALIGN_STORE_EXPR (t2, y', addr)
> 15. storefloor (z, addr)
Sure. I don't know that you necessarily need to pull out the first
computation round.
x = loadfloor(addr)
t1 = REALIGN_LOAD_EXPR (dontcare, x, addr)
loop {
t2 = computation
z = REALIGN_STORE_EXPR (t1, t2, addr)
storefloor (z, addr)
addr += size
t1 = t2
}
y = loadfloor(addr)
t2 = REALIGN_LOAD_EXPR (y, dontcare, addr)
z = REALIGN_STORE_EXPR (t1, t2, addr)
storefloor (z, addr)
We probably wanto to use zero for dontcare. In some cases the target
may be able to use a shorter sequence when it detects that case.
> Maybe instead we can consider adding the following tree-code:
> MISALIGNED_INDIRECT_REF <pointer, mis>
> which will be used like the ALIGN_INDIRECT_REF you suggested, as the
> operand of a MODIFY_EXPR. 'mis' will be an integer_cst with value -1 if the
> alignment of the pointer is unknown, and otherwise will hold the alignment
> of the pointer. ?
That might work. Adding it at the same time as ALIGN_INDIRECT_REF
wouldn't increase the workload any.
r~
More information about the Gcc
mailing list