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