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 within SwitchCases that sets an introduced bool local to true and does a break, jumping to immediately after the generated switch.

  • When generating code for a Switch statement, we conservatively assume it might contain such a Continue statement, so:

    • If it’s the outermost such Switch within a Loop, we declare the bool local ahead of the switch, initialized to false. Immediately after the switch, we check the local and do a continue if it’s set.

    • If the Switch is nested within other Switches, then after the generated switch, we check the local (which we know was declared before the surrounding switch) and do a break if it’s set.

    • As an optimization, we only generate the check of the local if a Continue statement is encountered within the Switch. This may help drivers more easily identify that the bool 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.

Enums§

  • A micro-IR for code a backend should generate after a Switch.
  • Nesting 🔒
    A summary of the code surrounding a statement.