Create a new optimization pass, strength reduction, which will replace
integer multiplication by a constant power of 2 with an equivalent bit
shift. More changes could be added later.
- Does not duplicate constants
- Adds vector |Concat| utility function to a common test header.
Only inline calls to functions with opaque params or return
TODO: Handle parameter type or return type where the opqaue
type is buried within an array.
- UniformElim: Only process reachable blocks
- UniformElim: Don't reuse loads of samplers and images across blocks.
Added a second phase which only reuses loads within a block for samplers
and images.
- UniformElim: Upgrade CopyObject skipping in GetPtr
- UniformElim: Add extensions whitelist
Currently disallowing SPV_KHR_variable_pointers because it doesn't
handle extended pointer forms.
- UniformElim: Do not process shaders with GroupDecorate
- UniformElim: Bail on shaders with non-32-bit ints.
- UniformElim: Document support for only single index and add TODO.
Create aggressive dead code elimination pass
This pass eliminates unused code from functions. In addition,
it detects and eliminates code which may have spurious uses but which do
not contribute to the output of the function. The most common cause of
such code sequences is summations in loops whose result is no longer used
due to dead code elimination. This optimization has additional compile
time cost over standard dead code elimination.
This pass only processes entry point functions. It also only processes
shaders with logical addressing. It currently will not process functions
with function calls. It currently only supports the GLSL.std.450 extended
instruction set. It currently does not support any extensions.
This pass will be made more effective by first running passes that remove
dead control flow and inlines function calls.
This pass can be especially useful after running Local Access Chain
Conversion, which tends to cause cycles of dead code to be left after
Store/Load elimination passes are completed. These cycles cannot be
eliminated with standard dead code elimination.
Additionally: This transform uses a whitelist of instructions that it
knows do have side effects, (a.k.a. combinators). It assumes other
instructions have side effects: it will not remove them, and assumes
they have side effects via their ID operands.
A SSA local variable load/store elimination pass.
For every entry point function, eliminate all loads and stores of function
scope variables only referenced with non-access-chain loads and stores.
Eliminate the variables as well.
The presence of access chain references and function calls can inhibit
the above optimization.
Only shader modules with logical addressing are currently processed.
Currently modules with any extensions enabled are not processed. This
is left for future work.
This pass is most effective if preceeded by Inlining and
LocalAccessChainConvert. LocalSingleStoreElim and LocalSingleBlockElim
will reduce the work that this pass has to do.
Add --flatten-decorations to spirv-opt
Flattens decoration groups. That is, replace OpDecorationGroup
and its uses in OpGroupDecorate and OpGroupMemberDecorate with
ordinary OpDecorate and OpMemberDecorate instructions.
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/602
Exercises our public APIs more, and avoid including most
internal headers. It also shortens the processing part
of the code, but does make adding passes look more complex.
Doing this exposed issue 611, a bug in spvtools::Optimizer.
Default-constructed Pass/PassManager will have a MessageConsumer
which ignores all messages. SetMessageConsumer() should be called
to supply a meaningful MessageConsumer.
De-duplicate constants and unifies the uses of constants for a SPIR-V
module. If two constants are defined exactly the same, only one of them
will be kept and all the uses of the removed constant will be redirected
to the kept one.
This pass handles normal constants (defined with
OpConstant{|True|False|Composite}), some spec constants (those defined
with OpSpecConstant{Op|Composite}) and null constants (defined with
OpConstantNull).
There are several cases not handled by this pass:
1) If there are decorations for the result id of a constant defining
instruction, that instruction will not be processed. This means the
instruction won't be used to replace other instructions and other
instructions won't be used to replace it either.
2) This pass does not unify null constants (defined with
OpConstantNull instruction) with their equivalent zero-valued normal
constants (defined with OpConstant{|False|Composite} with zero as the
operand values or component values).
For the spec constants defined by OpSpecConstantOp and
OpSpecContantComposite, if all of their operands are constants with
determined values (normal constants whose values are fixed), calculate
the correct values of the spec constants and re-define them as normal
constants.
In short, this pass replaces all the spec constants defined by
OpSpecContantOp and OpSpecConstantComposite with normal constants when
possible. So far not all valid operations of OpSpecConstantOp are
supported, we have several constriction here:
1) Only 32-bit integer and boolean (both scalar and vector) are
supported for any arithmetic operations. Integers in other width (like
64-bit) are not supported.
2) OpSConvert, OpFConvert, OpQuantizeToF16, and all the
operations under Kernel capability, are not supported.
3) OpCompositeInsert is not supported.
Note that this pass does not unify normal constants. This means it is
possible to have new generatd constants defining the same values.
Add a pass to freeze spec constants to their default values. This pass does
not fold the frozen spec constants and does not handle SpecConstantOp
instructions and SpecConstantComposite instructions.