Commit Graph

94 Commits

Author SHA1 Message Date
Laura Hermanns
951980e5ac
Enable vector constant folding (#4913) (#5272)
- Add test case 6 to UIntVectorInstructionFoldingTest
- Add test case 3 to IntVectorInstructionFoldingTest
2023-06-19 15:01:51 -04:00
Kévin Petit
f4343515ad
Remove duplicate lists of constant and type opcodes (#5106)
Adding a new type instruction required making the same change in two
places.

Also remove IsCompileTimeConstantInst that was used in a single place
and replace its use by an expression that better conveys the intent.

Change-Id: I49330b74bd34a35db6369c438c053224805c18e0

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2023-02-15 20:09:55 +00:00
Nathan Gauër
1a7f71afb4
clean: constexpr-ify and unify anon namespace use (#4991)
Constexpr guaranteed no runtime init in addition to const semantics.
Moving all opt/ to constexpr.
Moving all compile-unit statics to anonymous namespaces to uniformize
the method used (anonymous namespace vs static has the same behavior
here AFAIK).

Signed-off-by: Nathan Gauër <brioche@google.com>
2022-11-17 19:02:50 +01:00
alan-baker
d35a78db57
Switch SPIRV-Tools to use spirv.hpp11 internally (#4981)
Fixes #4960

* Switches to using enum classes with an underlying type to avoid
  undefined behaviour
2022-11-04 17:27:10 -04:00
Spencer Fricke
4386afb057
spirv-opt: Remove unused fold spec const code (#4906) 2022-09-02 16:24:02 +00:00
pd-valve
44923beb52
Optimize Instruction::Instruction (#4705)
Avoid constructing temporary vector + copying operands multiple times.
Add SmallVector(InputIt first, InputIt last), matching std::vector.
2022-02-10 18:31:07 +00:00
Shahbaz Youssefi
7fa9e746ef
Introduce spirv-diff (#4611)
spirv-diff is a new tool that produces diff-style output comparing two
SPIR-V modules.  The instructions between the src and dst modules are
matched as best as the tool can, and output is produced (in src
id-space) that shows which instructions are removed in src, added in dst
or modified between them.  The order of instructions are not retained.

Matching instructions between two SPIR-V modules is not trivial, and
thus a number of heuristics are applied in this tool.  In particular,
without debug information, it's hard to match functions as they can be
reordered.  As such, this tool is primarily useful to produce the diff
of two SPIR-V modules derived from the same source.

This tool can be useful in a number of scenarios:

- Compare the SPIR-V before and after modifying a shader
- Compare the SPIR-V produced from a shader before and after compiler
  codegen changes.
- Compare the SPIR-V produced from a shader before and after some
  transformation or optimization.
- Compare the SPIR-V produced from a shader with different compilers.
2022-02-02 10:33:18 -05:00
luzpaz
65ecfd1093
Fix various source comment (doxygen) typos (#4680)
Found via `codespell -q 3 -L fo,lod,parm
2022-01-26 15:13:08 -05:00
Marius Hillenbrand
1ed847f438
Fix endianness of string literals (#4622)
* Fix endianness of string literals

To get correct and consistent encoding and decoding of string literals
on big-endian platforms, use spvtools::utils::MakeString and MakeVector
(or wrapper functions) consistently for handling string literals.

- add variant of MakeVector that encodes a string literal into an
  existing vector of words
- add variants of MakeString
- add a wrapper spvDecodeLiteralStringOperand in source/
- fix wrapper Operand::AsString to use MakeString (source/opt)
- remove Operand::AsCString as broken and unused
- add a variant of GetOperandAs for string literals (source/val)
... and apply those wrappers throughout the code.

Fixes  #149

* Extend round trip test for StringLiterals to flip word order

In the encoding/decoding roundtrip tests for string literals, include
a case that flips byte order in words after encoding and then checks for
successful decoding. That is, on a little-endian host flip to big-endian
byte order and then decode, and vice versa.

* BinaryParseTest.InstructionWithStringOperand: also flip byte order

Test binary parsing of string operands both with the host's and with the
reversed byte order.
2021-12-08 12:01:26 -05:00
Lukas Hermanns
24476c2e32
spirv-opt: Don't eliminate dead members from StructuredBuffer (#4553)
* Don't eliminate dead members from StructuredBuffer as layout(offset) qualifiers cannot be applied to structure fields.

* Traverse arrays when marking structs as fully used.

Co-authored-by: Steven Perron <stevenperron@google.com>
2021-10-01 08:31:40 -04:00
Greg Fischer
19dc86c48c
Handle NonSemantic.Shader Debug[No]Line (#4530)
Debug[No]Line are tracked and optimized using the same mechanism that tracks
and optimizes Op[No]Line.

Also:
    - Fix missing DebugScope at top of block.
    - Allow scalar replacement of access chain in DebugDeclare
2021-09-24 10:56:08 -04:00
Greg Fischer
1454c95d1b
spirv-opt: Switch from Vulkan.DebugInfo to Shader.DebugInfo (#4493)
Includes:
- Shift to use of spirv-header extinst.nonsemantic.shader grammar.json
- Remove extinst.nonsemantic.vulkan.debuginfo.100.grammar.json
- Enable all optimizations for Shader.DebugInfo

Also fixes scalar replacement to only insert DebugValue after all
OpVariables. This is not necessary for OpenCL.DebugInfo, but it is
for Shader.DebugInfo.

Likewise, fixes Private-to-Local to insert DebugDeclare after all
OpVariables.

Also fixes inlining to handle FunctionDefinition which can show up
after first block if early return processing happens.

Co-authored-by: baldurk <baldurk@baldurk.org>
2021-09-15 14:38:53 -04:00
Greg Fischer
8966cc2b27
Add common enum for debug info instructions from either opencl or vulkan (#4377)
Co-authored-by: baldurk <baldurk@baldurk.org>
2021-07-16 16:28:14 -04:00
dan sinclair
cfa1dadb1e
Update a few virtuals to overrides. (#4143)
These methods are overriding their base class, so switch to override
from virtual.
2021-02-10 13:21:38 -05:00
Ben Clayton
8383bd5d6f
Migrate all Kokoro build scripts over to use the docker VM image (#4114)
* Work around GCC-9 warning treated as error

```
../source/opt/instruction.h:101:23: error: '*((void*)& operand +32)' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  101 |     uint64_t result = uint64_t(words[0]);
```

* Migrate all Kokoro build scripts over to use the docker VM image

Required updating the NDK SDK and build scripts, as well as the check_copyright for handling 2021.
2021-01-18 13:36:26 -05:00
Jaebaek Seo
8a0ebd40f8
Correctly replace debug lexical scope of instruction (#3718)
When we update OpenCL.DebugInfo.100 lexical scopes e.g., DebugFunction,
we have to replace DebugScope of each instruction that uses the lexical
scope correctly.
2020-08-31 10:05:38 -04:00
Jaebaek Seo
e02f178a71
Handle DebugScope in compact-ids pass (#3724)
We have to update OpenCL.DebugInfo.100 DebugScope for instructions if we
change its lexical scope or DebugInlinedAt.
2020-08-26 10:15:36 -04:00
alan-baker
b4c4da3e76
Improve non-semantic instruction handling in the optimizer (#3693)
* No longer blindly add global non-semantic info instructions to global
  types and values
  * functions now have a list of non-semantic instructions that succeed
    them in the global scope
  * global non-semantic instructions go in global types and values if
    they appear before any function, otherwise they are attached to the
    immediate function predecessor in the module
* changed ADCE to use the function removal utility
* Modified EliminateFunction to have special handling for non-semantic
  instructions in the global scope
  * non-semantic instructions are moved to an earlier function (or full
    global set) if the function they are attached to is eliminated
  * Added IRContext::KillNonSemanticInfo to remove the tree of
    non-semantic instructions that use an instruction
  * this is used in function elimination
* There is still significant work in the optimizer to handle
  non-semantic instructions fully in the optimizer
2020-08-13 14:54:14 -04:00
André Perez
3f33a9aa55
spirv-opt: Improve the code of the Instruction class (#3610) 2020-08-05 15:28:05 -04:00
Jaebaek Seo
ebaefda666
Debug info preservation in loop-unroll pass (#3548)
When we copy the loop body to unroll it, we have to copy its
instructions but DebugDeclare or DebugValue used for the declaration
i.e., DebugValue with Deref must not be copied and only the first block
can contain those instructions.
2020-07-30 12:18:06 -04:00
Jaebaek Seo
6a3eb679bd
Preserve debug info in scalar replacement pass (#3461)
1. Set the debug scope and line information for the new replacement
   instructions.
2. Replace DebugDeclare and DebugValue if their OpVariable or value
   operands are replaced by scalars. It uses 'Indexes' operand of
   DebugValue. For example,

   struct S { int a; int b;}
   S foo; // before scalar replacement

   int foo_a; // after scalar replacement
   int foo_b;

   DebugDeclare %dbg_foo %foo %null_expr // before

   DebugValue %dbg_foo %foo_a %Deref_expr 0 // after
   DebugValue %dbg_foo %foo_b %Deref_expr 1 // means Value(foo.members[1]) == Deref(%foo_b)
2020-07-27 13:02:25 -04:00
Jaebaek Seo
f8eddbbe59
Preserve OpenCL.100.DebugInfo in reduce-load-size pass (#3492)
The decision to reduce the load must be not affected by debug
instructions. For example, even when a DebugValue references a
result id of a loaded composite value, this change lets the
reduce-load-size pass reduce the load if the full composite value is not
used anywhere other than the DebugValue.
2020-07-08 16:34:00 -04:00
Jaebaek Seo
6a4da9da42
Debug info preservation in copy-prop-array pass (#3444)
When the pass replaces the local variable `OpVariable` ids to their
corresponding pointers, we have to update operands of DebugValue or
DebugDeclare instructions.
2020-07-06 13:48:12 -04:00
Jaebaek Seo
50b1557886
Preserve debug info in inline pass (#3349)
Handles the OpenCL100Debug extension in inlining.  It preserves the information that is available while also adding the debug inlined at for all of the inlining that it does.
2020-05-21 13:09:43 -04:00
André Perez
a6b0e132ec
Add adjust branch weights transformation (#3336)
In this PR, the classes that represent the adjust branch weights
transformation and fuzzer pass were implemented. This transformation
adjusts the branch weights of a OpBranchConditional instruction.
2020-05-14 11:38:34 +01:00
Jaebaek Seo
c8590c18bd
Preserve debug info for wrap-opkill (#3331)
Preserve debug info for wrap-opkill
2020-05-06 12:57:57 -04:00
Alastair Donaldson
49842b88ee
Generalize IsReadOnlyVariable() to apply to pointers (#3325)
Generalizes the IsReadOnlyVariable() method, and related methods, so
that they can be used to ask whether pointer result ids are read-only.

Fixes #3324.
2020-04-30 22:47:20 +01:00
David Neto
eed48ae479
Add spvtools::opt::Operand::AsLiteralUint64 (#3320) 2020-04-27 09:38:06 -04:00
Jaebaek Seo
000040e707
Preserve debug info in eliminate-dead-functions (#3251)
* Preserve debug info in eliminate-dead-functions

The elimination of dead functions makes OpFunction operand of
DebugFunction invalid. This commit replaces the operand with
DebugInfoNone.
2020-04-13 09:29:36 -04:00
Jaebaek Seo
1c8bda3721
Add data structure for DebugScope, DebugDeclare in spirv-opt (#3183)
When DebugScope is given in SPIR-V, each instruction following the
DebugScope is from the lexical scope pointed by the DebugScope in
the high level language. We add DebugScope struction to keep the
scope information in Instruction class. When ir_loader loads
DebugScope/DebugNoScope, it keeps the scope information in
|last_dbg_scope_| and lets following instructions have that scope
information.

In terms of DebugDeclare/DebugValue, if it is in a function body
but outside of a basic block, we keep it in |debug_insts_in_header_|
of Function class. If it is in a basic block, we keep it as a normal
instruction i.e., in a instruction list of BasicBlock.
2020-03-23 11:01:18 -04:00
David Neto
60104cd974
Add opt::Operand::AsCString and AsString (#3240)
It only works when the operand is a literal string.
2020-03-19 12:44:28 -04:00
Jaebaek Seo
f8d7df760c
Fix OpLine bug of merge-blocks pass (#3130)
As explained in #3118, spirv-opt merge-blocks pass causes a
spirv-val error when an OpBranch has an OpLine in front of it.

OpLoopMerge
OpBranch ; Will be killed by merge-blocks pass
OpLabel  ; Will be killed by merge-blocks pass
OpLine   ; will be placed between OpLoopMerge and OpBranch - error!
OpBranch

To fix this issue, this commit moves line info of OpBranch to
OpLoopMerge.

Fixes #3118
2020-01-14 14:35:21 -05:00
David Neto
31590104ec
Add pass to inject code for robust-buffer-access semantics (#2771)
spirv-opt: Add --graphics-robust-access

Clamps access chain indices so they are always
in bounds.

Assumes:
- Logical addressing mode
- No runtime-array-descriptor-indexing
- No variable pointers

Adds stub code for clamping coordinate and samples
for OpImageTexelPointer.

Adds SinglePassRunAndFail optimizer test fixture.

Android.mk: add source/opt/graphics_robust_access_pass.cpp

Adds Constant::GetSignExtendedValue, Constant::GetZeroExtendedValue
2019-07-30 19:52:46 -04:00
David Neto
76b75c40a1 Document opt::Instruction::InsertBefore methods (#2751) 2019-07-18 11:37:28 -04:00
Alastair Donaldson
3b13040cf9 New spirv-reduce reduction pass: operand to dominating id. (#2099)
* Added a reduction pass to replace ids with ids of the same type that dominate them.
* Introduce helper method for querying whether an operand type is an input id.
2018-11-26 17:06:21 -05:00
greg-lunarg
e545564887 Consider atomics that load when analyzing live stores in ADCE (#1956) (#1958)
Consider atomics that load when analyzing live stores in ADCE.

Previously it asserted that the base of an OpImageTexelPointer should
be an image. It is actually a pointer to an image, so IsValidBasePointer
should suffice.
2018-10-12 08:46:35 -04:00
Diego Novillo
4a4632264e Add IR dumping functions to use during debugging.
When using lldb and/or gdb I frequently get odd std::string failures
when using the IR printing instructions we have now.  This adds the
methods  Instruction::Dump(), BasicBlock::Dump() and Function::Dump() to
emit the output of the pretty print to stderr.

With this I can now reliably print IR from gdb and lldb sessions.
2018-09-14 14:28:34 -04:00
dan sinclair
eda2cfbe12
Cleanup includes. (#1795)
This Cl cleans up the include paths to be relative to the top level
directory. Various include-what-you-use fixes have been added.
2018-08-03 15:06:09 -04:00
dan sinclair
58a6876cee
Rewrite include guards (#1793)
This CL rewrites the include guards to make PRESUBMIT.py include guard
check happy.
2018-08-03 08:05:33 -04:00
dan sinclair
effafedcee
Replace opt::Instruction type and result cache with flags. (#1718)
Currentlty opt::Instruction class holds a cache of the result_id and
type_id for the instruction. That cache needs to be updated if the
underlying operand values are changes.

This CL changes the cache to being a flag if there is a type or result
id for the instruction. We then retrieve the value if needed from the
operands.
2018-07-20 11:09:30 -04:00
Alan Baker
3c19651733 Add variable pointer support to IsValidBasePointer
Fixes #1729

* Adds supported opcodes to IsValidBasePointer() enable by
VariablePointers and VariablePointersStorageBuffer capabilities
 * Added tests
2018-07-19 14:43:59 -04:00
dan sinclair
c7da51a085
Cleanup extraneous namespace qualifies in source/opt. (#1716)
This CL follows up on the opt namespacing CLs by removing the
unnecessary opt:: and opt::analysis:: namespace prefixes.
2018-07-12 15:14:43 -04:00
dan sinclair
e6b953361d
Move the ir namespace to opt. (#1680)
This CL moves the files in opt/ to consistenly be under the opt::
namespace. This frees up the ir:: namespace so it can be used to make a
shared ir represenation.
2018-07-09 11:32:29 -04:00
Steven Perron
1f7b1f1bf7 Small vector optimization for operands.
We replace the std::vector in the Operand class by a new class that does
a small size optimization.  This helps improve compile time on Windows.

Tested on three sets of shaders.  Trying various values for the small
vector.  The optimal value for the operand class was 2.  However, for
the Instruction class, using an std::vector was optimal.  Size of "0"
means that an std::vector was used.

                Instruction size
	        0      4      8
Operand Size

0               489    544    684
1               593    487
2               469    570
4               473
8               505

This is a single thread run of ~120 shaders.  For the multithreaded run
the results were the similar.  The basline time was ~62sec.  The
optimal configuration was an 2 for the OperandData and an
std::vector for the OperandList with a compile time of ~38sec.  Similar
expiriments were done with other sets of shaders.  The compile time still
improved, but not as much.

Contributes to https://github.com/KhronosGroup/SPIRV-Tools/issues/1609.
2018-06-12 13:41:08 -04:00
Steven Perron
0856997df6 Allow ADCE to remove more instructions.
At this time, DCE will only remove an instruction if it is a combinator.
However, there are certain non-combinator instructions that can be
safely removed if their results are not used.  The derivative
instructions are on example.

We are also missing some instructions from the list of combinators
those are added as the same time.
2018-05-05 09:15:28 -04:00
Steven Perron
9ba0879ddf Improve Vector DCE
Track live scalars in VDCE as if they were single element vectors.

Handle the extended instructions for GLSL in VDCE.

Handle composite construct instructions in VDCE.
2018-04-30 11:55:50 -04:00
Steven Perron
a00a0a09ae Revert "Improvements to vector dce."
This reverts commit 2813722993.

A regression was found.  Undoing the change until it is fixed.
2018-04-27 10:33:19 -04:00
Steven Perron
2813722993 Improvements to vector dce.
Track live scalars in VDCE as if they were single element vectors.

Handle the extended instructions for GLSL in VDCE.

Handle composite construct instructions in VDCE.

Fixes #1511.
2018-04-26 11:07:48 -04:00
Pierre Moreau
5bd55f10cd Reimplement the DecorationManager
This reimplementation fixes several issues when removing decorations associated
to an ID (partially addresses #1174 and gives tools for fixing #898), as well
as making it easier to remove groups; a few additional tests have been added.

DecorationManager::RemoveDecoration() will still not delete dead decorations it
created, but I do not think it is its job either; given the following input

```
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %2 Restrict
%2      = OpDecorationGroup
OpGroupDecorate %2 %1 %3
OpDecorate %4 Invariant
%4      = OpDecorationGroup
OpGroupDecorate %4 %2
%uint   = OpTypeInt 32 0
%1      = OpVariable %uint Uniform
%3      = OpVariable %uint Uniform
```

which of the following two outputs would you expect RemoveDecoration(2) to produce:

```
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
%uint = OpTypeInt 32 0
%1 = OpVariable %uint Uniform
%3 = OpVariable %uint Uniform
```

or

```
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %4 Invariant
%4      = OpDecorationGroup
%uint   = OpTypeInt 32 0
%1      = OpVariable %uint Uniform
%3      = OpVariable %uint Uniform
```

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/924
Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1174
2018-03-12 09:56:14 -04:00
Arseny Kapoulkine
309be423cc Add folding for redundant add/sub/mul/div/mix operations
This change implements instruction folding for arithmetic operations
that are redundant, specifically:

  x + 0 = 0 + x = x
  x - 0 = x
  0 - x = -x
  x * 0 = 0 * x = 0
  x * 1 = 1 * x = x
  0 / x = 0
  x / 1 = x
  mix(a, b, 0) = a
  mix(a, b, 1) = b

Cache ExtInst import id in feature manager

This allows us to avoid string lookups during optimization; for now we
just cache GLSL std450 import id but I can imagine caching more sets as
they become utilized by the optimizer.

Add tests for add/sub/mul/div/mix folding

The tests cover scalar float/double cases, and some vector cases.

Since most of the code for floating point folding is shared, the tests
for vector folding are not as exhaustive as scalar.

To test sub->negate folding I had to implement a custom fixture.
2018-02-20 18:29:27 -05:00