Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2018-02-22 20:06:00 +0300
committerPhilip Rebohle <philip.rebohle@tu-dortmund.de>2018-02-22 20:06:00 +0300
commit4c693fc2624a8d37288815125aba19fa0a3aef0b (patch)
tree63a3fde5fb8e7739acccb0c1b1765aa7df927628 /include
parent6aff0dbe8760fde351e52b72c22eb208fb26bd85 (diff)
[spirv] Added experimental spirv-tools integration
Added support for the validator in order to make debugging easier, as well as the optimizer, which may help Nvidia users run DXVK.
Diffstat (limited to 'include')
-rw-r--r--include/spirv-tools/libspirv.h583
-rw-r--r--include/spirv-tools/libspirv.hpp174
-rw-r--r--include/spirv-tools/linker.hpp83
-rw-r--r--include/spirv-tools/optimizer.hpp525
4 files changed, 1365 insertions, 0 deletions
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
new file mode 100644
index 00000000..7f1ebba7
--- /dev/null
+++ b/include/spirv-tools/libspirv.h
@@ -0,0 +1,583 @@
+// Copyright (c) 2015-2016 The Khronos Group Inc.
+//
+// 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.
+
+#ifndef SPIRV_TOOLS_LIBSPIRV_H_
+#define SPIRV_TOOLS_LIBSPIRV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#include <stdbool.h>
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(SPIRV_TOOLS_SHAREDLIB)
+#if defined(_WIN32)
+#if defined(SPIRV_TOOLS_IMPLEMENTATION)
+#define SPIRV_TOOLS_EXPORT __declspec(dllexport)
+#else
+#define SPIRV_TOOLS_EXPORT __declspec(dllimport)
+#endif
+#else
+#if defined(SPIRV_TOOLS_IMPLEMENTATION)
+#define SPIRV_TOOLS_EXPORT __attribute__((visibility("default")))
+#else
+#define SPIRV_TOOLS_EXPORT
+#endif
+#endif
+#else
+#define SPIRV_TOOLS_EXPORT
+#endif
+
+// Helpers
+
+#define SPV_BIT(shift) (1 << (shift))
+
+#define SPV_FORCE_16_BIT_ENUM(name) _##name = 0x7fff
+#define SPV_FORCE_32_BIT_ENUM(name) _##name = 0x7fffffff
+
+// Enumerations
+
+typedef enum spv_result_t {
+ SPV_SUCCESS = 0,
+ SPV_UNSUPPORTED = 1,
+ SPV_END_OF_STREAM = 2,
+ SPV_WARNING = 3,
+ SPV_FAILED_MATCH = 4,
+ SPV_REQUESTED_TERMINATION = 5, // Success, but signals early termination.
+ SPV_ERROR_INTERNAL = -1,
+ SPV_ERROR_OUT_OF_MEMORY = -2,
+ SPV_ERROR_INVALID_POINTER = -3,
+ SPV_ERROR_INVALID_BINARY = -4,
+ SPV_ERROR_INVALID_TEXT = -5,
+ SPV_ERROR_INVALID_TABLE = -6,
+ SPV_ERROR_INVALID_VALUE = -7,
+ SPV_ERROR_INVALID_DIAGNOSTIC = -8,
+ SPV_ERROR_INVALID_LOOKUP = -9,
+ SPV_ERROR_INVALID_ID = -10,
+ SPV_ERROR_INVALID_CFG = -11,
+ SPV_ERROR_INVALID_LAYOUT = -12,
+ SPV_ERROR_INVALID_CAPABILITY = -13,
+ SPV_ERROR_INVALID_DATA = -14, // Indicates data rules validation failure.
+ SPV_ERROR_MISSING_EXTENSION = -15,
+ SPV_FORCE_32_BIT_ENUM(spv_result_t)
+} spv_result_t;
+
+// Severity levels of messages communicated to the consumer.
+typedef enum spv_message_level_t {
+ SPV_MSG_FATAL, // Unrecoverable error due to environment.
+ // Will exit the program immediately. E.g.,
+ // out of memory.
+ SPV_MSG_INTERNAL_ERROR, // Unrecoverable error due to SPIRV-Tools
+ // internals.
+ // Will exit the program immediately. E.g.,
+ // unimplemented feature.
+ SPV_MSG_ERROR, // Normal error due to user input.
+ SPV_MSG_WARNING, // Warning information.
+ SPV_MSG_INFO, // General information.
+ SPV_MSG_DEBUG, // Debug information.
+} spv_message_level_t;
+
+typedef enum spv_endianness_t {
+ SPV_ENDIANNESS_LITTLE,
+ SPV_ENDIANNESS_BIG,
+ SPV_FORCE_32_BIT_ENUM(spv_endianness_t)
+} spv_endianness_t;
+
+// The kinds of operands that an instruction may have.
+//
+// Some operand types are "concrete". The binary parser uses a concrete
+// operand type to describe an operand of a parsed instruction.
+//
+// The assembler uses all operand types. In addition to determining what
+// kind of value an operand may be, non-concrete operand types capture the
+// fact that an operand might be optional (may be absent, or present exactly
+// once), or might occur zero or more times.
+//
+// Sometimes we also need to be able to express the fact that an operand
+// is a member of an optional tuple of values. In that case the first member
+// would be optional, and the subsequent members would be required.
+typedef enum spv_operand_type_t {
+ // A sentinel value.
+ SPV_OPERAND_TYPE_NONE = 0,
+
+ // Set 1: Operands that are IDs.
+ SPV_OPERAND_TYPE_ID,
+ SPV_OPERAND_TYPE_TYPE_ID,
+ SPV_OPERAND_TYPE_RESULT_ID,
+ SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, // SPIR-V Sec 3.25
+ SPV_OPERAND_TYPE_SCOPE_ID, // SPIR-V Sec 3.27
+
+ // Set 2: Operands that are literal numbers.
+ SPV_OPERAND_TYPE_LITERAL_INTEGER, // Always unsigned 32-bits.
+ // The Instruction argument to OpExtInst. It's an unsigned 32-bit literal
+ // number indicating which instruction to use from an extended instruction
+ // set.
+ SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
+ // The Opcode argument to OpSpecConstantOp. It determines the operation
+ // to be performed on constant operands to compute a specialization constant
+ // result.
+ SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER,
+ // A literal number whose format and size are determined by a previous operand
+ // in the same instruction. It's a signed integer, an unsigned integer, or a
+ // floating point number. It also has a specified bit width. The width
+ // may be larger than 32, which would require such a typed literal value to
+ // occupy multiple SPIR-V words.
+ SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER,
+
+ // Set 3: The literal string operand type.
+ SPV_OPERAND_TYPE_LITERAL_STRING,
+
+ // Set 4: Operands that are a single word enumerated value.
+ SPV_OPERAND_TYPE_SOURCE_LANGUAGE, // SPIR-V Sec 3.2
+ SPV_OPERAND_TYPE_EXECUTION_MODEL, // SPIR-V Sec 3.3
+ SPV_OPERAND_TYPE_ADDRESSING_MODEL, // SPIR-V Sec 3.4
+ SPV_OPERAND_TYPE_MEMORY_MODEL, // SPIR-V Sec 3.5
+ SPV_OPERAND_TYPE_EXECUTION_MODE, // SPIR-V Sec 3.6
+ SPV_OPERAND_TYPE_STORAGE_CLASS, // SPIR-V Sec 3.7
+ SPV_OPERAND_TYPE_DIMENSIONALITY, // SPIR-V Sec 3.8
+ SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, // SPIR-V Sec 3.9
+ SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, // SPIR-V Sec 3.10
+ SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, // SPIR-V Sec 3.11
+ SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, // SPIR-V Sec 3.12
+ SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, // SPIR-V Sec 3.13
+ SPV_OPERAND_TYPE_FP_ROUNDING_MODE, // SPIR-V Sec 3.16
+ SPV_OPERAND_TYPE_LINKAGE_TYPE, // SPIR-V Sec 3.17
+ SPV_OPERAND_TYPE_ACCESS_QUALIFIER, // SPIR-V Sec 3.18
+ SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, // SPIR-V Sec 3.19
+ SPV_OPERAND_TYPE_DECORATION, // SPIR-V Sec 3.20
+ SPV_OPERAND_TYPE_BUILT_IN, // SPIR-V Sec 3.21
+ SPV_OPERAND_TYPE_GROUP_OPERATION, // SPIR-V Sec 3.28
+ SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS, // SPIR-V Sec 3.29
+ SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, // SPIR-V Sec 3.30
+ SPV_OPERAND_TYPE_CAPABILITY, // SPIR-V Sec 3.31
+
+ // Set 5: Operands that are a single word bitmask.
+ // Sometimes a set bit indicates the instruction requires still more operands.
+ SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14
+ SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15
+ SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22
+ SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23
+ SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24
+ SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26
+
+// The remaining operand types are only used internally by the assembler.
+// There are two categories:
+// Optional : expands to 0 or 1 operand, like ? in regular expressions.
+// Variable : expands to 0, 1 or many operands or pairs of operands.
+// This is similar to * in regular expressions.
+
+// Macros for defining bounds on optional and variable operand types.
+// Any variable operand type is also optional.
+#define FIRST_OPTIONAL(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE = ENUM
+#define FIRST_VARIABLE(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE = ENUM
+#define LAST_VARIABLE(ENUM) \
+ ENUM, SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE = ENUM, \
+ SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE = ENUM
+
+ // An optional operand represents zero or one logical operands.
+ // In an instruction definition, this may only appear at the end of the
+ // operand types.
+ FIRST_OPTIONAL(SPV_OPERAND_TYPE_OPTIONAL_ID),
+ // An optional image operand type.
+ SPV_OPERAND_TYPE_OPTIONAL_IMAGE,
+ // An optional memory access type.
+ SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
+ // An optional literal integer.
+ SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER,
+ // An optional literal number, which may be either integer or floating point.
+ SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER,
+ // Like SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, but optional, and integral.
+ SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER,
+ // An optional literal string.
+ SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING,
+ // An optional access qualifier
+ SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER,
+ // An optional context-independent value, or CIV. CIVs are tokens that we can
+ // assemble regardless of where they occur -- literals, IDs, immediate
+ // integers, etc.
+ SPV_OPERAND_TYPE_OPTIONAL_CIV,
+
+ // A variable operand represents zero or more logical operands.
+ // In an instruction definition, this may only appear at the end of the
+ // operand types.
+ FIRST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID),
+ SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER,
+ // A sequence of zero or more pairs of (typed literal integer, Id).
+ // Expands to zero or more:
+ // (SPV_OPERAND_TYPE_TYPED_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID)
+ // where the literal number must always be an integer of some sort.
+ SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID,
+ // A sequence of zero or more pairs of (Id, Literal integer)
+ LAST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER),
+
+ // The following are concrete enum types.
+ SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, // DebugInfo Sec 3.2. A mask.
+ SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // DebugInfo Sec 3.3
+ SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, // DebugInfo Sec 3.4
+ SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, // DebugInfo Sec 3.5
+ SPV_OPERAND_TYPE_DEBUG_OPERATION, // DebugInfo Sec 3.6
+
+ // This is a sentinel value, and does not represent an operand type.
+ // It should come last.
+ SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,
+
+ SPV_FORCE_32_BIT_ENUM(spv_operand_type_t)
+} spv_operand_type_t;
+
+typedef enum spv_ext_inst_type_t {
+ SPV_EXT_INST_TYPE_NONE = 0,
+ SPV_EXT_INST_TYPE_GLSL_STD_450,
+ SPV_EXT_INST_TYPE_OPENCL_STD,
+ SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER,
+ SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX,
+ SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER,
+ SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT,
+ SPV_EXT_INST_TYPE_DEBUGINFO,
+
+ SPV_FORCE_32_BIT_ENUM(spv_ext_inst_type_t)
+} spv_ext_inst_type_t;
+
+// This determines at a high level the kind of a binary-encoded literal
+// number, but not the bit width.
+// In principle, these could probably be folded into new entries in
+// spv_operand_type_t. But then we'd have some special case differences
+// between the assembler and disassembler.
+typedef enum spv_number_kind_t {
+ SPV_NUMBER_NONE = 0, // The default for value initialization.
+ SPV_NUMBER_UNSIGNED_INT,
+ SPV_NUMBER_SIGNED_INT,
+ SPV_NUMBER_FLOATING,
+} spv_number_kind_t;
+
+typedef enum spv_text_to_binary_options_t {
+ SPV_TEXT_TO_BINARY_OPTION_NONE = SPV_BIT(0),
+ // Numeric IDs in the binary will have the same values as in the source.
+ // Non-numeric IDs are allocated by filling in the gaps, starting with 1
+ // and going up.
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS = SPV_BIT(1),
+ SPV_FORCE_32_BIT_ENUM(spv_text_to_binary_options_t)
+} spv_text_to_binary_options_t;
+
+typedef enum spv_binary_to_text_options_t {
+ SPV_BINARY_TO_TEXT_OPTION_NONE = SPV_BIT(0),
+ SPV_BINARY_TO_TEXT_OPTION_PRINT = SPV_BIT(1),
+ SPV_BINARY_TO_TEXT_OPTION_COLOR = SPV_BIT(2),
+ SPV_BINARY_TO_TEXT_OPTION_INDENT = SPV_BIT(3),
+ SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET = SPV_BIT(4),
+ // Do not output the module header as leading comments in the assembly.
+ SPV_BINARY_TO_TEXT_OPTION_NO_HEADER = SPV_BIT(5),
+ // Use friendly names where possible. The heuristic may expand over
+ // time, but will use common names for scalar types, and debug names from
+ // OpName instructions.
+ SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES = SPV_BIT(6),
+ SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t)
+} spv_binary_to_text_options_t;
+
+// Structures
+
+// Information about an operand parsed from a binary SPIR-V module.
+// Note that the values are not included. You still need access to the binary
+// to extract the values.
+typedef struct spv_parsed_operand_t {
+ // Location of the operand, in words from the start of the instruction.
+ uint16_t offset;
+ // Number of words occupied by this operand.
+ uint16_t num_words;
+ // The "concrete" operand type. See the definition of spv_operand_type_t
+ // for details.
+ spv_operand_type_t type;
+ // If type is a literal number type, then number_kind says whether it's
+ // a signed integer, an unsigned integer, or a floating point number.
+ spv_number_kind_t number_kind;
+ // The number of bits for a literal number type.
+ uint32_t number_bit_width;
+} spv_parsed_operand_t;
+
+// An instruction parsed from a binary SPIR-V module.
+typedef struct spv_parsed_instruction_t {
+ // An array of words for this instruction, in native endianness.
+ const uint32_t* words;
+ // The number of words in this instruction.
+ uint16_t num_words;
+ uint16_t opcode;
+ // The extended instruction type, if opcode is OpExtInst. Otherwise
+ // this is the "none" value.
+ spv_ext_inst_type_t ext_inst_type;
+ // The type id, or 0 if this instruction doesn't have one.
+ uint32_t type_id;
+ // The result id, or 0 if this instruction doesn't have one.
+ uint32_t result_id;
+ // The array of parsed operands.
+ const spv_parsed_operand_t* operands;
+ uint16_t num_operands;
+} spv_parsed_instruction_t;
+
+typedef struct spv_const_binary_t {
+ const uint32_t* code;
+ const size_t wordCount;
+} spv_const_binary_t;
+
+typedef struct spv_binary_t {
+ uint32_t* code;
+ size_t wordCount;
+} spv_binary_t;
+
+typedef struct spv_text_t {
+ const char* str;
+ size_t length;
+} spv_text_t;
+
+typedef struct spv_position_t {
+ size_t line;
+ size_t column;
+ size_t index;
+} spv_position_t;
+
+typedef struct spv_diagnostic_t {
+ spv_position_t position;
+ char* error;
+ bool isTextSource;
+} spv_diagnostic_t;
+
+// Opaque struct containing the context used to operate on a SPIR-V module.
+// Its object is used by various translation API functions.
+typedef struct spv_context_t spv_context_t;
+
+typedef struct spv_validator_options_t spv_validator_options_t;
+
+// Type Definitions
+
+typedef spv_const_binary_t* spv_const_binary;
+typedef spv_binary_t* spv_binary;
+typedef spv_text_t* spv_text;
+typedef spv_position_t* spv_position;
+typedef spv_diagnostic_t* spv_diagnostic;
+typedef const spv_context_t* spv_const_context;
+typedef spv_context_t* spv_context;
+typedef spv_validator_options_t* spv_validator_options;
+typedef const spv_validator_options_t* spv_const_validator_options;
+
+// Platform API
+
+// Returns the SPIRV-Tools software version as a null-terminated string.
+// The contents of the underlying storage is valid for the remainder of
+// the process.
+SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionString();
+// Returns a null-terminated string containing the name of the project,
+// the software version string, and commit details.
+// The contents of the underlying storage is valid for the remainder of
+// the process.
+SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionDetailsString();
+
+// Certain target environments impose additional restrictions on SPIR-V, so it's
+// often necessary to specify which one applies. SPV_ENV_UNIVERSAL means
+// environment-agnostic SPIR-V.
+typedef enum {
+ SPV_ENV_UNIVERSAL_1_0, // SPIR-V 1.0 latest revision, no other restrictions.
+ SPV_ENV_VULKAN_1_0, // Vulkan 1.0 latest revision.
+ SPV_ENV_UNIVERSAL_1_1, // SPIR-V 1.1 latest revision, no other restrictions.
+ SPV_ENV_OPENCL_2_1, // OpenCL Full Profile 2.1 latest revision.
+ SPV_ENV_OPENCL_2_2, // OpenCL Full Profile 2.2 latest revision.
+ SPV_ENV_OPENGL_4_0, // OpenGL 4.0 plus GL_ARB_gl_spirv, latest revisions.
+ SPV_ENV_OPENGL_4_1, // OpenGL 4.1 plus GL_ARB_gl_spirv, latest revisions.
+ SPV_ENV_OPENGL_4_2, // OpenGL 4.2 plus GL_ARB_gl_spirv, latest revisions.
+ SPV_ENV_OPENGL_4_3, // OpenGL 4.3 plus GL_ARB_gl_spirv, latest revisions.
+ // There is no variant for OpenGL 4.4.
+ SPV_ENV_OPENGL_4_5, // OpenGL 4.5 plus GL_ARB_gl_spirv, latest revisions.
+ SPV_ENV_UNIVERSAL_1_2, // SPIR-V 1.2, latest revision, no other restrictions.
+ SPV_ENV_OPENCL_1_2, // OpenCL Full Profile 1.2 plus cl_khr_il_program,
+ // latest revision.
+ SPV_ENV_OPENCL_EMBEDDED_1_2, // OpenCL Embedded Profile 1.2 plus
+ // cl_khr_il_program, latest revision.
+ SPV_ENV_OPENCL_2_0, // OpenCL Full Profile 2.0 plus cl_khr_il_program,
+ // latest revision.
+ SPV_ENV_OPENCL_EMBEDDED_2_0, // OpenCL Embedded Profile 2.0 plus
+ // cl_khr_il_program, latest revision.
+ SPV_ENV_OPENCL_EMBEDDED_2_1, // OpenCL Embedded Profile 2.1 latest revision.
+ SPV_ENV_OPENCL_EMBEDDED_2_2, // OpenCL Embedded Profile 2.2 latest revision.
+} spv_target_env;
+
+// SPIR-V Validator can be parameterized with the following Universal Limits.
+typedef enum {
+ spv_validator_limit_max_struct_members,
+ spv_validator_limit_max_struct_depth,
+ spv_validator_limit_max_local_variables,
+ spv_validator_limit_max_global_variables,
+ spv_validator_limit_max_switch_branches,
+ spv_validator_limit_max_function_args,
+ spv_validator_limit_max_control_flow_nesting_depth,
+ spv_validator_limit_max_access_chain_indexes,
+} spv_validator_limit;
+
+// Returns a string describing the given SPIR-V target environment.
+SPIRV_TOOLS_EXPORT const char* spvTargetEnvDescription(spv_target_env env);
+
+// Creates a context object. Returns null if env is invalid.
+SPIRV_TOOLS_EXPORT spv_context spvContextCreate(spv_target_env env);
+
+// Destroys the given context object.
+SPIRV_TOOLS_EXPORT void spvContextDestroy(spv_context context);
+
+// Creates a Validator options object with default options. Returns a valid
+// options object. The object remains valid until it is passed into
+// spvValidatorOptionsDestroy.
+SPIRV_TOOLS_EXPORT spv_validator_options spvValidatorOptionsCreate();
+
+// Destroys the given Validator options object.
+SPIRV_TOOLS_EXPORT void spvValidatorOptionsDestroy(
+ spv_validator_options options);
+
+// Records the maximum Universal Limit that is considered valid in the given
+// Validator options object. <options> argument must be a valid options object.
+SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetUniversalLimit(
+ spv_validator_options options, spv_validator_limit limit_type,
+ uint32_t limit);
+
+// Record whether or not the validator should relax the rules on types for
+// stores to structs. When relaxed, it will allow a type mismatch as long as
+// the types are structs with the same layout. Two structs have the same layout
+// if
+//
+// 1) the members of the structs are either the same type or are structs with
+// same layout, and
+//
+// 2) the decorations that affect the memory layout are identical for both
+// types. Other decorations are not relevant.
+SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxStoreStruct(
+ spv_validator_options options, bool val);
+
+// Records whether or not the validator should relax the rules on pointer usage
+// in logical addressing mode.
+//
+// When relaxed, it will allow the following usage cases of pointers:
+// 1) OpVariable allocating an object whose type is a pointer type
+// 2) OpReturnValue returning a pointer value
+SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxLogicalPointer(
+ spv_validator_options options, bool val);
+
+// Encodes the given SPIR-V assembly text to its binary representation. The
+// length parameter specifies the number of bytes for text. Encoded binary will
+// be stored into *binary. Any error will be written into *diagnostic if
+// diagnostic is non-null. The generated binary is independent of the context
+// and may outlive it.
+SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinary(const spv_const_context context,
+ const char* text,
+ const size_t length,
+ spv_binary* binary,
+ spv_diagnostic* diagnostic);
+
+// Encodes the given SPIR-V assembly text to its binary representation. Same as
+// spvTextToBinary but with options. The options parameter is a bit field of
+// spv_text_to_binary_options_t.
+SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinaryWithOptions(
+ const spv_const_context context, const char* text, const size_t length,
+ const uint32_t options, spv_binary* binary, spv_diagnostic* diagnostic);
+
+// Frees an allocated text stream. This is a no-op if the text parameter
+// is a null pointer.
+SPIRV_TOOLS_EXPORT void spvTextDestroy(spv_text text);
+
+// Decodes the given SPIR-V binary representation to its assembly text. The
+// word_count parameter specifies the number of words for binary. The options
+// parameter is a bit field of spv_binary_to_text_options_t. Decoded text will
+// be stored into *text. Any error will be written into *diagnostic if
+// diagnostic is non-null.
+SPIRV_TOOLS_EXPORT spv_result_t spvBinaryToText(const spv_const_context context,
+ const uint32_t* binary,
+ const size_t word_count,
+ const uint32_t options,
+ spv_text* text,
+ spv_diagnostic* diagnostic);
+
+// Frees a binary stream from memory. This is a no-op if binary is a null
+// pointer.
+SPIRV_TOOLS_EXPORT void spvBinaryDestroy(spv_binary binary);
+
+// Validates a SPIR-V binary for correctness. Any errors will be written into
+// *diagnostic if diagnostic is non-null.
+SPIRV_TOOLS_EXPORT spv_result_t spvValidate(const spv_const_context context,
+ const spv_const_binary binary,
+ spv_diagnostic* diagnostic);
+
+// Validates a SPIR-V binary for correctness. Uses the provided Validator
+// options. Any errors will be written into *diagnostic if diagnostic is
+// non-null.
+SPIRV_TOOLS_EXPORT spv_result_t spvValidateWithOptions(
+ const spv_const_context context, const spv_const_validator_options options,
+ const spv_const_binary binary, spv_diagnostic* diagnostic);
+
+// Validates a raw SPIR-V binary for correctness. Any errors will be written
+// into *diagnostic if diagnostic is non-null.
+SPIRV_TOOLS_EXPORT spv_result_t
+spvValidateBinary(const spv_const_context context, const uint32_t* words,
+ const size_t num_words, spv_diagnostic* diagnostic);
+
+// Creates a diagnostic object. The position parameter specifies the location in
+// the text/binary stream. The message parameter, copied into the diagnostic
+// object, contains the error message to display.
+SPIRV_TOOLS_EXPORT spv_diagnostic
+spvDiagnosticCreate(const spv_position position, const char* message);
+
+// Destroys a diagnostic object. This is a no-op if diagnostic is a null
+// pointer.
+SPIRV_TOOLS_EXPORT void spvDiagnosticDestroy(spv_diagnostic diagnostic);
+
+// Prints the diagnostic to stderr.
+SPIRV_TOOLS_EXPORT spv_result_t
+spvDiagnosticPrint(const spv_diagnostic diagnostic);
+
+// The binary parser interface.
+
+// A pointer to a function that accepts a parsed SPIR-V header.
+// The integer arguments are the 32-bit words from the header, as specified
+// in SPIR-V 1.0 Section 2.3 Table 1.
+// The function should return SPV_SUCCESS if parsing should continue.
+typedef spv_result_t (*spv_parsed_header_fn_t)(
+ void* user_data, spv_endianness_t endian, uint32_t magic, uint32_t version,
+ uint32_t generator, uint32_t id_bound, uint32_t reserved);
+
+// A pointer to a function that accepts a parsed SPIR-V instruction.
+// The parsed_instruction value is transient: it may be overwritten
+// or released immediately after the function has returned. That also
+// applies to the words array member of the parsed instruction. The
+// function should return SPV_SUCCESS if and only if parsing should
+// continue.
+typedef spv_result_t (*spv_parsed_instruction_fn_t)(
+ void* user_data, const spv_parsed_instruction_t* parsed_instruction);
+
+// Parses a SPIR-V binary, specified as counted sequence of 32-bit words.
+// Parsing feedback is provided via two callbacks provided as function
+// pointers. Each callback function pointer can be a null pointer, in
+// which case it is never called. Otherwise, in a valid parse the
+// parsed-header callback is called once, and then the parsed-instruction
+// callback once for each instruction in the stream. The user_data parameter
+// is supplied as context to the callbacks. Returns SPV_SUCCESS on successful
+// parse where the callbacks always return SPV_SUCCESS. For an invalid parse,
+// returns a status code other than SPV_SUCCESS, and if diagnostic is non-null
+// also emits a diagnostic. If a callback returns anything other than
+// SPV_SUCCESS, then that status code is returned, no further callbacks are
+// issued, and no additional diagnostics are emitted.
+SPIRV_TOOLS_EXPORT spv_result_t spvBinaryParse(
+ const spv_const_context context, void* user_data, const uint32_t* words,
+ const size_t num_words, spv_parsed_header_fn_t parse_header,
+ spv_parsed_instruction_fn_t parse_instruction, spv_diagnostic* diagnostic);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPIRV_TOOLS_LIBSPIRV_H_
diff --git a/include/spirv-tools/libspirv.hpp b/include/spirv-tools/libspirv.hpp
new file mode 100644
index 00000000..2e4aa628
--- /dev/null
+++ b/include/spirv-tools/libspirv.hpp
@@ -0,0 +1,174 @@
+// Copyright (c) 2016 Google Inc.
+//
+// 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.
+
+#ifndef SPIRV_TOOLS_LIBSPIRV_HPP_
+#define SPIRV_TOOLS_LIBSPIRV_HPP_
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "spirv-tools/libspirv.h"
+
+namespace spvtools {
+
+// Message consumer. The C strings for source and message are only alive for the
+// specific invocation.
+using MessageConsumer = std::function<void(
+ spv_message_level_t /* level */, const char* /* source */,
+ const spv_position_t& /* position */, const char* /* message */
+ )>;
+
+// C++ RAII wrapper around the C context object spv_context.
+class Context {
+ public:
+ // Constructs a context targeting the given environment |env|.
+ //
+ // The constructed instance will have an empty message consumer, which just
+ // ignores all messages from the library. Use SetMessageConsumer() to supply
+ // one if messages are of concern.
+ explicit Context(spv_target_env env);
+
+ // Enables move constructor/assignment operations.
+ Context(Context&& other);
+ Context& operator=(Context&& other);
+
+ // Disables copy constructor/assignment operations.
+ Context(const Context&) = delete;
+ Context& operator=(const Context&) = delete;
+
+ // Destructs this instance.
+ ~Context();
+
+ // Sets the message consumer to the given |consumer|. The |consumer| will be
+ // invoked once for each message communicated from the library.
+ void SetMessageConsumer(MessageConsumer consumer);
+
+ // Returns the underlying spv_context.
+ spv_context& CContext();
+ const spv_context& CContext() const;
+
+ private:
+ spv_context context_;
+};
+
+// A RAII wrapper around a validator options object.
+class ValidatorOptions {
+ public:
+ ValidatorOptions() : options_(spvValidatorOptionsCreate()) {}
+ ~ValidatorOptions() { spvValidatorOptionsDestroy(options_); }
+ // Allow implicit conversion to the underlying object.
+ operator spv_validator_options() const { return options_; }
+
+ // Sets a limit.
+ void SetUniversalLimit(spv_validator_limit limit_type, uint32_t limit) {
+ spvValidatorOptionsSetUniversalLimit(options_, limit_type, limit);
+ }
+
+ void SetRelaxStructStore(bool val) {
+ spvValidatorOptionsSetRelaxStoreStruct(options_, val);
+ }
+
+ // Records whether or not the validator should relax the rules on pointer
+ // usage in logical addressing mode.
+ //
+ // When relaxed, it will allow the following usage cases of pointers:
+ // 1) OpVariable allocating an object whose type is a pointer type
+ // 2) OpReturnValue returning a pointer value
+ void SetRelaxLogicalPointer(bool val) {
+ spvValidatorOptionsSetRelaxLogicalPointer(options_, val);
+ }
+
+ private:
+ spv_validator_options options_;
+};
+
+// C++ interface for SPIRV-Tools functionalities. It wraps the context
+// (including target environment and the corresponding SPIR-V grammar) and
+// provides methods for assembling, disassembling, and validating.
+//
+// Instances of this class provide basic thread-safety guarantee.
+class SpirvTools {
+ public:
+ enum {
+ // Default assembling option used by assemble():
+ kDefaultAssembleOption = SPV_TEXT_TO_BINARY_OPTION_NONE,
+
+ // Default disassembling option used by Disassemble():
+ // * Avoid prefix comments from decoding the SPIR-V module header, and
+ // * Use friendly names for variables.
+ kDefaultDisassembleOption = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
+ SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES
+ };
+
+ // Constructs an instance targeting the given environment |env|.
+ //
+ // The constructed instance will have an empty message consumer, which just
+ // ignores all messages from the library. Use SetMessageConsumer() to supply
+ // one if messages are of concern.
+ explicit SpirvTools(spv_target_env env);
+
+ // Disables copy/move constructor/assignment operations.
+ SpirvTools(const SpirvTools&) = delete;
+ SpirvTools(SpirvTools&&) = delete;
+ SpirvTools& operator=(const SpirvTools&) = delete;
+ SpirvTools& operator=(SpirvTools&&) = delete;
+
+ // Destructs this instance.
+ ~SpirvTools();
+
+ // Sets the message consumer to the given |consumer|. The |consumer| will be
+ // invoked once for each message communicated from the library.
+ void SetMessageConsumer(MessageConsumer consumer);
+
+ // Assembles the given assembly |text| and writes the result to |binary|.
+ // Returns true on successful assembling. |binary| will be kept untouched if
+ // assembling is unsuccessful.
+ bool Assemble(const std::string& text, std::vector<uint32_t>* binary,
+ uint32_t options = kDefaultAssembleOption) const;
+ // |text_size| specifies the number of bytes in |text|. A terminating null
+ // character is not required to present in |text| as long as |text| is valid.
+ bool Assemble(const char* text, size_t text_size,
+ std::vector<uint32_t>* binary,
+ uint32_t options = kDefaultAssembleOption) const;
+
+ // Disassembles the given SPIR-V |binary| with the given |options| and writes
+ // the assembly to |text|. Returns ture on successful disassembling. |text|
+ // will be kept untouched if diassembling is unsuccessful.
+ bool Disassemble(const std::vector<uint32_t>& binary, std::string* text,
+ uint32_t options = kDefaultDisassembleOption) const;
+ // |binary_size| specifies the number of words in |binary|.
+ bool Disassemble(const uint32_t* binary, size_t binary_size,
+ std::string* text,
+ uint32_t options = kDefaultDisassembleOption) const;
+
+ // Validates the given SPIR-V |binary|. Returns true if no issues are found.
+ // Otherwise, returns false and communicates issues via the message consumer
+ // registered.
+ bool Validate(const std::vector<uint32_t>& binary) const;
+ // |binary_size| specifies the number of words in |binary|.
+ bool Validate(const uint32_t* binary, size_t binary_size) const;
+ // Like the previous overload, but takes an options object.
+ bool Validate(const uint32_t* binary, size_t binary_size,
+ const ValidatorOptions& options) const;
+
+ private:
+ struct Impl; // Opaque struct for holding the data fields used by this class.
+ std::unique_ptr<Impl> impl_; // Unique pointer to implementation data.
+};
+
+} // namespace spvtools
+
+#endif // SPIRV_TOOLS_LIBSPIRV_HPP_
diff --git a/include/spirv-tools/linker.hpp b/include/spirv-tools/linker.hpp
new file mode 100644
index 00000000..df56251f
--- /dev/null
+++ b/include/spirv-tools/linker.hpp
@@ -0,0 +1,83 @@
+// Copyright (c) 2017 Pierre Moreau
+//
+// 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.
+
+#ifndef SPIRV_TOOLS_LINKER_HPP_
+#define SPIRV_TOOLS_LINKER_HPP_
+
+#include <cstdint>
+
+#include <memory>
+#include <vector>
+
+#include "libspirv.hpp"
+
+namespace spvtools {
+
+class LinkerOptions {
+ public:
+ LinkerOptions() : create_library_(false), verify_ids_(false) {}
+
+ // Returns whether a library or an executable should be produced by the
+ // linking phase.
+ //
+ // All exported symbols are kept when creating a library, whereas they will
+ // be removed when creating an executable.
+ // The returned value will be true if creating a library, and false if
+ // creating an executable.
+ bool GetCreateLibrary() const { return create_library_; }
+
+ // Sets whether a library or an executable should be produced.
+ void SetCreateLibrary(bool create_library) {
+ create_library_ = create_library;
+ }
+
+ // Returns whether to verify the uniqueness of the unique ids in the merged
+ // context.
+ bool GetVerifyIds() const { return verify_ids_; }
+
+ // Sets whether to verify the uniqueness of the unique ids in the merged
+ // context.
+ void SetVerifyIds(bool verify_ids) { verify_ids_ = verify_ids; }
+
+ private:
+ bool create_library_;
+ bool verify_ids_;
+};
+
+// Links one or more SPIR-V modules into a new SPIR-V module. That is, combine
+// several SPIR-V modules into one, resolving link dependencies between them.
+//
+// At least one binary has to be provided in |binaries|. Those binaries do not
+// have to be valid, but they should be at least parseable.
+// The functions can fail due to the following:
+// * The given context was not initialised using `spvContextCreate()`;
+// * No input modules were given;
+// * One or more of those modules were not parseable;
+// * The input modules used different addressing or memory models;
+// * The ID or global variable number limit were exceeded;
+// * Some entry points were defined multiple times;
+// * Some imported symbols did not have an exported counterpart;
+// * Possibly other reasons.
+spv_result_t Link(const Context& context,
+ const std::vector<std::vector<uint32_t>>& binaries,
+ std::vector<uint32_t>* linked_binary,
+ const LinkerOptions& options = LinkerOptions());
+spv_result_t Link(const Context& context, const uint32_t* const* binaries,
+ const size_t* binary_sizes, size_t num_binaries,
+ std::vector<uint32_t>* linked_binary,
+ const LinkerOptions& options = LinkerOptions());
+
+} // namespace spvtools
+
+#endif // SPIRV_TOOLS_LINKER_HPP_
diff --git a/include/spirv-tools/optimizer.hpp b/include/spirv-tools/optimizer.hpp
new file mode 100644
index 00000000..9f3b3601
--- /dev/null
+++ b/include/spirv-tools/optimizer.hpp
@@ -0,0 +1,525 @@
+// Copyright (c) 2016 Google Inc.
+//
+// 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.
+
+#ifndef SPIRV_TOOLS_OPTIMIZER_HPP_
+#define SPIRV_TOOLS_OPTIMIZER_HPP_
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "libspirv.hpp"
+
+namespace spvtools {
+
+// C++ interface for SPIR-V optimization functionalities. It wraps the context
+// (including target environment and the corresponding SPIR-V grammar) and
+// provides methods for registering optimization passes and optimizing.
+//
+// Instances of this class provides basic thread-safety guarantee.
+class Optimizer {
+ public:
+ // The token for an optimization pass. It is returned via one of the
+ // Create*Pass() standalone functions at the end of this header file and
+ // consumed by the RegisterPass() method. Tokens are one-time objects that
+ // only support move; copying is not allowed.
+ struct PassToken {
+ struct Impl; // Opaque struct for holding inernal data.
+
+ PassToken(std::unique_ptr<Impl>);
+
+ // Tokens can only be moved. Copying is disabled.
+ PassToken(const PassToken&) = delete;
+ PassToken(PassToken&&);
+ PassToken& operator=(const PassToken&) = delete;
+ PassToken& operator=(PassToken&&);
+
+ ~PassToken();
+
+ std::unique_ptr<Impl> impl_; // Unique pointer to internal data.
+ };
+
+ // Constructs an instance with the given target |env|, which is used to decode
+ // the binaries to be optimized later.
+ //
+ // The constructed instance will have an empty message consumer, which just
+ // ignores all messages from the library. Use SetMessageConsumer() to supply
+ // one if messages are of concern.
+ explicit Optimizer(spv_target_env env);
+
+ // Disables copy/move constructor/assignment operations.
+ Optimizer(const Optimizer&) = delete;
+ Optimizer(Optimizer&&) = delete;
+ Optimizer& operator=(const Optimizer&) = delete;
+ Optimizer& operator=(Optimizer&&) = delete;
+
+ // Destructs this instance.
+ ~Optimizer();
+
+ // Sets the message consumer to the given |consumer|. The |consumer| will be
+ // invoked once for each message communicated from the library.
+ void SetMessageConsumer(MessageConsumer consumer);
+
+ // Registers the given |pass| to this optimizer. Passes will be run in the
+ // exact order of registration. The token passed in will be consumed by this
+ // method.
+ Optimizer& RegisterPass(PassToken&& pass);
+
+ // Registers passes that attempt to improve performance of generated code.
+ // This sequence of passes is subject to constant review and will change
+ // from time to time.
+ Optimizer& RegisterPerformancePasses();
+
+ // Registers passes that attempt to improve the size of generated code.
+ // This sequence of passes is subject to constant review and will change
+ // from time to time.
+ Optimizer& RegisterSizePasses();
+
+ // Registers passes that attempt to legalize the generated code.
+ //
+ // Note: this recipe is specially for legalizing SPIR-V. It should be used
+ // by compilers after translating HLSL source code literally. It should
+ // *not* be used by general workloads for performance or size improvement.
+ //
+ // This sequence of passes is subject to constant review and will change
+ // from time to time.
+ Optimizer& RegisterLegalizationPasses();
+
+ // Optimizes the given SPIR-V module |original_binary| and writes the
+ // optimized binary into |optimized_binary|.
+ // Returns true on successful optimization, whether or not the module is
+ // modified. Returns false if errors occur when processing |original_binary|
+ // using any of the registered passes. In that case, no further passes are
+ // executed and the contents in |optimized_binary| may be invalid.
+ //
+ // It's allowed to alias |original_binary| to the start of |optimized_binary|.
+ bool Run(const uint32_t* original_binary, size_t original_binary_size,
+ std::vector<uint32_t>* optimized_binary) const;
+
+ // Returns a vector of strings with all the pass names added to this
+ // optimizer's pass manager. These strings are valid until the associated
+ // pass manager is destroyed.
+ std::vector<const char*> GetPassNames() const;
+
+ // Sets the option to print the disassembly before each pass and after the
+ // last pass. If |out| is null, then no output is generated. Otherwise,
+ // output is sent to the |out| output stream.
+ Optimizer& SetPrintAll(std::ostream* out);
+
+ private:
+ struct Impl; // Opaque struct for holding internal data.
+ std::unique_ptr<Impl> impl_; // Unique pointer to internal data.
+};
+
+// Creates a null pass.
+// A null pass does nothing to the SPIR-V module to be optimized.
+Optimizer::PassToken CreateNullPass();
+
+// Creates a strip-debug-info pass.
+// A strip-debug-info pass removes all debug instructions (as documented in
+// Section 3.32.2 of the SPIR-V spec) of the SPIR-V module to be optimized.
+Optimizer::PassToken CreateStripDebugInfoPass();
+
+// Creates an eliminate-dead-functions pass.
+// An eliminate-dead-functions pass will remove all functions that are not in
+// the call trees rooted at entry points and exported functions. These
+// functions are not needed because they will never be called.
+Optimizer::PassToken CreateEliminateDeadFunctionsPass();
+
+// Creates a set-spec-constant-default-value pass from a mapping from spec-ids
+// to the default values in the form of string.
+// A set-spec-constant-default-value pass sets the default values for the
+// spec constants that have SpecId decorations (i.e., those defined by
+// OpSpecConstant{|True|False} instructions).
+Optimizer::PassToken CreateSetSpecConstantDefaultValuePass(
+ const std::unordered_map<uint32_t, std::string>& id_value_map);
+
+// Creates a set-spec-constant-default-value pass from a mapping from spec-ids
+// to the default values in the form of bit pattern.
+// A set-spec-constant-default-value pass sets the default values for the
+// spec constants that have SpecId decorations (i.e., those defined by
+// OpSpecConstant{|True|False} instructions).
+Optimizer::PassToken CreateSetSpecConstantDefaultValuePass(
+ const std::unordered_map<uint32_t, std::vector<uint32_t>>& id_value_map);
+
+// Creates a flatten-decoration pass.
+// A flatten-decoration pass replaces grouped decorations with equivalent
+// ungrouped decorations. That is, it replaces each OpDecorationGroup
+// instruction and associated OpGroupDecorate and OpGroupMemberDecorate
+// instructions with equivalent OpDecorate and OpMemberDecorate instructions.
+// The pass does not attempt to preserve debug information for instructions
+// it removes.
+Optimizer::PassToken CreateFlattenDecorationPass();
+
+// Creates a freeze-spec-constant-value pass.
+// A freeze-spec-constant pass specializes the value of spec constants to
+// their default values. This pass only processes the spec constants that have
+// SpecId decorations (defined by OpSpecConstant, OpSpecConstantTrue, or
+// OpSpecConstantFalse instructions) and replaces them with their normal
+// counterparts (OpConstant, OpConstantTrue, or OpConstantFalse). The
+// corresponding SpecId annotation instructions will also be removed. This
+// pass does not fold the newly added normal constants and does not process
+// other spec constants defined by OpSpecConstantComposite or
+// OpSpecConstantOp.
+Optimizer::PassToken CreateFreezeSpecConstantValuePass();
+
+// Creates a fold-spec-constant-op-and-composite pass.
+// A fold-spec-constant-op-and-composite pass folds spec constants defined by
+// OpSpecConstantOp or OpSpecConstantComposite instruction, to normal Constants
+// defined by OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull, or
+// OpConstantComposite instructions. Note that spec constants defined with
+// OpSpecConstant, OpSpecConstantTrue, or OpSpecConstantFalse instructions are
+// not handled, as these instructions indicate their value are not determined
+// and can be changed in future. A spec constant is foldable if all of its
+// value(s) can be determined from the module. E.g., an integer spec constant
+// defined with OpSpecConstantOp instruction can be folded if its value won't
+// change later. This pass will replace the original OpSpecContantOp instruction
+// with an OpConstant instruction. When folding composite spec constants,
+// new instructions may be inserted to define the components of the composite
+// constant first, then the original spec constants will be replaced by
+// OpConstantComposite instructions.
+//
+// There are some operations not supported yet:
+// OpSConvert, OpFConvert, OpQuantizeToF16 and
+// all the operations under Kernel capability.
+// TODO(qining): Add support for the operations listed above.
+Optimizer::PassToken CreateFoldSpecConstantOpAndCompositePass();
+
+// Creates a unify-constant pass.
+// A unify-constant pass de-duplicates the constants. Constants with the exact
+// same value and identical form will be unified and only one constant will
+// be kept for each unique pair of type and value.
+// There are several cases not handled by this pass:
+// 1) Constants defined by OpConstantNull instructions (null constants) and
+// constants defined by OpConstantFalse, OpConstant or OpConstantComposite
+// with value 0 (zero-valued normal constants) are not considered equivalent.
+// So null constants won't be used to replace zero-valued normal constants,
+// vice versa.
+// 2) Whenever there are decorations to the constant's result id id, the
+// constant won't be handled, which means, it won't be used to replace any
+// other constants, neither can other constants replace it.
+// 3) NaN in float point format with different bit patterns are not unified.
+Optimizer::PassToken CreateUnifyConstantPass();
+
+// Creates a eliminate-dead-constant pass.
+// A eliminate-dead-constant pass removes dead constants, including normal
+// contants defined by OpConstant, OpConstantComposite, OpConstantTrue, or
+// OpConstantFalse and spec constants defined by OpSpecConstant,
+// OpSpecConstantComposite, OpSpecConstantTrue, OpSpecConstantFalse or
+// OpSpecConstantOp.
+Optimizer::PassToken CreateEliminateDeadConstantPass();
+
+// Creates a strength-reduction pass.
+// A strength-reduction pass will look for opportunities to replace an
+// instruction with an equivalent and less expensive one. For example,
+// multiplying by a power of 2 can be replaced by a bit shift.
+Optimizer::PassToken CreateStrengthReductionPass();
+
+// Creates a block merge pass.
+// This pass searches for blocks with a single Branch to a block with no
+// other predecessors and merges the blocks into a single block. Continue
+// blocks and Merge blocks are not candidates for the second block.
+//
+// The pass is most useful after Dead Branch Elimination, which can leave
+// such sequences of blocks. Merging them makes subsequent passes more
+// effective, such as single block local store-load elimination.
+//
+// While this pass reduces the number of occurrences of this sequence, at
+// this time it does not guarantee all such sequences are eliminated.
+//
+// Presence of phi instructions can inhibit this optimization. Handling
+// these is left for future improvements.
+Optimizer::PassToken CreateBlockMergePass();
+
+// Creates an exhaustive inline pass.
+// An exhaustive inline pass attempts to exhaustively inline all function
+// calls in all functions in an entry point call tree. The intent is to enable,
+// albeit through brute force, analysis and optimization across function
+// calls by subsequent optimization passes. As the inlining is exhaustive,
+// there is no attempt to optimize for size or runtime performance. Functions
+// that are not in the call tree of an entry point are not changed.
+Optimizer::PassToken CreateInlineExhaustivePass();
+
+// Creates an opaque inline pass.
+// An opaque inline pass inlines all function calls in all functions in all
+// entry point call trees where the called function contains an opaque type
+// in either its parameter types or return type. An opaque type is currently
+// defined as Image, Sampler or SampledImage. The intent is to enable, albeit
+// through brute force, analysis and optimization across these function calls
+// by subsequent passes in order to remove the storing of opaque types which is
+// not legal in Vulkan. Functions that are not in the call tree of an entry
+// point are not changed.
+Optimizer::PassToken CreateInlineOpaquePass();
+
+// Creates a single-block local variable load/store elimination pass.
+// For every entry point function, do single block memory optimization of
+// function variables referenced only with non-access-chain loads and stores.
+// For each targeted variable load, if previous store to that variable in the
+// block, replace the load's result id with the value id of the store.
+// If previous load within the block, replace the current load's result id
+// with the previous load's result id. In either case, delete the current
+// load. Finally, check if any remaining stores are useless, and delete store
+// and variable if possible.
+//
+// The presence of access chain references and function calls can inhibit
+// the above optimization.
+//
+// Only modules with relaxed logical addressing (see opt/instruction.h) are
+// currently processed.
+//
+// This pass is most effective if preceeded by Inlining and
+// LocalAccessChainConvert. This pass will reduce the work needed to be done
+// by LocalSingleStoreElim and LocalMultiStoreElim.
+//
+// Only functions in the call tree of an entry point are processed.
+Optimizer::PassToken CreateLocalSingleBlockLoadStoreElimPass();
+
+// Create dead branch elimination pass.
+// For each entry point function, this pass will look for SelectionMerge
+// BranchConditionals with constant condition and convert to a Branch to
+// the indicated label. It will delete resulting dead blocks.
+//
+// For all phi functions in merge block, replace all uses with the id
+// corresponding to the living predecessor.
+//
+// Note that some branches and blocks may be left to avoid creating invalid
+// control flow. Improving this is left to future work.
+//
+// This pass is most effective when preceeded by passes which eliminate
+// local loads and stores, effectively propagating constant values where
+// possible.
+Optimizer::PassToken CreateDeadBranchElimPass();
+
+// Creates an SSA local variable load/store elimination pass.
+// For every entry point function, eliminate all loads and stores of function
+// scope variables only referenced with non-access-chain loads and stores.
+// Eliminate the variables as well.
+//
+// The presence of access chain references and function calls can inhibit
+// the above optimization.
+//
+// Only shader modules with relaxed logical addressing (see opt/instruction.h)
+// are currently processed. Currently modules with any extensions enabled are
+// not processed. This is left for future work.
+//
+// This pass is most effective if preceeded by Inlining and
+// LocalAccessChainConvert. LocalSingleStoreElim and LocalSingleBlockElim
+// will reduce the work that this pass has to do.
+Optimizer::PassToken CreateLocalMultiStoreElimPass();
+
+// Creates a local access chain conversion pass.
+// A local access chain conversion pass identifies all function scope
+// variables which are accessed only with loads, stores and access chains
+// with constant indices. It then converts all loads and stores of such
+// variables into equivalent sequences of loads, stores, extracts and inserts.
+//
+// This pass only processes entry point functions. It currently only converts
+// non-nested, non-ptr access chains. It does not process modules with
+// non-32-bit integer types present. Optional memory access options on loads
+// and stores are ignored as we are only processing function scope variables.
+//
+// This pass unifies access to these variables to a single mode and simplifies
+// subsequent analysis and elimination of these variables along with their
+// loads and stores allowing values to propagate to their points of use where
+// possible.
+Optimizer::PassToken CreateLocalAccessChainConvertPass();
+
+// Creates a local single store elimination pass.
+// For each entry point function, this pass eliminates loads and stores for
+// function scope variable that are stored to only once, where possible. Only
+// whole variable loads and stores are eliminated; access-chain references are
+// not optimized. Replace all loads of such variables with the value that is
+// stored and eliminate any resulting dead code.
+//
+// Currently, the presence of access chains and function calls can inhibit this
+// pass, however the Inlining and LocalAccessChainConvert passes can make it
+// more effective. In additional, many non-load/store memory operations are
+// not supported and will prohibit optimization of a function. Support of
+// these operations are future work.
+//
+// Only shader modules with relaxed logical addressing (see opt/instruction.h)
+// are currently processed.
+//
+// This pass will reduce the work needed to be done by LocalSingleBlockElim
+// and LocalMultiStoreElim and can improve the effectiveness of other passes
+// such as DeadBranchElimination which depend on values for their analysis.
+Optimizer::PassToken CreateLocalSingleStoreElimPass();
+
+// Creates an insert/extract elimination pass.
+// This pass processes each entry point function in the module, searching for
+// extracts on a sequence of inserts. It further searches the sequence for an
+// insert with indices identical to the extract. If such an insert can be
+// found before hitting a conflicting insert, the extract's result id is
+// replaced with the id of the values from the insert.
+//
+// Besides removing extracts this pass enables subsequent dead code elimination
+// passes to delete the inserts. This pass performs best after access chains are
+// converted to inserts and extracts and local loads and stores are eliminated.
+Optimizer::PassToken CreateInsertExtractElimPass();
+
+// Creates a dead insert elimination pass.
+// This pass processes each entry point function in the module, searching for
+// unreferenced inserts into composite types. These are most often unused
+// stores to vector components. They are unused because they are never
+// referenced, or because there is another insert to the same component between
+// the insert and the reference. After removing the inserts, dead code
+// elimination is attempted on the inserted values.
+//
+// This pass performs best after access chains are converted to inserts and
+// extracts and local loads and stores are eliminated. While executing this
+// pass can be advantageous on its own, it is also advantageous to execute
+// this pass after CreateInsertExtractPass() as it will remove any unused
+// inserts created by that pass.
+Optimizer::PassToken CreateDeadInsertElimPass();
+
+// Creates a pass to consolidate uniform references.
+// For each entry point function in the module, first change all constant index
+// access chain loads into equivalent composite extracts. Then consolidate
+// identical uniform loads into one uniform load. Finally, consolidate
+// identical uniform extracts into one uniform extract. This may require
+// moving a load or extract to a point which dominates all uses.
+//
+// This pass requires a module to have structured control flow ie shader
+// capability. It also requires logical addressing ie Addresses capability
+// is not enabled. It also currently does not support any extensions.
+//
+// This pass currently only optimizes loads with a single index.
+Optimizer::PassToken CreateCommonUniformElimPass();
+
+// Create aggressive dead code elimination pass
+// This pass eliminates unused code from the module. In addition,
+// it detects and eliminates code which may have spurious uses but which do
+// not contribute to the output of the function. The most common cause of
+// such code sequences is summations in loops whose result is no longer used
+// due to dead code elimination. This optimization has additional compile
+// time cost over standard dead code elimination.
+//
+// This pass only processes entry point functions. It also only processes
+// shaders with relaxed logical addressing (see opt/instruction.h). It
+// currently will not process functions with function calls. Unreachable
+// functions are deleted.
+//
+// This pass will be made more effective by first running passes that remove
+// dead control flow and inlines function calls.
+//
+// This pass can be especially useful after running Local Access Chain
+// Conversion, which tends to cause cycles of dead code to be left after
+// Store/Load elimination passes are completed. These cycles cannot be
+// eliminated with standard dead code elimination.
+Optimizer::PassToken CreateAggressiveDCEPass();
+
+// Creates a compact ids pass.
+// The pass remaps result ids to a compact and gapless range starting from %1.
+Optimizer::PassToken CreateCompactIdsPass();
+
+// Creates a remove duplicate pass.
+// This pass removes various duplicates:
+// * duplicate capabilities;
+// * duplicate extended instruction imports;
+// * duplicate types;
+// * duplicate decorations.
+Optimizer::PassToken CreateRemoveDuplicatesPass();
+
+// Creates a CFG cleanup pass.
+// This pass removes cruft from the control flow graph of functions that are
+// reachable from entry points and exported functions. It currently includes the
+// following functionality:
+//
+// - Removal of unreachable basic blocks.
+Optimizer::PassToken CreateCFGCleanupPass();
+
+// Create dead variable elimination pass.
+// This pass will delete module scope variables, along with their decorations,
+// that are not referenced.
+Optimizer::PassToken CreateDeadVariableEliminationPass();
+
+// Create merge return pass.
+// This pass replaces all returns with unconditional branches to a new block
+// containing a return. If necessary, this new block will contain a PHI node to
+// select the correct return value.
+//
+// This pass does not consider unreachable code, nor does it perform any other
+// optimizations.
+//
+// This pass does not currently support structured control flow. It bails out if
+// the shader capability is detected.
+Optimizer::PassToken CreateMergeReturnPass();
+
+// Create value numbering pass.
+// This pass will look for instructions in the same basic block that compute the
+// same value, and remove the redundant ones.
+Optimizer::PassToken CreateLocalRedundancyEliminationPass();
+
+// Create LICM pass.
+// This pass will look for invariant instructions inside loops and hoist them to
+// the loops preheader.
+Optimizer::PassToken CreateLoopInvariantCodeMotionPass();
+
+// Create global value numbering pass.
+// This pass will look for instructions where the same value is computed on all
+// paths leading to the instruction. Those instructions are deleted.
+Optimizer::PassToken CreateRedundancyEliminationPass();
+
+// Create scalar replacement pass.
+// This pass replaces composite function scope variables with variables for each
+// element if those elements are accessed individually.
+Optimizer::PassToken CreateScalarReplacementPass();
+
+// Create a private to local pass.
+// This pass looks for variables delcared in the private storage class that are
+// used in only one function. Those variables are moved to the function storage
+// class in the function that they are used.
+Optimizer::PassToken CreatePrivateToLocalPass();
+
+// Creates a conditional constant propagation (CCP) pass.
+// This pass implements the SSA-CCP algorithm in
+//
+// Constant propagation with conditional branches,
+// Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
+//
+// Constant values in expressions and conditional jumps are folded and
+// simplified. This may reduce code size by removing never executed jump targets
+// and computations with constant operands.
+Optimizer::PassToken CreateCCPPass();
+
+// Creates a workaround driver bugs pass. This pass attempts to work around
+// a known driver bug (issue #1209) by identifying the bad code sequences and
+// rewriting them.
+//
+// Current workaround: Avoid OpUnreachable instructions in loops.
+Optimizer::PassToken CreateWorkaround1209Pass();
+
+// Creates a pass that converts if-then-else like assignments into OpSelect.
+Optimizer::PassToken CreateIfConversionPass();
+
+// Creates a pass that will replace instructions that are not valid for the
+// current shader stage by constants. Has no effect on non-shader modules.
+Optimizer::PassToken CreateReplaceInvalidOpcodePass();
+
+// Creates a pass that simplifies instructions using the instruction folder.
+Optimizer::PassToken CreateSimplificationPass();
+
+// Create loop unroller pass.
+// Creates a pass to fully unroll loops which have the "Unroll" loop control
+// mask set. The loops must meet a specific criteria in order to be unrolled
+// safely this criteria is checked before doing the unroll by the
+// LoopUtils::CanPerformUnroll method. Any loop that does not meet the criteria
+// won't be unrolled. See CanPerformUnroll LoopUtils.h for more information.
+Optimizer::PassToken CreateLoopFullyUnrollPass();
+
+} // namespace spvtools
+
+#endif // SPIRV_TOOLS_OPTIMIZER_HPP_