blob: bff36a26999cb7a30c86e4681d2bd2be150342f6 [file] [log] [blame]
Daniel Koch5a97e3a2020-03-17 15:30:19 -04001// Copyright (c) 2015-2020 The Khronos Group Inc.
2// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
3// reserved.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01004//
David Neto9fc86582016-09-01 15:33:59 -04005// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01008//
David Neto9fc86582016-09-01 15:33:59 -04009// http://www.apache.org/licenses/LICENSE-2.0
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010010//
David Neto9fc86582016-09-01 15:33:59 -040011// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010016
dan sinclaireda2cfb2018-08-03 15:06:09 -040017#include "source/operand.h"
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010018
19#include <assert.h>
20#include <string.h>
alan-baker45fb6962019-05-10 11:02:01 -040021
Chris Forbes78338d52017-06-27 16:28:22 -070022#include <algorithm>
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010023
Jaebaek Seodd37d732020-01-23 17:04:30 -050024#include "DebugInfo.h"
25#include "OpenCLDebugInfo100.h"
dan sinclaireda2cfb2018-08-03 15:06:09 -040026#include "source/macro.h"
alan-baker862d44a2020-12-08 08:46:47 -050027#include "source/opcode.h"
dan sinclaireda2cfb2018-08-03 15:06:09 -040028#include "source/spirv_constant.h"
29#include "source/spirv_target_env.h"
David Netoba73a7c2016-01-06 13:08:39 -050030
David Neto00fa3932018-02-09 14:29:02 -050031// For now, assume unified1 contains up to SPIR-V 1.3 and no later
32// SPIR-V version.
33// TODO(dneto): Make one set of tables, but with version tags on a
34// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
35
David Neto00fa3932018-02-09 14:29:02 -050036#include "operand.kinds-unified1.inc"
David Neto64f36ea2019-12-19 17:16:26 -050037#include "spirv-tools/libspirv.h"
Lei Zhang16981f82017-09-21 17:24:57 -040038
Lei Zhang1ef6b192018-03-14 13:06:18 -040039static const spv_operand_table_t kOperandTable = {
40 ARRAY_SIZE(pygen_variable_OperandInfoTable),
41 pygen_variable_OperandInfoTable};
Lei Zhang063dbea2017-10-25 12:15:51 -040042
43spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
Lei Zhang1ef6b192018-03-14 13:06:18 -040044 spv_target_env) {
Lei Zhang063dbea2017-10-25 12:15:51 -040045 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010046
Lei Zhang1ef6b192018-03-14 13:06:18 -040047 *pOperandTable = &kOperandTable;
48 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010049}
50
Lei Zhang1ef6b192018-03-14 13:06:18 -040051spv_result_t spvOperandTableNameLookup(spv_target_env env,
52 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010053 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040054 const char* name,
55 const size_t nameLength,
56 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040057 if (!table) return SPV_ERROR_INVALID_TABLE;
58 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010059
alan-baker45fb6962019-05-10 11:02:01 -040060 const auto version = spvVersionForTargetEnv(env);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010061 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040062 const auto& group = table->types[typeIndex];
63 if (type != group.type) continue;
64 for (uint64_t index = 0; index < group.count; ++index) {
65 const auto& entry = group.entries[index];
David Neto363bfca2018-06-05 23:07:51 -070066 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -040067 // 1. The target environment satisfies the minimal requirement of the
68 // operand; or
David Neto363bfca2018-06-05 23:07:51 -070069 // 2. There is at least one extension enabling this operand; or
70 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -040071 //
72 // Note that the second rule assumes the extension enabling this operand
73 // is indeed requested in the SPIR-V code; checking that should be
74 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -040075 if (((version >= entry.minVersion && version <= entry.lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -070076 entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
Lei Zhang1ef6b192018-03-14 13:06:18 -040077 nameLength == strlen(entry.name) &&
Lei Zhangca1bf942016-04-27 16:47:13 -040078 !strncmp(entry.name, name, nameLength)) {
79 *pEntry = &entry;
80 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010081 }
82 }
83 }
84
85 return SPV_ERROR_INVALID_LOOKUP;
86}
87
Lei Zhang1ef6b192018-03-14 13:06:18 -040088spv_result_t spvOperandTableValueLookup(spv_target_env env,
89 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010090 const spv_operand_type_t type,
91 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040092 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040093 if (!table) return SPV_ERROR_INVALID_TABLE;
94 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010095
alan-baker45fb6962019-05-10 11:02:01 -040096 spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u};
Lei Zhang1ef6b192018-03-14 13:06:18 -040097
98 auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
99 return lhs.value < rhs.value;
100 };
101
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100102 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -0400103 const auto& group = table->types[typeIndex];
104 if (type != group.type) continue;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400105
106 const auto beg = group.entries;
107 const auto end = group.entries + group.count;
108
109 // We need to loop here because there can exist multiple symbols for the
110 // same operand value, and they can be introduced in different target
111 // environments, which means they can have different minimal version
112 // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
113 // version as long as the SPV_KHR_shader_ballot extension is there; but
114 // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
115 // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
116 // requirements.
117 // Assumes the underlying table is already sorted ascendingly according to
118 // opcode value.
alan-baker45fb6962019-05-10 11:02:01 -0400119 const auto version = spvVersionForTargetEnv(env);
Lei Zhang1ef6b192018-03-14 13:06:18 -0400120 for (auto it = std::lower_bound(beg, end, needle, comp);
121 it != end && it->value == value; ++it) {
David Neto363bfca2018-06-05 23:07:51 -0700122 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -0400123 // 1. The target environment satisfies the minimal requirement of the
124 // operand; or
David Neto363bfca2018-06-05 23:07:51 -0700125 // 2. There is at least one extension enabling this operand; or
126 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -0400127 //
128 // Note that the second rule assumes the extension enabling this operand
129 // is indeed requested in the SPIR-V code; checking that should be
130 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -0400131 if ((version >= it->minVersion && version <= it->lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -0700132 it->numExtensions > 0u || it->numCapabilities > 0u) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400133 *pEntry = it;
Lei Zhangca1bf942016-04-27 16:47:13 -0400134 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100135 }
136 }
137 }
138
139 return SPV_ERROR_INVALID_LOOKUP;
140}
141
Dejan Mircevski50babb22015-09-29 10:56:32 -0400142const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100143 switch (type) {
144 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400145 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400146 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500147 case SPV_OPERAND_TYPE_TYPE_ID:
148 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100149 case SPV_OPERAND_TYPE_RESULT_ID:
150 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400151 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500152 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
153 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100154 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500155 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
156 return "possibly multi-word literal integer";
157 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
158 return "possibly multi-word literal number";
159 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
160 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500161 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
162 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100163 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500164 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100165 return "literal string";
166 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400167 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100168 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
169 return "execution model";
170 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
171 return "addressing model";
172 case SPV_OPERAND_TYPE_MEMORY_MODEL:
173 return "memory model";
174 case SPV_OPERAND_TYPE_EXECUTION_MODE:
175 return "execution mode";
176 case SPV_OPERAND_TYPE_STORAGE_CLASS:
177 return "storage class";
178 case SPV_OPERAND_TYPE_DIMENSIONALITY:
179 return "dimensionality";
180 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500181 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100182 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
183 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400184 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400185 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100186 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400187 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100188 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400189 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100190 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
191 return "linkage type";
192 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500193 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100194 return "access qualifier";
195 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
196 return "function parameter attribute";
197 case SPV_OPERAND_TYPE_DECORATION:
198 return "decoration";
199 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400200 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100201 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
202 return "selection control";
203 case SPV_OPERAND_TYPE_LOOP_CONTROL:
204 return "loop control";
205 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
206 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500207 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500208 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500209 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400210 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100211 return "memory access";
Tobskia1d38172020-10-20 13:00:13 +0100212 case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
213 return "shading rate";
David Neto64a9be92015-11-18 15:48:32 -0500214 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500215 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100216 case SPV_OPERAND_TYPE_GROUP_OPERATION:
217 return "group operation";
218 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
219 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400220 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100221 return "kernel profiling info";
222 case SPV_OPERAND_TYPE_CAPABILITY:
223 return "capability";
Daniel Koch5a97e3a2020-03-17 15:30:19 -0400224 case SPV_OPERAND_TYPE_RAY_FLAGS:
225 return "ray flags";
226 case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
227 return "ray query intersection";
228 case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
229 return "ray query committed intersection type";
230 case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
231 return "ray query candidate intersection type";
Kévin Petite065c482021-06-23 18:32:24 +0100232 case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
233 case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
234 return "packed vector format";
David Neto201caf72015-11-04 17:38:17 -0500235 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400236 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500237 return "image";
David Neto201caf72015-11-04 17:38:17 -0500238 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
239 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500240 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
241 return "debug info flags";
242 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
243 return "debug base type encoding";
244 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
245 return "debug composite type";
246 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
247 return "debug type qualifier";
248 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
249 return "debug operation";
David Neto64f36ea2019-12-19 17:16:26 -0500250 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
251 return "OpenCL.DebugInfo.100 debug info flags";
252 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
253 return "OpenCL.DebugInfo.100 debug base type encoding";
254 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
255 return "OpenCL.DebugInfo.100 debug composite type";
256 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
257 return "OpenCL.DebugInfo.100 debug type qualifier";
258 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
259 return "OpenCL.DebugInfo.100 debug operation";
260 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
261 return "OpenCL.DebugInfo.100 debug imported entity";
David Neto201caf72015-11-04 17:38:17 -0500262
263 // The next values are for values returned from an instruction, not actually
264 // an operand. So the specific strings don't matter. But let's add them
265 // for completeness and ease of testing.
266 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
267 return "image channel order";
268 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
269 return "image channel data type";
270
David Neto1bd539b2021-01-20 09:39:51 -0500271 case SPV_OPERAND_TYPE_FPDENORM_MODE:
272 return "FP denorm mode";
273 case SPV_OPERAND_TYPE_FPOPERATION_MODE:
274 return "FP operation mode";
David Netobbc660e2021-06-09 16:20:39 -0400275 case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
276 return "quantization mode";
277 case SPV_OPERAND_TYPE_OVERFLOW_MODES:
278 return "overflow mode";
David Neto1bd539b2021-01-20 09:39:51 -0500279
David Neto78c3b432015-08-27 13:03:52 -0400280 case SPV_OPERAND_TYPE_NONE:
281 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100282 default:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100283 break;
284 }
285 return "unknown";
286}
David Neto78c3b432015-08-27 13:03:52 -0400287
Chris Forbes78338d52017-06-27 16:28:22 -0700288void spvPushOperandTypes(const spv_operand_type_t* types,
289 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400290 const spv_operand_type_t* endTypes;
dan sinclair84846b72018-07-10 13:09:46 -0400291 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
292 }
293
Chris Forbes78338d52017-06-27 16:28:22 -0700294 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400295 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700296 }
David Neto78c3b432015-08-27 13:03:52 -0400297}
298
Lei Zhang1ef6b192018-03-14 13:06:18 -0400299void spvPushOperandTypesForMask(spv_target_env env,
300 const spv_operand_table operandTable,
Chris Forbes78338d52017-06-27 16:28:22 -0700301 const spv_operand_type_t type,
302 const uint32_t mask,
303 spv_operand_pattern_t* pattern) {
304 // Scan from highest bits to lowest bits because we will append in LIFO
305 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400306 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
307 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400308 if (candidate_bit & mask) {
309 spv_operand_desc entry = nullptr;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400310 if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
David Neto5bf88fc2015-09-17 17:06:10 -0400311 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700312 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400313 }
314 }
315 }
316}
317
David Neto0dbe1842017-12-03 14:26:16 -0500318bool spvOperandIsConcrete(spv_operand_type_t type) {
319 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
320 return true;
321 }
322 switch (type) {
323 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
324 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
325 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
326 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
327 case SPV_OPERAND_TYPE_LITERAL_STRING:
328 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
329 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
330 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
331 case SPV_OPERAND_TYPE_MEMORY_MODEL:
332 case SPV_OPERAND_TYPE_EXECUTION_MODE:
333 case SPV_OPERAND_TYPE_STORAGE_CLASS:
334 case SPV_OPERAND_TYPE_DIMENSIONALITY:
335 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
336 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
337 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
338 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
339 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
340 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
341 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
342 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
343 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
344 case SPV_OPERAND_TYPE_DECORATION:
345 case SPV_OPERAND_TYPE_BUILT_IN:
346 case SPV_OPERAND_TYPE_GROUP_OPERATION:
347 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
348 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
349 case SPV_OPERAND_TYPE_CAPABILITY:
Daniel Koch5a97e3a2020-03-17 15:30:19 -0400350 case SPV_OPERAND_TYPE_RAY_FLAGS:
351 case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
352 case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
353 case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
David Neto59de6102017-12-03 12:30:08 -0500354 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
355 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
356 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
357 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
David Neto64f36ea2019-12-19 17:16:26 -0500358 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
359 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
360 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
361 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
362 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
David Neto1bd539b2021-01-20 09:39:51 -0500363 case SPV_OPERAND_TYPE_FPDENORM_MODE:
364 case SPV_OPERAND_TYPE_FPOPERATION_MODE:
David Netobbc660e2021-06-09 16:20:39 -0400365 case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
366 case SPV_OPERAND_TYPE_OVERFLOW_MODES:
Kévin Petite065c482021-06-23 18:32:24 +0100367 case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
David Neto0dbe1842017-12-03 14:26:16 -0500368 return true;
369 default:
370 break;
371 }
372 return false;
373}
374
David Netob5267562016-02-02 12:05:34 -0500375bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500376 switch (type) {
377 case SPV_OPERAND_TYPE_IMAGE:
378 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
379 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
380 case SPV_OPERAND_TYPE_LOOP_CONTROL:
381 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
382 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
Tobskia1d38172020-10-20 13:00:13 +0100383 case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
David Neto59de6102017-12-03 12:30:08 -0500384 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
David Neto64f36ea2019-12-19 17:16:26 -0500385 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
David Neto0dbe1842017-12-03 14:26:16 -0500386 return true;
387 default:
388 break;
389 }
390 return false;
David Netob5267562016-02-02 12:05:34 -0500391}
392
David Neto78c3b432015-08-27 13:03:52 -0400393bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto31c82132020-07-27 10:14:03 -0700394 switch (type) {
395 case SPV_OPERAND_TYPE_OPTIONAL_ID:
396 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
397 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
398 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
399 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
400 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
401 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
402 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kévin Petite065c482021-06-23 18:32:24 +0100403 case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
David Neto31c82132020-07-27 10:14:03 -0700404 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
405 return true;
406 default:
407 break;
408 }
409 // Any variable operand is also optional.
410 return spvOperandIsVariable(type);
David Neto78c3b432015-08-27 13:03:52 -0400411}
412
413bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto31c82132020-07-27 10:14:03 -0700414 switch (type) {
415 case SPV_OPERAND_TYPE_VARIABLE_ID:
416 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
417 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
418 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
419 return true;
420 default:
421 break;
422 }
423 return false;
David Neto78c3b432015-08-27 13:03:52 -0400424}
425
David Neto78c3b432015-08-27 13:03:52 -0400426bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
427 spv_operand_pattern_t* pattern) {
428 switch (type) {
429 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700430 pattern->push_back(type);
431 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400432 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400433 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
Chris Forbes78338d52017-06-27 16:28:22 -0700434 pattern->push_back(type);
435 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400436 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400437 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500438 // Represents Zero or more (Literal number, Id) pairs,
439 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700440 pattern->push_back(type);
441 pattern->push_back(SPV_OPERAND_TYPE_ID);
442 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400443 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400444 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400445 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700446 pattern->push_back(type);
447 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
448 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400449 return true;
David Neto78c3b432015-08-27 13:03:52 -0400450 default:
451 break;
452 }
453 return false;
454}
455
Dejan Mircevski50babb22015-09-29 10:56:32 -0400456spv_operand_type_t spvTakeFirstMatchableOperand(
457 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400458 assert(!pattern->empty());
459 spv_operand_type_t result;
460 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700461 result = pattern->back();
462 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400463 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400464 return result;
465}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400466
Dejan Mircevski897bff92015-09-29 10:38:18 -0400467spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
468 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400469 auto it =
470 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700471 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400472 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
473 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700474 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
475 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400476 }
Chris Forbes78338d52017-06-27 16:28:22 -0700477
Dejan Mircevski897bff92015-09-29 10:38:18 -0400478 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400479 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400480}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500481
482bool spvIsIdType(spv_operand_type_t type) {
483 switch (type) {
484 case SPV_OPERAND_TYPE_ID:
485 case SPV_OPERAND_TYPE_TYPE_ID:
486 case SPV_OPERAND_TYPE_RESULT_ID:
487 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
488 case SPV_OPERAND_TYPE_SCOPE_ID:
489 return true;
490 default:
491 return false;
492 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500493}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400494
Alastair Donaldson3b130402018-11-26 22:06:21 +0000495bool spvIsInIdType(spv_operand_type_t type) {
496 if (!spvIsIdType(type)) {
497 // If it is not an ID it cannot be an input ID.
498 return false;
499 }
500 switch (type) {
dan sinclair52a5f072020-06-15 13:20:40 -0400501 // Deny non-input IDs.
Alastair Donaldson3b130402018-11-26 22:06:21 +0000502 case SPV_OPERAND_TYPE_TYPE_ID:
503 case SPV_OPERAND_TYPE_RESULT_ID:
504 return false;
505 default:
506 return true;
507 }
508}
509
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400510std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
511 SpvOp opcode) {
512 std::function<bool(unsigned index)> out;
alan-baker862d44a2020-12-08 08:46:47 -0500513 if (spvOpcodeGeneratesType(opcode)) {
514 // All types can use forward pointers.
515 out = [](unsigned) { return true; };
516 return out;
517 }
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400518 switch (opcode) {
519 case SpvOpExecutionMode:
Lei Zhangefcc33e2018-05-16 08:43:50 -0400520 case SpvOpExecutionModeId:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400521 case SpvOpEntryPoint:
522 case SpvOpName:
523 case SpvOpMemberName:
524 case SpvOpSelectionMerge:
525 case SpvOpDecorate:
526 case SpvOpMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500527 case SpvOpDecorateId:
528 case SpvOpDecorateStringGOOGLE:
529 case SpvOpMemberDecorateStringGOOGLE:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400530 case SpvOpBranch:
531 case SpvOpLoopMerge:
532 out = [](unsigned) { return true; };
533 break;
534 case SpvOpGroupDecorate:
535 case SpvOpGroupMemberDecorate:
536 case SpvOpBranchConditional:
537 case SpvOpSwitch:
538 out = [](unsigned index) { return index != 0; };
539 break;
540
541 case SpvOpFunctionCall:
542 // The Function parameter.
543 out = [](unsigned index) { return index == 2; };
544 break;
545
546 case SpvOpPhi:
547 out = [](unsigned index) { return index > 1; };
548 break;
549
550 case SpvOpEnqueueKernel:
551 // The Invoke parameter.
552 out = [](unsigned index) { return index == 8; };
553 break;
554
555 case SpvOpGetKernelNDrangeSubGroupCount:
556 case SpvOpGetKernelNDrangeMaxSubGroupSize:
557 // The Invoke parameter.
558 out = [](unsigned index) { return index == 3; };
559 break;
560
561 case SpvOpGetKernelWorkGroupSize:
562 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
563 // The Invoke parameter.
564 out = [](unsigned index) { return index == 2; };
565 break;
566 case SpvOpTypeForwardPointer:
567 out = [](unsigned index) { return index == 0; };
568 break;
alan-baker899735f2020-01-07 13:55:46 -0500569 case SpvOpTypeArray:
570 out = [](unsigned index) { return index == 1; };
571 break;
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400572 default:
573 out = [](unsigned) { return false; };
574 break;
575 }
576 return out;
577}
Jaebaek Seodd37d732020-01-23 17:04:30 -0500578
579std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
580 spv_ext_inst_type_t ext_type, uint32_t key) {
Greg Fischer983ee232021-07-28 19:35:32 -0600581 // The Vulkan debug info extended instruction set is non-semantic so allows no
582 // forward references ever.
583 if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100) {
584 return [](unsigned) { return false; };
585 }
586
Jaebaek Seodd37d732020-01-23 17:04:30 -0500587 // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
588 // references for debug info instructions are still in discussion. We must
589 // update the following lines of code when we conclude the spec.
590 std::function<bool(unsigned index)> out;
591 if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
592 switch (OpenCLDebugInfo100Instructions(key)) {
593 case OpenCLDebugInfo100DebugFunction:
594 out = [](unsigned index) { return index == 13; };
595 break;
596 case OpenCLDebugInfo100DebugTypeComposite:
597 out = [](unsigned index) { return index >= 13; };
598 break;
599 default:
600 out = [](unsigned) { return false; };
601 break;
602 }
603 } else {
604 switch (DebugInfoInstructions(key)) {
605 case DebugInfoDebugFunction:
606 out = [](unsigned index) { return index == 13; };
607 break;
608 case DebugInfoDebugTypeComposite:
609 out = [](unsigned index) { return index >= 12; };
610 break;
611 default:
612 out = [](unsigned) { return false; };
613 break;
614 }
615 }
616 return out;
617}