Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[naga spv-out] Loop bounding probably shouldn't use local variables #7116

Open
jimblandy opened this issue Feb 12, 2025 · 1 comment
Open
Labels
area: naga back-end Outputs of naga shader conversion kind: refactor Making existing function faster or nicer lang: SPIR-V Vulkan's Shading Language naga Shader Translator

Comments

@jimblandy
Copy link
Member

(This is a pre-emptive follow-up issue for #7080, not yet landed.)

Because unbounded loops are undefined behavior in SPIR-V, #7080 changes Naga's SPIR-V backend to make all loops bounded by an injected counter that allows only ~2^64 iterations, introducing new OpVariable local variables to serve as the counters.

However, SPIR-V's SSA form allows us to express such counters using no local variables at all, and this form might be more digestible to optimizers and code generators. Here's a complete SPIR-V module that passes spirv-val validation and does a loop from 0 to 1000 without any local variables. The trick is that the OpPhi instruction selects either the initial value of the counter, when we enter the loop header for the first time, or the incremented value of the counter, when we enter the loop header from a prior iteration.

                 OpCapability Shader
                 OpCapability Linkage
                 OpMemoryModel Logical GLSL450
         %void = OpTypeVoid               
          %int = OpTypeInt 32 1
         %bool = OpTypeBool
         %zero = OpConstantNull %int
          %one = OpConstant %int 1
        %limit = OpConstant %int 1000

      %fn_void = OpTypeFunction %void
            %f = OpFunction %void None %fn_void
     %prologue = OpLabel
                 OpBranch %loop_header

  %loop_header = OpLabel
      %counter = OpPhi %int %zero %prologue %next_counter %loop_continue
         %cond = OpSLessThan %bool %counter %limit
                 OpLoopMerge %loop_merge %loop_continue None
                 OpBranchConditional %cond %loop_body %loop_merge

    %loop_body = OpLabel
                 OpBranch %loop_continue

%loop_continue = OpLabel
 %next_counter = OpIAdd %int %counter %one
                 OpBranch %loop_header

   %loop_merge = OpLabel
                 OpReturn
                 OpFunctionEnd

I don't know that this would really make any difference, which is why I'm filing it as a separate issue, prioritized as a "refactor". But it is nice that we can do this without introducing new local variables, and I think the code is a bit shorter.

@jimblandy jimblandy added area: naga back-end Outputs of naga shader conversion kind: refactor Making existing function faster or nicer lang: SPIR-V Vulkan's Shading Language naga Shader Translator labels Feb 12, 2025
@jimblandy
Copy link
Member Author

cc @jamienicol Just for fun - this is not a priority for Firefox WebGPU.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: naga back-end Outputs of naga shader conversion kind: refactor Making existing function faster or nicer lang: SPIR-V Vulkan's Shading Language naga Shader Translator
Projects
Status: Todo
Development

No branches or pull requests

1 participant