Expand description
Workarounds for platform bugs and limitations in switches and loops.
In these docs, we use CamelCase links for Naga IR concepts, and ordinary
code formatting for HLSL or GLSL concepts.
§Avoiding continue within switch
As described in https://github.com/gfx-rs/wgpu/issues/4485, the FXC HLSL
compiler doesn’t allow continue statements within switch statements, but
Naga IR does. We work around this by introducing synthetic boolean local
variables and branches.
Specifically:
- 
We generate code for
Continuestatements withinSwitchCases that sets an introducedboollocal totrueand does abreak, jumping to immediately after the generatedswitch. - 
When generating code for a
Switchstatement, we conservatively assume it might contain such aContinuestatement, so:- 
If it’s the outermost such
Switchwithin aLoop, we declare theboollocal ahead of the switch, initialized tofalse. Immediately after theswitch, we check the local and do acontinueif it’s set. - 
If the
Switchis nested within otherSwitches, then after the generatedswitch, we check the local (which we know was declared before the surroundingswitch) and do abreakif it’s set. - 
As an optimization, we only generate the check of the local if a
Continuestatement is encountered within theSwitch. This may help drivers more easily identify that theboolis unused. 
 - 
 
So while we “weaken” the Continue statement by rendering it as a break
statement, we also place checks immediately at the locations to which those
break statements will jump, until we can be sure we’ve reached the
intended target of the original Continue.
In the case of nested Loop and Switch statements, there may be
multiple introduced bool locals in scope, but there’s no problem knowing
which one to operate on. At any point, there is at most one Loop
statement that could be targeted by a Continue statement, so the correct
bool local to set and test is always the one introduced for the innermost
enclosing Loop’s outermost Switch.
§Avoiding single body switch statements
As described in https://github.com/gfx-rs/wgpu/issues/4514, some language
front ends miscompile switch statements where all cases branch to the same
body. Our HLSL and GLSL backends render Switch statements with a single
SwitchCase as do {} while(false); loops.
However, this rewriting introduces a new loop that could “capture”
continue statements in its body. To avoid doing so, we apply the
Continue-to-break transformation described above.
Structs§
- Continue
Ctx 🔒 - Utility for tracking nesting of loops and switches to orchestrate forwarding of continue statements inside of a switch to the enclosing loop.
 
Enums§
- Exit
Control 🔒Flow  - A micro-IR for code a backend should generate after a 
Switch. - Nesting 🔒
 - A summary of the code surrounding a statement.