spv/lift: elide empty targets of an if
-else
/switch
, as allowed by SPIR-V.
#28
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
SPIR-V allows what it calls "merge edges" (edges from a structured header block, to its merge block), e.g.:
can directly use the merge block as the "else" edge of the conditional branch:
but before this PR, SPIR-T -> SPIR-V lifting was not taking advantage of that, instead emitting:
This pattern became most obvious on Rust-GPU shaders with a lot of panics from e.g. bounds-checking (which get turned into conditional "
OpReturn
from entry point"), but not from inspecting the SPIR-V output.Instead, I ended up noticing that
spirv-opt
has amerge-blocks
pass, which can remove the slight inefficiency from situations like the above example, but it's very slow for what it does (and it was the slowest pass inspirv-opt --time-report
, for the SPIR-V module I was looking at).(if linear, that would mean around 200µs per trivial basic block, which feels absurd given how simple the check in this PR is, so I suspect it's accidentally quadratic or worse, but I haven't looked at the C++ code to confirm either)
EDIT: with this PR used in Rust-GPU, the specific testcase which prompted it (schell/renderling@d9f4d6f) has the time spent in
spirv-opt
shrink by ~20% (4s
->3.21s
), which is even better than the0.5s
I was expecting.