Make better use of simplification pass
[platform/upstream/SPIRV-Tools.git] / README.md
index 429702d..9a7ac66 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,30 +1,54 @@
 # SPIR-V Tools
 
 [![Build Status](https://travis-ci.org/KhronosGroup/SPIRV-Tools.svg?branch=master)](https://travis-ci.org/KhronosGroup/SPIRV-Tools)
+[![Build status](https://ci.appveyor.com/api/projects/status/gpue87cesrx3pi0d/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/spirv-tools/branch/master)
 
 ## Overview
 
 The SPIR-V Tools project provides an API and commands for processing SPIR-V
 modules.
 
-The project includes an assembler, binary module parser, disassembler, and
-validator for SPIR-V, all based on a common static library. The library contains
-all of the implementation details, and is used in the standalone tools whilst
-also enabling integration into other code bases directly.
+The project includes an assembler, binary module parser, disassembler,
+validator, and optimizer for SPIR-V. Except for the optimizer, all are based
+on a common static library.  The library contains all of the implementation
+details, and is used in the standalone tools whilst also enabling integration
+into other code bases directly. The optimizer implementation resides in its
+own library, which depends on the core library.
 
-The interfaces are still under development, and are expected to change.
+The interfaces have stabilized:
+We don't anticipate making a breaking change for existing features.
 
 SPIR-V is defined by the Khronos Group Inc.
-See the [SPIR-V Registry](https://www.khronos.org/registry/spir-v/) for the
-SPIR-V specification, headers, and XML registry.
+See the [SPIR-V Registry][spirv-registry] for the SPIR-V specification,
+headers, and XML registry.
+
+## Versioning SPIRV-Tools
+
+See [`CHANGES`](CHANGES) for a high level summary of recent changes, by version.
+
+SPIRV-Tools project version numbers are of the form `v`*year*`.`*index* and with
+an optional `-dev` suffix to indicate work in progress.  For exampe, the
+following versions are ordered from oldest to newest:
+
+* `v2016.0`
+* `v2016.1-dev`
+* `v2016.1`
+* `v2016.2-dev`
+* `v2016.2`
+
+Use the `--version` option on each command line tool to see the software
+version.  An API call reports the software version as a C-style string.
 
 ## Supported features
 
 ### Assembler, binary parser, and disassembler
 
-* Based on SPIR-V 1.0 Revision 2.
-  * Supports GLSL std450 extended instructions.
-  * Supports OpenCL extended instructions.
+* Support for SPIR-V 1.0, 1.1, 1.2
+  * Based on SPIR-V syntax described by JSON grammar files in the
+    [SPIRV-Headers](spirv-headers) repository.
+* Support for extended instruction sets:
+  * GLSL std450 version 1.0 Rev 3
+  * OpenCL version 1.0 Rev 2
 * Assembler only does basic syntax checking.  No cross validation of
   IDs or types is performed, except to check literal arguments to
   `OpConstant`, `OpSpecConstant`, and `OpSwitch`.
@@ -33,17 +57,110 @@ See [`syntax.md`](syntax.md) for the assembly language syntax.
 
 ### Validator
 
-*Warning:* The validator is incomplete.
+The validator checks validation rules described by the SPIR-V specification.
+
+Khronos recommends that tools that create or transform SPIR-V modules use the
+validator to ensure their outputs are valid, and that tools that consume SPIR-V
+modules optionally use the validator to protect themselves from bad inputs.
+This is especially encouraged for debug and development scenarios.
+
+The validator has one-sided error: it will only return an error when it has
+implemented a rule check and the module violates that rule.
+
+The validator is incomplete.
+See the [CHANGES](CHANGES) file for reports on completed work, and
+the [Validator
+sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/1) for planned
+and in-progress work.
+
+*Note*: The validator checks some Universal Limits, from section 2.17 of the SPIR-V spec.
+The validator will fail on a module that exceeds those minimum upper bound limits.
+It is [future work](https://github.com/KhronosGroup/SPIRV-Tools/projects/1#card-1052403)
+to parameterize the validator to allow larger
+limits accepted by a more than minimally capable SPIR-V consumer.
+
+
+### Optimizer
+
+*Note:* The optimizer is still under development.
+
+Currently supported optimizations:
+* General
+  * Strip debug info
+* Specialization Constants
+  * Set spec constant default value
+  * Freeze spec constant
+  * Fold `OpSpecConstantOp` and `OpSpecConstantComposite`
+  * Unify constants
+  * Eliminate dead constant
+* Code Reduction
+  * Inline all function calls exhaustively
+  * Convert local access chains to inserts/extracts
+  * Eliminate local load/store in single block
+  * Eliminate local load/store with single store
+  * Eliminate local load/store with multiple stores
+  * Eliminate local extract from insert
+  * Eliminate dead instructions (aggressive)
+  * Eliminate dead branches
+  * Merge single successor / single predecessor block pairs
+  * Eliminate common uniform loads
+  * Remove duplicates: Capabilities, extended instruction imports, types, and
+    decorations.
 
-## Source code
+For the latest list with detailed documentation, please refer to
+[`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp).
 
-The SPIR-V Tools are maintained by members of the The Khronos Group Inc.,
-at [https://github.com/KhronosGroup/SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools).
+For suggestions on using the code reduction options, please refer to this [white paper](https://www.lunarg.com/shader-compiler-technologies/white-paper-spirv-opt/).
+
+
+### Linker
+
+*Note:* The linker is still under development.
+
+Current features:
+* Combine multiple SPIR-V binary modules together.
+* Combine into a library (exports are retained) or an executable (no symbols
+  are exported).
+
+See the [CHANGES](CHANGES) file for reports on completed work, and the [General
+sub-project](https://github.com/KhronosGroup/SPIRV-Tools/projects/2) for
+planned and in-progress work.
+
+### Extras
+
+* [Utility filters](#utility-filters)
+* Build target `spirv-tools-vimsyntax` generates file `spvasm.vim`.
+  Copy that file into your `$HOME/.vim/syntax` directory to get SPIR-V assembly syntax
+  highlighting in Vim.  This build target is not built by default.
+
+## Contributing
+
+The SPIR-V Tools project is maintained by members of the The Khronos Group Inc.,
+and is hosted at https://github.com/KhronosGroup/SPIRV-Tools.
+
+Consider joining the `public_spirv_tools_dev@khronos.org` mailing list, via
+[https://www.khronos.org/spir/spirv-tools-mailing-list/](https://www.khronos.org/spir/spirv-tools-mailing-list/).
+The mailing list is used to discuss development plans for the SPIRV-Tools as an open source project.
+Once discussion is resolved,
+specific work is tracked via issues and sometimes in one of the
+[projects][spirv-tools-projects].
+
+(To provide feedback on the SPIR-V _specification_, file an issue on the
+[SPIRV-Headers][spirv-headers] GitHub repository.)
+
+See [`projects.md`](projects.md) to see how we use the
+[GitHub Project
+feature](https://help.github.com/articles/tracking-the-progress-of-your-work-with-projects/)
+to organize planned and in-progress work.
 
 Contributions via merge request are welcome. Changes should:
-* Be provided under the [Khronos license](#license).
+* Be provided under the [Apache 2.0](#license).
+* You'll be prompted with a one-time "click-through"
+  [Khronos Open Source Contributor License Agreement][spirv-tools-cla]
+  (CLA) dialog as part of submitting your pull request or
+  other contribution to GitHub.
 * Include tests to cover updated functionality.
-* C++ code should follow the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).
+* C++ code should follow the [Google C++ Style Guide][cpp-style-guide].
 * Code should be formatted with `clang-format`.  Settings are defined by
   the included [.clang-format](.clang-format) file.
 
@@ -51,21 +168,35 @@ We intend to maintain a linear history on the GitHub `master` branch.
 
 ### Source code organization
 
-* `external/headers`: Standard SPIR-V header files used by the implementation,
-   from the SPIR-V Registry
+* `example`: demo code of using SPIRV-Tools APIs
 * `external/googletest`: Intended location for the
-  [googletest](https://github.com/google/googletest) sources, not provided.
-* `include/libspirv/libspirv.h`: C API public interface
+  [googletest][googletest] sources, not provided
+* `external/effcee`: Location of [Effcee][effcee] sources, if the `effcee` library
+  is not already configured by an enclosing project.
+* `external/re2`: Location of [RE2][re2] sources, if the `effcee` library is not already
+  configured by an enclosing project.
+  (The Effcee project already requires RE2.)
+* `include/`: API clients should add this directory to the include search path
+* `external/spirv-headers`: Intended location for
+  [SPIR-V headers][spirv-headers], not provided
+* `include/spirv-tools/libspirv.h`: C API public interface
 * `source/`: API implementation
-* `test/`: Tests, using the [googletest](https://github.com/google/googletest)
-  framework.
+* `test/`: Tests, using the [googletest][googletest] framework
 * `tools/`: Command line executables
 
+Example of getting sources, assuming SPIRV-Tools is configured as a standalone project:
+
+    git clone https://github.com/KhronosGroup/SPIRV-Tools.git   spirv-tools
+    git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-tools/external/spirv-headers
+    git clone https://github.com/google/googletest.git          spirv-tools/external/googletest
+    git clone https://github.com/google/effcee.git              spirv-tools/external/effcee
+    git clone https://github.com/google/re2.git                 spirv-tools/external/re2
+
 ### Tests
 
 The project contains a number of tests, used to drive development
 and ensure correctness.  The tests are written using the
-[googletest](https://github.com/google/googletest) framework.  The `googletest`
+[googletest][googletest] framework.  The `googletest`
 source is not provided with this project.  There are two ways to enable
 tests:
 * If SPIR-V Tools is configured as part of an enclosing project, then the
@@ -75,20 +206,40 @@ tests:
   configuring and building the project.
 
 *Note*: You must use a version of googletest that includes
-[a fix](https://github.com/google/googletest/pull/612) for
-[googletest issue 610](https://github.com/google/googletest/issues/610).
+[a fix][googletest-pull-612] for [googletest issue 610][googletest-issue-610].
 The fix is included on the googletest master branch any time after 2015-11-10.
 In particular, googletest must be newer than version 1.7.0.
 
+### Optional dependency on Effcee
+
+Some tests depend on the [Effcee][effcee] library for stateful matching.
+Effcee itself depends on [RE2][re2].
+
+* If SPIRV-Tools is configured as part of a larger project that already uses
+  Effcee, then that project should include Effcee before SPIRV-Tools.
+* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`
+  and RE2 sources to appear in `external/re2`.
+
+Currently Effcee is an optional dependency, but soon it will be required.
+
 ## Build
 
-The project uses [CMake](https://cmake.org/) to generate platform-specific
-build configurations.  To generate these build files, issue the following
-commands:
+Instead of building manually, you can also download the binaries for your
+platform directly from the [master-tot release][master-tot-release] on GitHub.
+Those binaries are automatically uploaded by the buildbots after successful
+testing and they always reflect the current top of the tree of the master
+branch.
 
-```
-mkdir <spirv-dir>/build
-cd <spirv-dir>/build
+The project uses [CMake][cmake] to generate platform-specific build
+configurations. Assume that `<spirv-dir>` is the root directory of the checked
+out code:
+
+```sh
+cd <spirv-dir>
+git clone https://github.com/KhronosGroup/SPIRV-Headers.git external/spirv-headers
+git clone https://github.com/google/googletest.git external/googletest # optional
+
+mkdir build && cd build
 cmake [-G <platform-generator>] <spirv-dir>
 ```
 
@@ -100,12 +251,15 @@ development environment.
 The following CMake options are supported:
 
 * `SPIRV_COLOR_TERMINAL={ON|OFF}`, default `ON` - Enables color console output.
+* `SPIRV_SKIP_TESTS={ON|OFF}`, default `OFF`- Build only the library and
+  the command line tools.  This will prevent the tests from being built.
 * `SPIRV_SKIP_EXECUTABLES={ON|OFF}`, default `OFF`- Build only the library, not
-  the command line tools.  This will also prevent the tests from being built.
-* `SPIRV_USE_SANITIZER=<sanitizer>`, default is no sanitizing - On UNIX platforms
-  with an appropriate version of `clang` this option enables the use of the
-  sanitizers documented
-  [here](http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation).
+  the command line tools and tests.
+* `SPIRV_BUILD_COMPRESSION={ON|OFF}`, default `OFF`- Build SPIR-V compressing
+  codec.
+* `SPIRV_USE_SANITIZER=<sanitizer>`, default is no sanitizing - On UNIX
+  platforms with an appropriate version of `clang` this option enables the use
+  of the sanitizers documented [here][clang-sanitizers].
   This should only be used with a debug build.
 * `SPIRV_WARN_EVERYTHING={ON|OFF}`, default `OFF` - On UNIX platforms enable
   more strict warnings.  The code might not compile with this option enabled.
@@ -115,27 +269,40 @@ The following CMake options are supported:
   warnings encountered by enabling the compiler-specific compiler front-end
   option.
 
+Additionally, you can pass additional C preprocessor definitions to SPIRV-Tools
+via setting `SPIRV_TOOLS_EXTRA_DEFINITIONS`. For example, by setting it to
+`/D_ITERATOR_DEBUG_LEVEL=0` on Windows, you can disable checked iterators and
+iterator debugging.
+
 ## Library
 
 ### Usage
 
-The library provides a C API, but the internals use C++11.
+The internals of the library use C++11 features, and are exposed via both a C
+and C++ API.
 
-In order to use the library from an application, the include path should point to
-`<spirv-dir>/include`, which will enable the application to include the header
-`<spirv-dir>/include/libspirv/libspirv.h` then linking against the static
-library in `<spirv-build-dir>/libSPIRV-Tools.a` or
-`<spirv-build-dir>/SPIRV-Tools.lib`.
+In order to use the library from an application, the include path should point
+to `<spirv-dir>/include`, which will enable the application to include the
+header `<spirv-dir>/include/spirv-tools/libspirv.h{|pp}` then linking against
+the static library in `<spirv-build-dir>/source/libSPIRV-Tools.a` or
+`<spirv-build-dir>/source/SPIRV-Tools.lib`.
+For optimization, the header file is
+`<spirv-dir>/include/spirv-tools/optimizer.hpp`, and the static library is
+`<spirv-build-dir>/source/libSPIRV-Tools-opt.a` or
+`<spirv-build-dir>/source/SPIRV-Tools-opt.lib`.
 
 * `SPIRV-Tools` CMake target: Creates the static library:
-  * `<spirv-build-dir>/libSPIRV-Tools.a` on Linux and OS X.
-  * `<spirv-build-dir>/libSPIRV-Tools.lib` on Windows.
+  * `<spirv-build-dir>/source/libSPIRV-Tools.a` on Linux and OS X.
+  * `<spirv-build-dir>/source/libSPIRV-Tools.lib` on Windows.
+* `SPIRV-Tools-opt` CMake target: Creates the static library:
+  * `<spirv-build-dir>/source/libSPIRV-Tools-opt.a` on Linux and OS X.
+  * `<spirv-build-dir>/source/libSPIRV-Tools-opt.lib` on Windows.
 
 #### Entry points
 
 The interfaces are still under development, and are expected to change.
 
-There are three main entry points into the library.
+There are five main entry points into the library in the C interface:
 
 * `spvTextToBinary`: An assembler, translating text to a binary SPIR-V module.
 * `spvBinaryToText`: A disassembler, translating a binary SPIR-V module to
@@ -144,19 +311,30 @@ There are three main entry points into the library.
   for the header and each parsed instruction.  The disassembler is implemented
   as a client of `spvBinaryParse`.
 * `spvValidate` implements the validator functionality. *Incomplete*
+* `spvValidateBinary` implements the validator functionality. *Incomplete*
+
+The C++ interface is comprised of three classes, `SpirvTools`, `Optimizer` and
+`Linker`, all in the `spvtools` namespace.
+* `SpirvTools` provides `Assemble`, `Disassemble`, and `Validate` methods.
+* `Optimizer` provides methods for registering and running optimization passes.
+* `Linker` provides methods for combining together multiple binaries.
 
 ## Command line tools
 
+Command line tools, which wrap the above library functions, are provided to
+assemble or disassemble shader files.  It's a convention to name SPIR-V
+assembly and binary files with suffix `.spvasm` and `.spv`, respectively.
+
 ### Assembler tool
 
 The assembler reads the assembly language text, and emits the binary form.
 
 The standalone assembler is the exectuable called `spirv-as`, and is located in
-`<spirv-build-dir>/spirv-as`.  The functionality of the assembler is implemented
+`<spirv-build-dir>/tools/spirv-as`.  The functionality of the assembler is implemented
 by the `spvTextToBinary` library function.
 
 * `spirv-as` - the standalone assembler
-  * `<spirv-dir>/spirv-as`
+  * `<spirv-dir>/tools/as`
 
 Use option `-h` to print help.
 
@@ -165,43 +343,116 @@ Use option `-h` to print help.
 The disassembler reads the binary form, and emits assembly language text.
 
 The standalone disassembler is the executable called `spirv-dis`, and is located in
-`<spirv-build-dir>/spirv-dis`. The functionality of the disassembler is implemented
+`<spirv-build-dir>/tools/spirv-dis`. The functionality of the disassembler is implemented
 by the `spvBinaryToText` library function.
 
 * `spirv-dis` - the standalone disassembler
-  * `<spirv-dir>/spirv-dis`
+  * `<spirv-dir>/tools/dis`
 
 Use option `-h` to print help.
 
 The output includes syntax colouring when printing to the standard output stream,
 on Linux, Windows, and OS X.
 
+### Linker tool
+
+The linker combines multiple SPIR-V binary modules together, resulting in a single
+binary module as output.
+
+This is a work in progress.
+The linker does not support OpenCL program linking options related to math
+flags. (See section 5.6.5.2 in OpenCL 1.2)
+
+* `spirv-link` - the standalone linker
+  * `<spirv-dir>/tools/link`
+
+### Optimizer tool
+
+The optimizer processes a SPIR-V binary module, applying transformations
+in the specified order.
+
+This is a work in progress, with initially only few available transformations.
+
+* `spirv-opt` - the standalone optimizer
+  * `<spirv-dir>/tools/opt`
+
 ### Validator tool
 
 *Warning:* This functionality is under development, and is incomplete.
 
 The standalone validator is the executable called `spirv-val`, and is located in
-`<spirv-build-dir>/spirv-val`. The functionality of the validator is implemented
+`<spirv-build-dir>/tools/spirv-val`. The functionality of the validator is implemented
 by the `spvValidate` library function.
 
 The validator operates on the binary form.
 
 * `spirv-val` - the standalone validator
-  * `<spirv-dir>/spirv-val`
-
-### Tests
+  * `<spirv-dir>/tools/val`
+
+### Control flow dumper tool
+
+The control flow dumper prints the control flow graph for a SPIR-V module as a
+[GraphViz](http://www.graphviz.org/) graph.
+
+This is experimental.
+
+* `spirv-cfg` - the control flow graph dumper
+  * `<spirv-dir>/tools/cfg`
+
+### Utility filters
+
+* `spirv-lesspipe.sh` - Automatically disassembles `.spv` binary files for the
+  `less` program, on compatible systems.  For example, set the `LESSOPEN`
+  environment variable as follows, assuming both `spirv-lesspipe.sh` and
+  `spirv-dis` are on your executable search path:
+  ```
+   export LESSOPEN='| spirv-lesspipe.sh "%s"'
+  ```
+  Then you page through a disassembled module as follows:
+  ```
+  less foo.spv
+  ```
+  * The `spirv-lesspipe.sh` script will pass through any extra arguments to
+    `spirv-dis`.  So, for example, you can turn off colours and friendly ID
+    naming as follows:
+    ```
+    export LESSOPEN='| spirv-lesspipe.sh "%s" --no-color --raw-id'
+    ```
+
+* [vim-spirv](https://github.com/kbenzie/vim-spirv) - A vim plugin which
+  supports automatic disassembly of `.spv` files using the `:edit` command and
+  assembly using the `:write` command. The plugin also provides additional
+  features which include; syntax highlighting; highlighting of all ID's matching
+  the ID under the cursor; and highlighting errors where the `Instruction`
+  operand of `OpExtInst` is used without an appropriate `OpExtInstImport`.
+
+* `50spirv-tools.el` - Automatically disassembles '.spv' binary files when
+  loaded into the emacs text editor, and re-assembles them when saved,
+  provided any modifications to the file are valid.  This functionality
+  must be explicitly requested by defining the symbol
+  SPIRV_TOOLS_INSTALL_EMACS_HELPERS as follows:
+  ```
+  cmake -DSPIRV_TOOLS_INSTALL_EMACS_HELPERS=true ...
+  ```
+
+  In addition, this helper is only installed if the directory /etc/emacs/site-start.d
+  exists, which is typically true if emacs is installed on the system.
+
+  Note that symbol IDs are not currently preserved through a load/edit/save operation.
+  This may change if the ability is added to spirv-as.
 
-Tests are only built when googletest is found.
 
-The `<spirv-build-dir>/UnitSPIRV` executable runs the project tests.
-It supports the standard `googletest` command line options.
+### Tests
 
-The project also adds a CMake test `spirv-tools-testsuite`, which executes
-`UnitSPIRV`.  That way it's possible to run the tests using `ctest`.
+Tests are only built when googletest is found. Use `ctest` to run all the
+tests.
 
 ## Future Work
 <a name="future"></a>
 
+_See the [projects pages](https://github.com/KhronosGroup/SPIRV-Tools/projects)
+for more information._
+
 ### Assembler and disassembler
 
 * The disassembler could emit helpful annotations in comments.  For example:
@@ -215,32 +466,44 @@ The project also adds a CMake test `spirv-tools-testsuite`, which executes
 
 This is a work in progress.
 
+### Linker
+
+* The linker could accept math transformations such as allowing MADs, or other
+  math flags passed at linking-time in OpenCL.
+* Linkage attributes can not be applied through a group.
+* Check decorations of linked functions attributes.
+* Remove dead instructions, such as OpName targeting imported symbols.
+
 ## Licence
 <a name="license"></a>
+Full license terms are in [LICENSE](LICENSE)
 ```
 Copyright (c) 2015-2016 The Khronos Group Inc.
 
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and/or associated documentation files (the
-"Materials"), to deal in the Materials without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Materials, and to
-permit persons to whom the Materials are furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Materials.
-
-MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
-KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
-SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
-   https://www.khronos.org/registry/
-
-THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
 ```
+
+[spirv-tools-cla]: https://cla-assistant.io/KhronosGroup/SPIRV-Tools
+[spirv-tools-projects]: https://github.com/KhronosGroup/SPIRV-Tools/projects
+[spirv-tools-mailing-list]: https://www.khronos.org/spir/spirv-tools-mailing-list
+[spirv-registry]: https://www.khronos.org/registry/spir-v/
+[spirv-headers]: https://github.com/KhronosGroup/SPIRV-Headers
+[googletest]: https://github.com/google/googletest
+[googletest-pull-612]: https://github.com/google/googletest/pull/612
+[googletest-issue-610]: https://github.com/google/googletest/issues/610
+[effcee]: https://github.com/google/effcee
+[re2]: https://github.com/google/re2
+[CMake]: https://cmake.org/
+[cpp-style-guide]: https://google.github.io/styleguide/cppguide.html
+[clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
+[master-tot-release]: https://github.com/KhronosGroup/SPIRV-Tools/releases/tag/master-tot