Skip to content

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

Open
@jimblandy

Description

@jimblandy

(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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: naga back-endOutputs of naga shader conversionkind: refactorMaking existing function faster or nicerlang: SPIR-VVulkan's Shading LanguagenagaShader Translator

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions