Module naga::back::continue_forward
source · 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
Continue
statements withinSwitchCase
s that sets an introducedbool
local totrue
and does abreak
, jumping to immediately after the generatedswitch
. -
When generating code for a
Switch
statement, we conservatively assume it might contain such aContinue
statement, so:-
If it’s the outermost such
Switch
within aLoop
, we declare thebool
local ahead of the switch, initialized tofalse
. Immediately after theswitch
, we check the local and do acontinue
if it’s set. -
If the
Switch
is nested within otherSwitch
es, then after the generatedswitch
, we check the local (which we know was declared before the surroundingswitch
) and do abreak
if it’s set. -
As an optimization, we only generate the check of the local if a
Continue
statement is encountered within theSwitch
. This may help drivers more easily identify that thebool
is 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§
- Utility for tracking nesting of loops and switches to orchestrate forwarding of continue statements inside of a switch to the enclosing loop.