blob: 7b2b98f2d1ad478ab165330562c9004916bbbc6e [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"
27#include "source/spirv_constant.h"
28#include "source/spirv_target_env.h"
David Netoba73a7c2016-01-06 13:08:39 -050029
David Neto00fa3932018-02-09 14:29:02 -050030// For now, assume unified1 contains up to SPIR-V 1.3 and no later
31// SPIR-V version.
32// TODO(dneto): Make one set of tables, but with version tags on a
33// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
34
David Neto00fa3932018-02-09 14:29:02 -050035#include "operand.kinds-unified1.inc"
David Neto64f36ea2019-12-19 17:16:26 -050036#include "spirv-tools/libspirv.h"
Lei Zhang16981f82017-09-21 17:24:57 -040037
Lei Zhang1ef6b192018-03-14 13:06:18 -040038static const spv_operand_table_t kOperandTable = {
39 ARRAY_SIZE(pygen_variable_OperandInfoTable),
40 pygen_variable_OperandInfoTable};
Lei Zhang063dbea2017-10-25 12:15:51 -040041
42spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
Lei Zhang1ef6b192018-03-14 13:06:18 -040043 spv_target_env) {
Lei Zhang063dbea2017-10-25 12:15:51 -040044 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010045
Lei Zhang1ef6b192018-03-14 13:06:18 -040046 *pOperandTable = &kOperandTable;
47 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010048}
49
Lei Zhang1ef6b192018-03-14 13:06:18 -040050spv_result_t spvOperandTableNameLookup(spv_target_env env,
51 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010052 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040053 const char* name,
54 const size_t nameLength,
55 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040056 if (!table) return SPV_ERROR_INVALID_TABLE;
57 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010058
alan-baker45fb6962019-05-10 11:02:01 -040059 const auto version = spvVersionForTargetEnv(env);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010060 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040061 const auto& group = table->types[typeIndex];
62 if (type != group.type) continue;
63 for (uint64_t index = 0; index < group.count; ++index) {
64 const auto& entry = group.entries[index];
David Neto363bfca2018-06-05 23:07:51 -070065 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -040066 // 1. The target environment satisfies the minimal requirement of the
67 // operand; or
David Neto363bfca2018-06-05 23:07:51 -070068 // 2. There is at least one extension enabling this operand; or
69 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -040070 //
71 // Note that the second rule assumes the extension enabling this operand
72 // is indeed requested in the SPIR-V code; checking that should be
73 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -040074 if (((version >= entry.minVersion && version <= entry.lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -070075 entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
Lei Zhang1ef6b192018-03-14 13:06:18 -040076 nameLength == strlen(entry.name) &&
Lei Zhangca1bf942016-04-27 16:47:13 -040077 !strncmp(entry.name, name, nameLength)) {
78 *pEntry = &entry;
79 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010080 }
81 }
82 }
83
84 return SPV_ERROR_INVALID_LOOKUP;
85}
86
Lei Zhang1ef6b192018-03-14 13:06:18 -040087spv_result_t spvOperandTableValueLookup(spv_target_env env,
88 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010089 const spv_operand_type_t type,
90 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040091 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040092 if (!table) return SPV_ERROR_INVALID_TABLE;
93 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010094
alan-baker45fb6962019-05-10 11:02:01 -040095 spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u};
Lei Zhang1ef6b192018-03-14 13:06:18 -040096
97 auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
98 return lhs.value < rhs.value;
99 };
100
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100101 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -0400102 const auto& group = table->types[typeIndex];
103 if (type != group.type) continue;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400104
105 const auto beg = group.entries;
106 const auto end = group.entries + group.count;
107
108 // We need to loop here because there can exist multiple symbols for the
109 // same operand value, and they can be introduced in different target
110 // environments, which means they can have different minimal version
111 // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
112 // version as long as the SPV_KHR_shader_ballot extension is there; but
113 // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
114 // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
115 // requirements.
116 // Assumes the underlying table is already sorted ascendingly according to
117 // opcode value.
alan-baker45fb6962019-05-10 11:02:01 -0400118 const auto version = spvVersionForTargetEnv(env);
Lei Zhang1ef6b192018-03-14 13:06:18 -0400119 for (auto it = std::lower_bound(beg, end, needle, comp);
120 it != end && it->value == value; ++it) {
David Neto363bfca2018-06-05 23:07:51 -0700121 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -0400122 // 1. The target environment satisfies the minimal requirement of the
123 // operand; or
David Neto363bfca2018-06-05 23:07:51 -0700124 // 2. There is at least one extension enabling this operand; or
125 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -0400126 //
127 // Note that the second rule assumes the extension enabling this operand
128 // is indeed requested in the SPIR-V code; checking that should be
129 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -0400130 if ((version >= it->minVersion && version <= it->lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -0700131 it->numExtensions > 0u || it->numCapabilities > 0u) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400132 *pEntry = it;
Lei Zhangca1bf942016-04-27 16:47:13 -0400133 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100134 }
135 }
136 }
137
138 return SPV_ERROR_INVALID_LOOKUP;
139}
140
Dejan Mircevski50babb22015-09-29 10:56:32 -0400141const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100142 switch (type) {
143 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400144 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400145 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500146 case SPV_OPERAND_TYPE_TYPE_ID:
147 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100148 case SPV_OPERAND_TYPE_RESULT_ID:
149 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400150 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500151 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
152 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100153 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500154 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
155 return "possibly multi-word literal integer";
156 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
157 return "possibly multi-word literal number";
158 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
159 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500160 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
161 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100162 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500163 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100164 return "literal string";
165 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400166 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100167 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
168 return "execution model";
169 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
170 return "addressing model";
171 case SPV_OPERAND_TYPE_MEMORY_MODEL:
172 return "memory model";
173 case SPV_OPERAND_TYPE_EXECUTION_MODE:
174 return "execution mode";
175 case SPV_OPERAND_TYPE_STORAGE_CLASS:
176 return "storage class";
177 case SPV_OPERAND_TYPE_DIMENSIONALITY:
178 return "dimensionality";
179 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500180 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100181 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
182 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400183 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400184 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100185 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400186 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100187 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400188 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100189 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
190 return "linkage type";
191 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500192 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100193 return "access qualifier";
194 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
195 return "function parameter attribute";
196 case SPV_OPERAND_TYPE_DECORATION:
197 return "decoration";
198 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400199 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100200 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
201 return "selection control";
202 case SPV_OPERAND_TYPE_LOOP_CONTROL:
203 return "loop control";
204 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
205 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500206 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500207 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500208 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400209 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100210 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500211 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500212 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100213 case SPV_OPERAND_TYPE_GROUP_OPERATION:
214 return "group operation";
215 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
216 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400217 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100218 return "kernel profiling info";
219 case SPV_OPERAND_TYPE_CAPABILITY:
220 return "capability";
Daniel Koch5a97e3a2020-03-17 15:30:19 -0400221 case SPV_OPERAND_TYPE_RAY_FLAGS:
222 return "ray flags";
223 case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
224 return "ray query intersection";
225 case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
226 return "ray query committed intersection type";
227 case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
228 return "ray query candidate intersection type";
David Neto201caf72015-11-04 17:38:17 -0500229 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400230 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500231 return "image";
David Neto201caf72015-11-04 17:38:17 -0500232 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
233 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500234 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
235 return "debug info flags";
236 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
237 return "debug base type encoding";
238 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
239 return "debug composite type";
240 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
241 return "debug type qualifier";
242 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
243 return "debug operation";
David Neto64f36ea2019-12-19 17:16:26 -0500244 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
245 return "OpenCL.DebugInfo.100 debug info flags";
246 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
247 return "OpenCL.DebugInfo.100 debug base type encoding";
248 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
249 return "OpenCL.DebugInfo.100 debug composite type";
250 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
251 return "OpenCL.DebugInfo.100 debug type qualifier";
252 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
253 return "OpenCL.DebugInfo.100 debug operation";
254 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
255 return "OpenCL.DebugInfo.100 debug imported entity";
David Neto201caf72015-11-04 17:38:17 -0500256
257 // The next values are for values returned from an instruction, not actually
258 // an operand. So the specific strings don't matter. But let's add them
259 // for completeness and ease of testing.
260 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
261 return "image channel order";
262 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
263 return "image channel data type";
264
David Neto78c3b432015-08-27 13:03:52 -0400265 case SPV_OPERAND_TYPE_NONE:
266 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100267 default:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100268 break;
269 }
270 return "unknown";
271}
David Neto78c3b432015-08-27 13:03:52 -0400272
Chris Forbes78338d52017-06-27 16:28:22 -0700273void spvPushOperandTypes(const spv_operand_type_t* types,
274 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400275 const spv_operand_type_t* endTypes;
dan sinclair84846b72018-07-10 13:09:46 -0400276 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
277 }
278
Chris Forbes78338d52017-06-27 16:28:22 -0700279 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400280 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700281 }
David Neto78c3b432015-08-27 13:03:52 -0400282}
283
Lei Zhang1ef6b192018-03-14 13:06:18 -0400284void spvPushOperandTypesForMask(spv_target_env env,
285 const spv_operand_table operandTable,
Chris Forbes78338d52017-06-27 16:28:22 -0700286 const spv_operand_type_t type,
287 const uint32_t mask,
288 spv_operand_pattern_t* pattern) {
289 // Scan from highest bits to lowest bits because we will append in LIFO
290 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400291 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
292 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400293 if (candidate_bit & mask) {
294 spv_operand_desc entry = nullptr;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400295 if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
David Neto5bf88fc2015-09-17 17:06:10 -0400296 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700297 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400298 }
299 }
300 }
301}
302
David Neto0dbe1842017-12-03 14:26:16 -0500303bool spvOperandIsConcrete(spv_operand_type_t type) {
304 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
305 return true;
306 }
307 switch (type) {
308 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
309 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
310 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
311 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
312 case SPV_OPERAND_TYPE_LITERAL_STRING:
313 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
314 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
315 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
316 case SPV_OPERAND_TYPE_MEMORY_MODEL:
317 case SPV_OPERAND_TYPE_EXECUTION_MODE:
318 case SPV_OPERAND_TYPE_STORAGE_CLASS:
319 case SPV_OPERAND_TYPE_DIMENSIONALITY:
320 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
321 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
322 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
323 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
324 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
325 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
326 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
327 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
328 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
329 case SPV_OPERAND_TYPE_DECORATION:
330 case SPV_OPERAND_TYPE_BUILT_IN:
331 case SPV_OPERAND_TYPE_GROUP_OPERATION:
332 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
333 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
334 case SPV_OPERAND_TYPE_CAPABILITY:
Daniel Koch5a97e3a2020-03-17 15:30:19 -0400335 case SPV_OPERAND_TYPE_RAY_FLAGS:
336 case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
337 case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
338 case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
David Neto59de6102017-12-03 12:30:08 -0500339 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
340 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
341 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
342 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
David Neto64f36ea2019-12-19 17:16:26 -0500343 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
344 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
345 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
346 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
347 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
David Neto0dbe1842017-12-03 14:26:16 -0500348 return true;
349 default:
350 break;
351 }
352 return false;
353}
354
David Netob5267562016-02-02 12:05:34 -0500355bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500356 switch (type) {
357 case SPV_OPERAND_TYPE_IMAGE:
358 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
359 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
360 case SPV_OPERAND_TYPE_LOOP_CONTROL:
361 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
362 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto59de6102017-12-03 12:30:08 -0500363 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
David Neto64f36ea2019-12-19 17:16:26 -0500364 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
David Neto0dbe1842017-12-03 14:26:16 -0500365 return true;
366 default:
367 break;
368 }
369 return false;
David Netob5267562016-02-02 12:05:34 -0500370}
371
David Neto78c3b432015-08-27 13:03:52 -0400372bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto31c82132020-07-27 10:14:03 -0700373 switch (type) {
374 case SPV_OPERAND_TYPE_OPTIONAL_ID:
375 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
376 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
377 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
378 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
379 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
380 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
381 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
382 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
383 return true;
384 default:
385 break;
386 }
387 // Any variable operand is also optional.
388 return spvOperandIsVariable(type);
David Neto78c3b432015-08-27 13:03:52 -0400389}
390
391bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto31c82132020-07-27 10:14:03 -0700392 switch (type) {
393 case SPV_OPERAND_TYPE_VARIABLE_ID:
394 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
395 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
396 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
397 return true;
398 default:
399 break;
400 }
401 return false;
David Neto78c3b432015-08-27 13:03:52 -0400402}
403
David Neto78c3b432015-08-27 13:03:52 -0400404bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
405 spv_operand_pattern_t* pattern) {
406 switch (type) {
407 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700408 pattern->push_back(type);
409 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400410 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400411 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
Chris Forbes78338d52017-06-27 16:28:22 -0700412 pattern->push_back(type);
413 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400414 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400415 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500416 // Represents Zero or more (Literal number, Id) pairs,
417 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700418 pattern->push_back(type);
419 pattern->push_back(SPV_OPERAND_TYPE_ID);
420 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400421 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400422 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400423 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700424 pattern->push_back(type);
425 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
426 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400427 return true;
David Neto78c3b432015-08-27 13:03:52 -0400428 default:
429 break;
430 }
431 return false;
432}
433
Dejan Mircevski50babb22015-09-29 10:56:32 -0400434spv_operand_type_t spvTakeFirstMatchableOperand(
435 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400436 assert(!pattern->empty());
437 spv_operand_type_t result;
438 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700439 result = pattern->back();
440 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400441 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400442 return result;
443}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400444
Dejan Mircevski897bff92015-09-29 10:38:18 -0400445spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
446 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400447 auto it =
448 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700449 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400450 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
451 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700452 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
453 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400454 }
Chris Forbes78338d52017-06-27 16:28:22 -0700455
Dejan Mircevski897bff92015-09-29 10:38:18 -0400456 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400457 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400458}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500459
460bool spvIsIdType(spv_operand_type_t type) {
461 switch (type) {
462 case SPV_OPERAND_TYPE_ID:
463 case SPV_OPERAND_TYPE_TYPE_ID:
464 case SPV_OPERAND_TYPE_RESULT_ID:
465 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
466 case SPV_OPERAND_TYPE_SCOPE_ID:
467 return true;
468 default:
469 return false;
470 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500471}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400472
Alastair Donaldson3b130402018-11-26 22:06:21 +0000473bool spvIsInIdType(spv_operand_type_t type) {
474 if (!spvIsIdType(type)) {
475 // If it is not an ID it cannot be an input ID.
476 return false;
477 }
478 switch (type) {
dan sinclair52a5f072020-06-15 13:20:40 -0400479 // Deny non-input IDs.
Alastair Donaldson3b130402018-11-26 22:06:21 +0000480 case SPV_OPERAND_TYPE_TYPE_ID:
481 case SPV_OPERAND_TYPE_RESULT_ID:
482 return false;
483 default:
484 return true;
485 }
486}
487
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400488std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
489 SpvOp opcode) {
490 std::function<bool(unsigned index)> out;
491 switch (opcode) {
492 case SpvOpExecutionMode:
Lei Zhangefcc33e2018-05-16 08:43:50 -0400493 case SpvOpExecutionModeId:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400494 case SpvOpEntryPoint:
495 case SpvOpName:
496 case SpvOpMemberName:
497 case SpvOpSelectionMerge:
498 case SpvOpDecorate:
499 case SpvOpMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500500 case SpvOpDecorateId:
501 case SpvOpDecorateStringGOOGLE:
502 case SpvOpMemberDecorateStringGOOGLE:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400503 case SpvOpTypeStruct:
504 case SpvOpBranch:
505 case SpvOpLoopMerge:
506 out = [](unsigned) { return true; };
507 break;
508 case SpvOpGroupDecorate:
509 case SpvOpGroupMemberDecorate:
510 case SpvOpBranchConditional:
511 case SpvOpSwitch:
512 out = [](unsigned index) { return index != 0; };
513 break;
514
515 case SpvOpFunctionCall:
516 // The Function parameter.
517 out = [](unsigned index) { return index == 2; };
518 break;
519
520 case SpvOpPhi:
521 out = [](unsigned index) { return index > 1; };
522 break;
523
524 case SpvOpEnqueueKernel:
525 // The Invoke parameter.
526 out = [](unsigned index) { return index == 8; };
527 break;
528
529 case SpvOpGetKernelNDrangeSubGroupCount:
530 case SpvOpGetKernelNDrangeMaxSubGroupSize:
531 // The Invoke parameter.
532 out = [](unsigned index) { return index == 3; };
533 break;
534
535 case SpvOpGetKernelWorkGroupSize:
536 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
537 // The Invoke parameter.
538 out = [](unsigned index) { return index == 2; };
539 break;
540 case SpvOpTypeForwardPointer:
541 out = [](unsigned index) { return index == 0; };
542 break;
alan-baker899735f2020-01-07 13:55:46 -0500543 case SpvOpTypeArray:
544 out = [](unsigned index) { return index == 1; };
545 break;
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400546 default:
547 out = [](unsigned) { return false; };
548 break;
549 }
550 return out;
551}
Jaebaek Seodd37d732020-01-23 17:04:30 -0500552
553std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
554 spv_ext_inst_type_t ext_type, uint32_t key) {
555 // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
556 // references for debug info instructions are still in discussion. We must
557 // update the following lines of code when we conclude the spec.
558 std::function<bool(unsigned index)> out;
559 if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
560 switch (OpenCLDebugInfo100Instructions(key)) {
561 case OpenCLDebugInfo100DebugFunction:
562 out = [](unsigned index) { return index == 13; };
563 break;
564 case OpenCLDebugInfo100DebugTypeComposite:
565 out = [](unsigned index) { return index >= 13; };
566 break;
567 default:
568 out = [](unsigned) { return false; };
569 break;
570 }
571 } else {
572 switch (DebugInfoInstructions(key)) {
573 case DebugInfoDebugFunction:
574 out = [](unsigned index) { return index == 13; };
575 break;
576 case DebugInfoDebugTypeComposite:
577 out = [](unsigned index) { return index >= 12; };
578 break;
579 default:
580 out = [](unsigned) { return false; };
581 break;
582 }
583 }
584 return out;
585}