On 5/17/22 08:21, Giovanni Mascellani wrote:
Hi,
Il 16/05/22 19:42, Zebediah Figura ha scritto:
In principle we could do the same processing each time we add any cast, explicit or not, but that means we have to hook in many places, making everything more brittle.
Would it be many places, though? I think it'd only be the explicit cast parsing rule and add_implicit_conversion(). We'd want a helper function anyway, that wraps hlsl_new_cast() and handles scalar-to-structure casts.
Whatever number they are, it is at least a few places versus just one well-defined place. Also, in the latter case the place is always the same (it would be one of the first optimization passes), while in the former case the places where you need to take care of this might change with time, further complicating a piece of code (the front end) which is already rather involved in itself. The optimization passes have a much nicer structure, it's just a pipeline for which hlsl_emit_bytecode() gives a quick and readable summary.
On the one hand, yes, but it comes at the cost of making the IR more complicated. That complexity may not always be reflected in the structures used to encode it, but it's a mental burden to consider "what is it legal to express in IR at what point in execution?"
In some cases, like this, it doesn't really make a difference either way, but then I also don't see a reason to perform a lowering pass instead of emitting the code already lowered. With the use of helper functions I have a hard time conceiving of that lowering as happening in any more than one place.
What's the problem with having this as an optimization pass? Why is that different from lower_broadcasts()?
Broadly, it's the principle of making the IR as simple as possible. In this case it's especially helpful to be able to assume that types larger than a vector can only be generated by HLSL_IR_LOAD instructions. But I think it'd also be desirable to handle scalar-to-vector broadcasts at parse time; I just didn't consider that when writing the pass.
If the first few passes care about ensuring the invariants that we want in later "real" passes then we get both the advantages of having a simpler IR (except in the first few stages, but that's doesn't look like a huge drawback) and giving an easier-to-read structure to the compiler without overloading the front end.
But I already tried to convince you and Matteo of this and I didn't manage, so I guess I'll withdraw.
Giovanni.