README.md
1# SPIR-V Tools
2[](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/SPIRV-Tools)
3
4NEWS 2023-01-11: Development occurs on the `main` branch.
5
6## Overview
7
8The SPIR-V Tools project provides an API and commands for processing SPIR-V
9modules.
10
11The project includes an assembler, binary module parser, disassembler,
12validator, and optimizer for SPIR-V. Except for the optimizer, all are based
13on a common static library. The library contains all of the implementation
14details, and is used in the standalone tools whilst also enabling integration
15into other code bases directly. The optimizer implementation resides in its
16own library, which depends on the core library.
17
18The interfaces have stabilized:
19We don't anticipate making a breaking change for existing features.
20
21SPIR-V is defined by the Khronos Group Inc.
22See the [SPIR-V Registry][spirv-registry] for the SPIR-V specification,
23headers, and XML registry.
24
25## Downloads
26
27<img alt="Linux" src="kokoro/img/linux.png" width="20px" height="20px" hspace="2px"/>[](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html)
28<img alt="MacOS" src="kokoro/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html)
29<img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/>[](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2019_release.html)
30
31[More downloads](docs/downloads.md)
32
33## Versioning SPIRV-Tools
34
35See [`CHANGES`](CHANGES) for a high level summary of recent changes, by version.
36
37SPIRV-Tools project version numbers are of the form `v`*year*`.`*index* and with
38an optional `-dev` suffix to indicate work in progress. For example, the
39following versions are ordered from oldest to newest:
40
41* `v2016.0`
42* `v2016.1-dev`
43* `v2016.1`
44* `v2016.2-dev`
45* `v2016.2`
46
47Use the `--version` option on each command line tool to see the software
48version. An API call reports the software version as a C-style string.
49
50## Releases
51
52Some versions of SPIRV-Tools are tagged as stable releases (see
53[tags](https://github.com/KhronosGroup/SPIRV-Tools/tags) on github).
54These versions undergo extra testing.
55Releases are not directly related to releases (or versions) of
56[SPIRV-Headers][spirv-headers].
57Releases of SPIRV-Tools are tested against the version of SPIRV-Headers listed
58in the [DEPS](DEPS) file.
59The release generally uses the most recent compatible version of SPIRV-Headers
60available at the time of release.
61No version of SPIRV-Headers other than the one listed in the DEPS file is
62guaranteed to work with the SPIRV-Tools release.
63
64## Supported features
65
66### Assembler, binary parser, and disassembler
67
68* Support for SPIR-V 1.0, through 1.5
69 * Based on SPIR-V syntax described by JSON grammar files in the
70 [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) repository.
71 * Usually, support for a new version of SPIR-V is ready within days after
72 publication.
73* Support for extended instruction sets:
74 * GLSL std450 version 1.0 Rev 3
75 * OpenCL version 1.0 Rev 2
76* Assembler only does basic syntax checking. No cross validation of
77 IDs or types is performed, except to check literal arguments to
78 `OpConstant`, `OpSpecConstant`, and `OpSwitch`.
79
80See [`docs/syntax.md`](docs/syntax.md) for the assembly language syntax.
81
82### Validator
83
84The validator checks validation rules described by the SPIR-V specification.
85
86Khronos recommends that tools that create or transform SPIR-V modules use the
87validator to ensure their outputs are valid, and that tools that consume SPIR-V
88modules optionally use the validator to protect themselves from bad inputs.
89This is especially encouraged for debug and development scenarios.
90
91The validator has one-sided error: it will only return an error when it has
92implemented a rule check and the module violates that rule.
93
94The validator is incomplete.
95See the [CHANGES](CHANGES) file for reports on completed work, and
96the [Validator
97sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/1) for planned
98and in-progress work.
99
100*Note*: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec.
101The validator will fail on a module that exceeds those minimum upper bound limits.
102The validator has been parameterized to allow larger values, for use when targeting
103a more-than-minimally-capable SPIR-V consumer.
104
105See [`tools/val/val.cpp`](tools/val/val.cpp) or run `spirv-val --help` for the command-line help.
106
107### Optimizer
108
109The optimizer is a collection of code transforms, or "passes".
110Transforms are written for a diverse set of reasons:
111
112* To restructure, simplify, or normalize the code for further processing.
113* To eliminate undesirable code.
114* To improve code quality in some metric such as size or performance.
115 **Note**: These transforms are not guaranteed to actually improve any
116 given metric. Users should always measure results for their own situation.
117
118As of this writing, there are 67 transforms including examples such as:
119* Simplification
120 * Strip debug info
121 * Strip reflection info
122* Specialization Constants
123 * Set spec constant default value
124 * Freeze spec constant to default value
125 * Fold `OpSpecConstantOp` and `OpSpecConstantComposite`
126 * Unify constants
127 * Eliminate dead constant
128* Code Reduction
129 * Inline all function calls exhaustively
130 * Convert local access chains to inserts/extracts
131 * Eliminate local load/store in single block
132 * Eliminate local load/store with single store
133 * Eliminate local load/store with multiple stores
134 * Eliminate local extract from insert
135 * Eliminate dead instructions (aggressive)
136 * Eliminate dead branches
137 * Merge single successor / single predecessor block pairs
138 * Eliminate common uniform loads
139 * Remove duplicates: Capabilities, extended instruction imports, types, and
140 decorations.
141* Normalization
142 * Compact IDs
143 * CFG cleanup
144 * Flatten decorations
145 * Merge returns
146 * Convert AMD-specific instructions to KHR instructions
147* Code improvement
148 * Conditional constant propagation
149 * If-conversion
150 * Loop fission
151 * Loop fusion
152 * Loop-invariant code motion
153 * Loop unroll
154* Other
155 * Graphics robust access
156 * Upgrade memory model to VulkanKHR
157
158Additionally, certain sets of transformations have been packaged into
159higher-level recipes. These include:
160
161* Optimization for size (`spirv-opt -Os`)
162* Optimization for performance (`spirv-opt -O`)
163
164For the latest list with detailed documentation, please refer to
165[`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp).
166
167For suggestions on using the code reduction options, please refer to this [white paper](https://www.lunarg.com/shader-compiler-technologies/white-paper-spirv-opt/).
168
169
170### Linker
171
172*Note:* The linker is still under development.
173
174Current features:
175* Combine multiple SPIR-V binary modules together.
176* Combine into a library (exports are retained) or an executable (no symbols
177 are exported).
178
179See the [CHANGES](CHANGES) file for reports on completed work, and the [General
180sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/2) for
181planned and in-progress work.
182
183
184### Reducer
185
186*Note:* The reducer is still under development.
187
188The reducer simplifies and shrinks a SPIR-V module with respect to a
189user-supplied *interestingness function*. For example, given a large
190SPIR-V module that cause some SPIR-V compiler to fail with a given
191fatal error message, the reducer could be used to look for a smaller
192version of the module that causes the compiler to fail with the same
193fatal error message.
194
195To suggest an additional capability for the reducer, [file an
196issue](https://github.com/KhronosGroup/SPIRV-Tools/issues]) with
197"Reducer:" as the start of its title.
198
199
200### Fuzzer
201
202*Note:* The fuzzer is still under development.
203
204The fuzzer applies semantics-preserving transformations to a SPIR-V binary
205module, to produce an equivalent module. The original and transformed modules
206should produce essentially identical results when executed on identical inputs:
207their results should differ only due to floating-point round-off, if at all.
208Significant differences in results can pinpoint bugs in tools that process
209SPIR-V binaries, such as miscompilations. This *metamorphic testing* approach
210is similar to the method used by the [GraphicsFuzz
211project](https://github.com/google/graphicsfuzz) for fuzzing of GLSL shaders.
212
213To suggest an additional capability for the fuzzer, [file an
214issue](https://github.com/KhronosGroup/SPIRV-Tools/issues]) with
215"Fuzzer:" as the start of its title.
216
217
218### Diff
219
220*Note:* The diff tool is still under development.
221
222The diff tool takes two SPIR-V files, either in binary or text format and
223produces a diff-style comparison between the two. The instructions between the
224src and dst modules are matched as best as the tool can, and output is produced
225(in src id-space) that shows which instructions are removed in src, added in dst
226or modified between them. The order of instructions are not retained.
227
228Matching instructions between two SPIR-V modules is not trivial, and thus a
229number of heuristics are applied in this tool. In particular, without debug
230information, match functions is nontrivial as they can be reordered. As such,
231this tool is primarily useful to produce the diff of two SPIR-V modules derived
232from the same source, for example before and after a modification to the shader,
233before and after a transformation, or SPIR-V produced from different tools.
234
235
236### Extras
237
238* [Utility filters](#utility-filters)
239* Build target `spirv-tools-vimsyntax` generates file `spvasm.vim`.
240 Copy that file into your `$HOME/.vim/syntax` directory to get SPIR-V assembly syntax
241 highlighting in Vim. This build target is not built by default.
242
243## Contributing
244
245The SPIR-V Tools project is maintained by members of the The Khronos Group Inc.,
246and is hosted at https://github.com/KhronosGroup/SPIRV-Tools.
247
248Consider joining the `[email protected]` mailing list, via
249[https://www.khronos.org/spir/spirv-tools-mailing-list/](https://www.khronos.org/spir/spirv-tools-mailing-list/).
250The mailing list is used to discuss development plans for the SPIRV-Tools as an open source project.
251Once discussion is resolved,
252specific work is tracked via issues and sometimes in one of the
253[projects][spirv-tools-projects].
254
255(To provide feedback on the SPIR-V _specification_, file an issue on the
256[SPIRV-Headers][spirv-headers] GitHub repository.)
257
258See [`docs/projects.md`](docs/projects.md) to see how we use the
259[GitHub Project
260feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/)
261to organize planned and in-progress work.
262
263Contributions via merge request are welcome. Changes should:
264* Be provided under the [Apache 2.0](#license).
265* You'll be prompted with a one-time "click-through"
266 [Khronos Open Source Contributor License Agreement][spirv-tools-cla]
267 (CLA) dialog as part of submitting your pull request or
268 other contribution to GitHub.
269* Include tests to cover updated functionality.
270* C++ code should follow the [Google C++ Style Guide][cpp-style-guide].
271* Code should be formatted with `clang-format`.
272 [kokoro/check-format/build.sh](kokoro/check-format/build.sh)
273 shows how to download it. Note that we currently use
274 `clang-format version 5.0.0` for SPIRV-Tools. Settings are defined by
275 the included [.clang-format](.clang-format) file.
276
277We intend to maintain a linear history on the GitHub `main` branch.
278
279### Getting the source
280
281Example of getting sources, assuming SPIRV-Tools is configured as a standalone project:
282
283 git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
284 cd spirv-tools
285
286 # Check out sources for dependencies, at versions known to work together,
287 # as listed in the DEPS file.
288 python3 utils/git-sync-deps
289
290For some kinds of development, you may need the latest sources from the third-party projects:
291
292 git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers
293 git clone https://github.com/google/googletest.git spirv-tools/external/googletest
294 git clone https://github.com/google/effcee.git spirv-tools/external/effcee
295 git clone https://github.com/google/re2.git spirv-tools/external/re2
296 git clone https://github.com/abseil/abseil-cpp.git spirv-tools/external/abseil_cpp
297
298#### Dependency on Effcee
299
300Some tests depend on the [Effcee][effcee] library for stateful matching.
301Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp].
302
303* If SPIRV-Tools is configured as part of a larger project that already uses
304 Effcee, then that project should include Effcee before SPIRV-Tools.
305* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`,
306 RE2 sources to appear in `external/re2`, and Abseil sources to appear in
307 `external/abseil_cpp`.
308
309### Source code organization
310
311* `example`: demo code of using SPIRV-Tools APIs
312* `external/googletest`: Intended location for the
313 [googletest][googletest] sources, not provided
314* `external/effcee`: Location of [Effcee][effcee] sources, if the `effcee` library
315 is not already configured by an enclosing project.
316* `external/re2`: Location of [RE2][re2] sources, if the `re2` library is not already
317 configured by an enclosing project.
318 (The Effcee project already requires RE2.)
319* `external/abseil_cpp`: Location of [Abseil][abseil-cpp] sources, if Abseil is
320 not already configured by an enclosing project.
321 (The RE2 project already requires Abseil.)
322* `include/`: API clients should add this directory to the include search path
323* `external/spirv-headers`: Intended location for
324 [SPIR-V headers][spirv-headers], not provided
325* `include/spirv-tools/libspirv.h`: C API public interface
326* `source/`: API implementation
327* `test/`: Tests, using the [googletest][googletest] framework
328* `tools/`: Command line executables
329
330### Tests
331
332The project contains a number of tests, used to drive development
333and ensure correctness. The tests are written using the
334[googletest][googletest] framework. The `googletest`
335source is not provided with this project. There are two ways to enable
336tests:
337* If SPIR-V Tools is configured as part of an enclosing project, then the
338 enclosing project should configure `googletest` before configuring SPIR-V Tools.
339* If SPIR-V Tools is configured as a standalone project, then download the
340 `googletest` source into the `<spirv-dir>/external/googletest` directory before
341 configuring and building the project.
342
343## Build
344
345*Note*: Prebuilt binaries are available from the [downloads](docs/downloads.md) page.
346
347First [get the sources](#getting-the-source).
348Then build using CMake, Bazel, Android ndk-build, or the Emscripten SDK.
349
350### Build using CMake
351You can build the project using [CMake][cmake]:
352
353```sh
354cd <spirv-dir>
355mkdir build && cd build
356cmake [-G <platform-generator>] <spirv-dir>
357```
358
359Once the build files have been generated, build using the appropriate build
360command (e.g. `ninja`, `make`, `msbuild`, etc.; this depends on the platform
361generator used above), or use your IDE, or use CMake to run the appropriate build
362command for you:
363
364```sh
365cmake --build . [--config Debug] # runs `make` or `ninja` or `msbuild` etc.
366```
367
368#### Note about the fuzzer
369
370The SPIR-V fuzzer, `spirv-fuzz`, can only be built via CMake, and is disabled by
371default. To build it, clone protobuf and use the `SPIRV_BUILD_FUZZER` CMake
372option, like so:
373
374```sh
375# In <spirv-dir> (the SPIRV-Tools repo root):
376git clone --depth=1 --branch v3.13.0.1 https://github.com/protocolbuffers/protobuf external/protobuf
377
378# In your build directory:
379cmake [-G <platform-generator>] <spirv-dir> -DSPIRV_BUILD_FUZZER=ON
380cmake --build . --config Debug
381```
382
383You can also add `-DSPIRV_ENABLE_LONG_FUZZER_TESTS=ON` to build additional
384fuzzer tests.
385
386
387### Build using Bazel
388You can also use [Bazel](https://bazel.build/) to build the project.
389
390```sh
391bazel build :all
392```
393
394### Build a node.js package using Emscripten
395
396The SPIRV-Tools core library can be built to a WebAssembly [node.js](https://nodejs.org)
397module. The resulting `SpirvTools` WebAssembly module only exports methods to
398assemble and disassemble SPIR-V modules.
399
400First, make sure you have the [Emscripten SDK](https://emscripten.org).
401Then:
402
403```sh
404cd <spirv-dir>
405./source/wasm/build.sh
406```
407
408The resulting node package, with JavaScript and TypeScript bindings, is
409written to `<spirv-dir>/out/web`.
410
411Note: This builds the package locally. It does *not* publish it to [npm](https://npmjs.org).
412
413To test the result:
414
415```sh
416node ./test/wasm/test.js
417```
418
419### Tools you'll need
420
421For building and testing SPIRV-Tools, the following tools should be
422installed regardless of your OS:
423
424- [CMake](http://www.cmake.org/): if using CMake for generating compilation
425targets, you need to install CMake Version 2.8.12 or later.
426- [Python 3](http://www.python.org/): for utility scripts and running the test
427suite.
428- [Bazel](https://bazel.build/) (optional): if building the source with Bazel,
429you need to install Bazel Version 5.0.0 on your machine. Other versions may
430also work, but are not verified.
431- [Emscripten SDK](https://emscripten.org) (optional): if building the
432 WebAssembly module.
433
434SPIRV-Tools is regularly tested with the following compilers:
435
436On Linux
437- GCC version 9.3
438- Clang version 10.0
439
440On MacOS
441- AppleClang 11.0
442
443On Windows
444- Visual Studio 2017
445- Visual Studio 2019
446- Visual Studio 2022
447
448Note: Visual Studio 2017 has incomplete c++17 support. We might stop
449testing it soon. Other compilers or later versions may work, but they are not
450tested.
451
452### CMake options
453
454The following CMake options are supported:
455
456* `SPIRV_BUILD_FUZZER={ON|OFF}`, default `OFF` - Build the spirv-fuzz tool.
457* `SPIRV_COLOR_TERMINAL={ON|OFF}`, default `ON` - Enables color console output.
458* `SPIRV_SKIP_TESTS={ON|OFF}`, default `OFF`- Build only the library and
459 the command line tools. This will prevent the tests from being built.
460* `SPIRV_SKIP_EXECUTABLES={ON|OFF}`, default `OFF`- Build only the library, not
461 the command line tools and tests.
462* `SPIRV_USE_SANITIZER=<sanitizer>`, default is no sanitizing - On UNIX
463 platforms with an appropriate version of `clang` this option enables the use
464 of the sanitizers documented [here][clang-sanitizers].
465 This should only be used with a debug build.
466* `SPIRV_WARN_EVERYTHING={ON|OFF}`, default `OFF` - On UNIX platforms enable
467 more strict warnings. The code might not compile with this option enabled.
468 For Clang, enables `-Weverything`. For GCC, enables `-Wpedantic`.
469 See [`CMakeLists.txt`](CMakeLists.txt) for details.
470* `SPIRV_WERROR={ON|OFF}`, default `ON` - Forces a compilation error on any
471 warnings encountered by enabling the compiler-specific compiler front-end
472 option. No compiler front-end options are enabled when this option is OFF.
473
474Additionally, you can pass additional C preprocessor definitions to SPIRV-Tools
475via setting `SPIRV_TOOLS_EXTRA_DEFINITIONS`. For example, by setting it to
476`/D_ITERATOR_DEBUG_LEVEL=0` on Windows, you can disable checked iterators and
477iterator debugging.
478
479### Android ndk-build
480
481SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and
482`libSPIRV-Tools-opt.a` for Android. Using the Android NDK r25c or later:
483
484```
485cd <spirv-dir>
486
487export ANDROID_NDK=/path/to/your/ndk # NDK r25c or later
488
489mkdir build && cd build
490mkdir libs
491mkdir app
492
493$ANDROID_NDK/ndk-build -C ../android_test \
494 NDK_PROJECT_PATH=. \
495 NDK_LIBS_OUT=`pwd`/libs \
496 NDK_APP_OUT=`pwd`/app
497```
498
499### Updating DEPS
500
501Occasionally the entries in [DEPS](DEPS) will need to be updated. This is done on
502demand when there is a request to do this, often due to downstream breakages.
503To update `DEPS`, run `utils/roll_deps.sh` and confirm that tests pass.
504The script requires Chromium's
505[`depot_tools`](https://chromium.googlesource.com/chromium/tools/depot_tools).
506
507## Library
508
509### Usage
510
511The internals of the library use C++17 features, and are exposed via both a C
512and C++ API.
513
514In order to use the library from an application, the include path should point
515to `<spirv-dir>/include`, which will enable the application to include the
516header `<spirv-dir>/include/spirv-tools/libspirv.h{|pp}` then linking against
517the static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or
518`<spirv-build-dir>/source/SPIRV-Tools.lib`.
519For optimization, the header file is
520`<spirv-dir>/include/spirv-tools/optimizer.hpp`, and the static library is
521`<spirv-build-dir>/source/libSPIRV-Tools-opt.a` or
522`<spirv-build-dir>/source/SPIRV-Tools-opt.lib`.
523
524* `SPIRV-Tools` CMake target: Creates the static library:
525 * `<spirv-build-dir>/source/libSPIRV-Tools.a` on Linux and OS X.
526 * `<spirv-build-dir>/source/libSPIRV-Tools.lib` on Windows.
527* `SPIRV-Tools-opt` CMake target: Creates the static library:
528 * `<spirv-build-dir>/source/libSPIRV-Tools-opt.a` on Linux and OS X.
529 * `<spirv-build-dir>/source/libSPIRV-Tools-opt.lib` on Windows.
530
531#### Entry points
532
533The interfaces are still under development, and are expected to change.
534
535There are five main entry points into the library in the C interface:
536
537* `spvTextToBinary`: An assembler, translating text to a binary SPIR-V module.
538* `spvBinaryToText`: A disassembler, translating a binary SPIR-V module to
539 text.
540* `spvBinaryParse`: The entry point to a binary parser API. It issues callbacks
541 for the header and each parsed instruction. The disassembler is implemented
542 as a client of `spvBinaryParse`.
543* `spvValidate` implements the validator functionality. *Incomplete*
544* `spvValidateBinary` implements the validator functionality. *Incomplete*
545
546The C++ interface is comprised of three classes, `SpirvTools`, `Optimizer` and
547`Linker`, all in the `spvtools` namespace.
548* `SpirvTools` provides `Assemble`, `Disassemble`, and `Validate` methods.
549* `Optimizer` provides methods for registering and running optimization passes.
550* `Linker` provides methods for combining together multiple binaries.
551
552## Command line tools
553
554Command line tools, which wrap the above library functions, are provided to
555assemble or disassemble shader files. It's a convention to name SPIR-V
556assembly and binary files with suffix `.spvasm` and `.spv`, respectively.
557
558### Assembler tool
559
560The assembler reads the assembly language text, and emits the binary form.
561
562The standalone assembler is the executable called `spirv-as`, and is located in
563`<spirv-build-dir>/tools/spirv-as`. The functionality of the assembler is implemented
564by the `spvTextToBinary` library function.
565
566* `spirv-as` - the standalone assembler
567 * `<spirv-dir>/tools/as`
568
569Use option `-h` to print help.
570
571### Disassembler tool
572
573The disassembler reads the binary form, and emits assembly language text.
574
575The standalone disassembler is the executable called `spirv-dis`, and is located in
576`<spirv-build-dir>/tools/spirv-dis`. The functionality of the disassembler is implemented
577by the `spvBinaryToText` library function.
578
579* `spirv-dis` - the standalone disassembler
580 * `<spirv-dir>/tools/dis`
581
582Use option `-h` to print help.
583
584The output includes syntax colouring when printing to the standard output stream,
585on Linux, Windows, and OS X.
586
587### Linker tool
588
589The linker combines multiple SPIR-V binary modules together, resulting in a single
590binary module as output.
591
592This is a work in progress.
593The linker does not support OpenCL program linking options related to math
594flags. (See section 5.6.5.2 in OpenCL 1.2)
595
596* `spirv-link` - the standalone linker
597 * `<spirv-dir>/tools/link`
598
599### Optimizer tool
600
601The optimizer processes a SPIR-V binary module, applying transformations
602in the specified order.
603
604This is a work in progress, with initially only few available transformations.
605
606* `spirv-opt` - the standalone optimizer
607 * `<spirv-dir>/tools/opt`
608
609### Validator tool
610
611*Warning:* This functionality is under development, and is incomplete.
612
613The standalone validator is the executable called `spirv-val`, and is located in
614`<spirv-build-dir>/tools/spirv-val`. The functionality of the validator is implemented
615by the `spvValidate` library function.
616
617The validator operates on the binary form.
618
619* `spirv-val` - the standalone validator
620 * `<spirv-dir>/tools/val`
621
622### Reducer tool
623
624The reducer shrinks a SPIR-V binary module, guided by a user-supplied
625*interestingness test*.
626
627This is a work in progress, with initially only shrinks a module in a few ways.
628
629* `spirv-reduce` - the standalone reducer
630 * `<spirv-dir>/tools/reduce`
631
632Run `spirv-reduce --help` to see how to specify interestingness.
633
634### Fuzzer tool
635
636The fuzzer transforms a SPIR-V binary module into a semantically-equivalent
637SPIR-V binary module by applying transformations in a randomized fashion.
638
639This is a work in progress, with initially only a few semantics-preserving
640transformations.
641
642* `spirv-fuzz` - the standalone fuzzer
643 * `<spirv-dir>/tools/fuzz`
644
645Run `spirv-fuzz --help` for a detailed list of options.
646
647### Control flow dumper tool
648
649The control flow dumper prints the control flow graph for a SPIR-V module as a
650[GraphViz](http://www.graphviz.org/) graph.
651
652This is experimental.
653
654* `spirv-cfg` - the control flow graph dumper
655 * `<spirv-dir>/tools/cfg`
656
657### Diff tool
658
659*Warning:* This functionality is under development, and is incomplete.
660
661The diff tool produces a diff-style comparison between two SPIR-V modules.
662
663* `spirv-diff` - the standalone diff tool
664 * `<spirv-dir>`/tools/diff`
665
666### Utility filters
667
668* `spirv-lesspipe.sh` - Automatically disassembles `.spv` binary files for the
669 `less` program, on compatible systems. For example, set the `LESSOPEN`
670 environment variable as follows, assuming both `spirv-lesspipe.sh` and
671 `spirv-dis` are on your executable search path:
672 ```
673 export LESSOPEN='| spirv-lesspipe.sh "%s"'
674 ```
675 Then you page through a disassembled module as follows:
676 ```
677 less foo.spv
678 ```
679 * The `spirv-lesspipe.sh` script will pass through any extra arguments to
680 `spirv-dis`. So, for example, you can turn off colours and friendly ID
681 naming as follows:
682 ```
683 export LESSOPEN='| spirv-lesspipe.sh "%s" --no-color --raw-id'
684 ```
685
686* [vim-spirv](https://github.com/kbenzie/vim-spirv) - A vim plugin which
687 supports automatic disassembly of `.spv` files using the `:edit` command and
688 assembly using the `:write` command. The plugin also provides additional
689 features which include; syntax highlighting; highlighting of all ID's matching
690 the ID under the cursor; and highlighting errors where the `Instruction`
691 operand of `OpExtInst` is used without an appropriate `OpExtInstImport`.
692
693* `50spirv-tools.el` - Automatically disassembles '.spv' binary files when
694 loaded into the emacs text editor, and re-assembles them when saved,
695 provided any modifications to the file are valid. This functionality
696 must be explicitly requested by defining the symbol
697 SPIRV_TOOLS_INSTALL_EMACS_HELPERS as follows:
698 ```
699 cmake -DSPIRV_TOOLS_INSTALL_EMACS_HELPERS=true ...
700 ```
701
702 In addition, this helper is only installed if the directory /etc/emacs/site-start.d
703 exists, which is typically true if emacs is installed on the system.
704
705 Note that symbol IDs are not currently preserved through a load/edit/save operation.
706 This may change if the ability is added to spirv-as.
707
708
709### Tests
710
711Tests are only built when googletest is found.
712
713#### Running test with CMake
714
715Use `ctest -j <num threads>` to run all the tests. To run tests using all threads:
716```shell
717ctest -j$(nproc)
718```
719
720To run a single test target, use `ctest [-j <N>] -R <test regex>`. For example,
721you can run all `opt` tests with:
722```shell
723ctest -R 'spirv-tools-test_opt'
724```
725
726#### Running test with Bazel
727
728Use `bazel test :all` to run all tests. This will run tests in parallel by default.
729
730To run a single test target, specify `:my_test_target` instead of `:all`. Test target
731names get printed when you run `bazel test :all`. For example, you can run
732`opt_def_use_test` with:
733
734on linux:
735```shell
736bazel test --cxxopt=-std=c++17 :opt_def_use_test
737```
738
739on windows:
740```shell
741bazel test --cxxopt=/std:c++17 :opt_def_use_test
742```
743
744## Future Work
745<a name="future"></a>
746
747_See the [projects pages](https://github.com/KhronosGroup/SPIRV-Tools/projects)
748for more information._
749
750### Assembler and disassembler
751
752* The disassembler could emit helpful annotations in comments. For example:
753 * Use variable name information from debug instructions to annotate
754 key operations on variables.
755 * Show control flow information by annotating `OpLabel` instructions with
756 that basic block's predecessors.
757* Error messages could be improved.
758
759### Validator
760
761This is a work in progress.
762
763### Linker
764
765* The linker could accept math transformations such as allowing MADs, or other
766 math flags passed at linking-time in OpenCL.
767* Linkage attributes can not be applied through a group.
768* Check decorations of linked functions attributes.
769* Remove dead instructions, such as OpName targeting imported symbols.
770
771## Licence
772<a name="license"></a>
773Full license terms are in [LICENSE](LICENSE)
774```
775Copyright (c) 2015-2016 The Khronos Group Inc.
776
777Licensed under the Apache License, Version 2.0 (the "License");
778you may not use this file except in compliance with the License.
779You may obtain a copy of the License at
780
781 http://www.apache.org/licenses/LICENSE-2.0
782
783Unless required by applicable law or agreed to in writing, software
784distributed under the License is distributed on an "AS IS" BASIS,
785WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
786See the License for the specific language governing permissions and
787limitations under the License.
788```
789
790[spirv-tools-cla]: https://cla-assistant.io/KhronosGroup/SPIRV-Tools
791[spirv-tools-projects]: https://github.com/KhronosGroup/SPIRV-Tools/projects
792[spirv-tools-mailing-list]: https://www.khronos.org/spir/spirv-tools-mailing-list
793[spirv-registry]: https://www.khronos.org/registry/spir-v/
794[spirv-headers]: https://github.com/KhronosGroup/SPIRV-Headers
795[googletest]: https://github.com/google/googletest
796[googletest-pull-612]: https://github.com/google/googletest/pull/612
797[googletest-issue-610]: https://github.com/google/googletest/issues/610
798[effcee]: https://github.com/google/effcee
799[re2]: https://github.com/google/re2
800[abseil-cpp]: https://github.com/abseil/abseil-cpp
801[CMake]: https://cmake.org/
802[cpp-style-guide]: https://google.github.io/styleguide/cppguide.html
803[clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
804