You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Use CopyLogical to further defer storage-to-logical translation when emitting SPIRV. (#8819)
In #8526, we implemented an
optimization that defers translation to end of access chains from
strorage type to logical type until a leaf logical value is needed.
Upon seeing:
```
mutablePtr : ptr<SomeStorageType> = ...
t = translateStorageToLogical(mutablePtr);
result = load(t)
```
We will create a local var to hold the result of the load, but defer the
conversion logic from storage type to logical type past the load, so we
translate the code into:
```
var tmp;
v = load(mutablePtr)
store(tmp, v);
result = translateStorageToLogicalDeref(tmp)
...
```
So that after this translation, we can continue pushing the
`translateStorageToLogicalDeref` to the users of the `result`.
Unfortunately, this translation breaks a vulkan-spirv validation rule:
because `tmp` will have `SomeStorageType`, which is a type that has
explicit layout, it cannot be used to declare a local variable in the
`Function` address space.
Due to this, we rolled back this optimization and stop deferring
storage-to-logical conversion past the loads from mutable locations in
#8752.
In this PR, we re-enables the deferring logic, by translating into the
following code instead:
```
var tmp : Ptr<SomeStorageType_logical>;
// load from `mutablePtr`, convert it from SomeStorageType
// to SomeStorageType_logical, and write to `tmp`.
copyLogical(tmp, mutablePtr)
result = translateStorageToLogicalDeref(tmp)
```
Where `SomeStorageType_logical` is a clone of `SomeStorageType` that is
the same in all aspects, except that `SomeStorageType_logical` does not
have a `PhysicalType` decoration and won't be emitted with explicit
layouts when emitting SPIRV. This means that `SomeStorageType_logical`
is still a "storage type" in Slang's terminology (since `bool` are
represented as `uint32_t`, `float4x4` is still represented in a
`_MatrixStorage_float_4x4` struct), but is a "logical" type in SPIRV
terminology because it does not have explicit offsets or array strides.
The `copyLogical` inst can be implemented by the `OpCopyLogical` in
SPIRV 1.4.
When emitting code for older SPIRV versions, we will run a dedicated
pass to convert the `copyLogical` into recursive
field-by-field/element-by-element copies.
Using SPIRV's `CopyLogical` allow us to generate cleaner code that has
higher chance of being optimized out by the driver.
Part of #8652.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
0 commit comments