Hi,
On 11/11/21 12:14, Matteo Bruni wrote:
Notice that variables can have more than four components. Matrices can have up to 16 and arrays even more.
Right, but we probably don't want or need to do copy propagation on those i.e. copy propagation should probably happen after matrix / struct / array splitting.
Mmh, then there is something about splitting that I'm not understanding.
My understanding so far was that variables themselves are not splitted: they are just there, and do not appear in the code as themselves. What gets splitted are the temporaries that appear when some piece of code actually does something with (say) a matrix. So, for example, if you have this fragment of code:
--- float4x4 a; float4x4 b; float4x4 c; c = a + b; ---
the compile first naively represents it as:
--- float4x4 a float4x4 b float4x4 c @1 = load(a) of type float4x4 @2 = load(b) of type float4x4 @3 = + (@1 @2) of type float4x4 store(c, @3) ---
and then this gets splitted as:
--- float4x4 a float4x4 b float4x4 c @1 = load(a, 0) of type float4 @2 = load(b, 0) of type float4 @3 = + (@1 @2) of type float4 store(c, 0, @3) @5 = load(a, 4) of type float4 @6 = load(b, 4) of type float4 @7 = + (@5 @6) of type float4 store(c, 4, @7) ... ---
That is, the variables keep their type, even though the accesses (loads and stores) to the variables have a smaller type. That's my understanding of what we want. My code mirrors this, therefore allows a variable to have more than four registers.
What is the advantage of splitting variables themselves?
In the specific case of my copy propagation pass, this would make things more complicated. For example, if right now I cannot reconstruct the offset of a store, I can just invalidate the whole variable. In your model, as I get it, I'd have to also invalidate other variables, that are unrelated by that point.
Thanks, Giovanni.