The SPIR-V optimiser spirv-opt is able to optimise a SPIR-V module containing simple and identical duplicate branches. With the use of the --if-conversion, --eliminate-dead-code-aggressive, and --merge-blocks options, the duplicate branches will be removed.
If instead the branches were not completely identical but rather only shared some number of identical instructions, then the module could be similarly optimised by removing the duplicate instructions and inserting them before the branching occurs. However, spirv-opt appears to be unable to do this.
The following is the assembly of a SPIR-V module containing a compute shading stage entry point function.
The module's entry point functionally does the following (pseudocode).
UINT x = global invocation ID
IF x is even
x = x + 1
x = x << 1
ELSE
x = x + 1
x = x >> 1
ENDIF
STORE x
Both branches begin with OpIAdd %uint %2 %uint_1 (x = x + 1), meaning it will be executed in all possible structured control-flow paths, making it a duplicate instruction. The module can therefore be optimised by merging these duplicate instructions before the branch and merge instructions. However, no option provided by spirv-opt seems to be able to achieve this optimisation. Numerous potentially relevant options were tested, including -O, -Os, --local-redundancy-elimination, --loop-invariant-code-motion, --strength-reduction, etc.
As such, it will likely be beneficial either to add this optimisation to an existing option, such as --redundancy-elimination, or to add a new option for this optimisation, such as --branch-redundancy-elimination.
All utilised SPIR-V tools used SPIR-V 1.6, and gave the following --version.
The SPIR-V optimiser
spirv-opt
is able to optimise a SPIR-V module containing simple and identical duplicate branches. With the use of the--if-conversion
,--eliminate-dead-code-aggressive
, and--merge-blocks
options, the duplicate branches will be removed.If instead the branches were not completely identical but rather only shared some number of identical instructions, then the module could be similarly optimised by removing the duplicate instructions and inserting them before the branching occurs. However,
spirv-opt
appears to be unable to do this.The following is the assembly of a SPIR-V module containing a compute shading stage entry point function.
The module's entry point functionally does the following (pseudocode).
Both branches begin with
OpIAdd %uint %2 %uint_1
(x = x + 1
), meaning it will be executed in all possible structured control-flow paths, making it a duplicate instruction. The module can therefore be optimised by merging these duplicate instructions before the branch and merge instructions. However, no option provided byspirv-opt
seems to be able to achieve this optimisation. Numerous potentially relevant options were tested, including-O
,-Os
,--local-redundancy-elimination
,--loop-invariant-code-motion
,--strength-reduction
, etc.As such, it will likely be beneficial either to add this optimisation to an existing option, such as
--redundancy-elimination
, or to add a new option for this optimisation, such as--branch-redundancy-elimination
.All utilised SPIR-V tools used SPIR-V 1.6, and gave the following
--version
.