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