blob: 304260668d5056336b1150492d7e1321df8a4b38 [file] [log] [blame]
Dejan Mircevskib6fe02f2016-01-07 13:44:22 -05001// Copyright (c) 2015-2016 The Khronos Group Inc.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01002//
David Neto9fc86582016-09-01 15:33:59 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01006//
David Neto9fc86582016-09-01 15:33:59 -04007// http://www.apache.org/licenses/LICENSE-2.0
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01008//
David Neto9fc86582016-09-01 15:33:59 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010014
dan sinclaireda2cfb2018-08-03 15:06:09 -040015#include "source/operand.h"
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010016
17#include <assert.h>
18#include <string.h>
alan-baker45fb6962019-05-10 11:02:01 -040019
Chris Forbes78338d52017-06-27 16:28:22 -070020#include <algorithm>
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010021
Jaebaek Seodd37d732020-01-23 17:04:30 -050022#include "DebugInfo.h"
23#include "OpenCLDebugInfo100.h"
dan sinclaireda2cfb2018-08-03 15:06:09 -040024#include "source/macro.h"
25#include "source/spirv_constant.h"
26#include "source/spirv_target_env.h"
David Netoba73a7c2016-01-06 13:08:39 -050027
David Neto00fa3932018-02-09 14:29:02 -050028// For now, assume unified1 contains up to SPIR-V 1.3 and no later
29// SPIR-V version.
30// TODO(dneto): Make one set of tables, but with version tags on a
31// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
32
David Neto00fa3932018-02-09 14:29:02 -050033#include "operand.kinds-unified1.inc"
David Neto64f36ea2019-12-19 17:16:26 -050034#include "spirv-tools/libspirv.h"
Lei Zhang16981f82017-09-21 17:24:57 -040035
Lei Zhang1ef6b192018-03-14 13:06:18 -040036static const spv_operand_table_t kOperandTable = {
37 ARRAY_SIZE(pygen_variable_OperandInfoTable),
38 pygen_variable_OperandInfoTable};
Lei Zhang063dbea2017-10-25 12:15:51 -040039
40spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
Lei Zhang1ef6b192018-03-14 13:06:18 -040041 spv_target_env) {
Lei Zhang063dbea2017-10-25 12:15:51 -040042 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010043
Lei Zhang1ef6b192018-03-14 13:06:18 -040044 *pOperandTable = &kOperandTable;
45 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010046}
47
Lei Zhang1ef6b192018-03-14 13:06:18 -040048spv_result_t spvOperandTableNameLookup(spv_target_env env,
49 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010050 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040051 const char* name,
52 const size_t nameLength,
53 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040054 if (!table) return SPV_ERROR_INVALID_TABLE;
55 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010056
alan-baker45fb6962019-05-10 11:02:01 -040057 const auto version = spvVersionForTargetEnv(env);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010058 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040059 const auto& group = table->types[typeIndex];
60 if (type != group.type) continue;
61 for (uint64_t index = 0; index < group.count; ++index) {
62 const auto& entry = group.entries[index];
David Neto363bfca2018-06-05 23:07:51 -070063 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -040064 // 1. The target environment satisfies the minimal requirement of the
65 // operand; or
David Neto363bfca2018-06-05 23:07:51 -070066 // 2. There is at least one extension enabling this operand; or
67 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -040068 //
69 // Note that the second rule assumes the extension enabling this operand
70 // is indeed requested in the SPIR-V code; checking that should be
71 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -040072 if (((version >= entry.minVersion && version <= entry.lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -070073 entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
Lei Zhang1ef6b192018-03-14 13:06:18 -040074 nameLength == strlen(entry.name) &&
Lei Zhangca1bf942016-04-27 16:47:13 -040075 !strncmp(entry.name, name, nameLength)) {
76 *pEntry = &entry;
77 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010078 }
79 }
80 }
81
82 return SPV_ERROR_INVALID_LOOKUP;
83}
84
Lei Zhang1ef6b192018-03-14 13:06:18 -040085spv_result_t spvOperandTableValueLookup(spv_target_env env,
86 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010087 const spv_operand_type_t type,
88 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040089 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040090 if (!table) return SPV_ERROR_INVALID_TABLE;
91 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010092
alan-baker45fb6962019-05-10 11:02:01 -040093 spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u};
Lei Zhang1ef6b192018-03-14 13:06:18 -040094
95 auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
96 return lhs.value < rhs.value;
97 };
98
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010099 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -0400100 const auto& group = table->types[typeIndex];
101 if (type != group.type) continue;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400102
103 const auto beg = group.entries;
104 const auto end = group.entries + group.count;
105
106 // We need to loop here because there can exist multiple symbols for the
107 // same operand value, and they can be introduced in different target
108 // environments, which means they can have different minimal version
109 // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
110 // version as long as the SPV_KHR_shader_ballot extension is there; but
111 // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
112 // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
113 // requirements.
114 // Assumes the underlying table is already sorted ascendingly according to
115 // opcode value.
alan-baker45fb6962019-05-10 11:02:01 -0400116 const auto version = spvVersionForTargetEnv(env);
Lei Zhang1ef6b192018-03-14 13:06:18 -0400117 for (auto it = std::lower_bound(beg, end, needle, comp);
118 it != end && it->value == value; ++it) {
David Neto363bfca2018-06-05 23:07:51 -0700119 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -0400120 // 1. The target environment satisfies the minimal requirement of the
121 // operand; or
David Neto363bfca2018-06-05 23:07:51 -0700122 // 2. There is at least one extension enabling this operand; or
123 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -0400124 //
125 // Note that the second rule assumes the extension enabling this operand
126 // is indeed requested in the SPIR-V code; checking that should be
127 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -0400128 if ((version >= it->minVersion && version <= it->lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -0700129 it->numExtensions > 0u || it->numCapabilities > 0u) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400130 *pEntry = it;
Lei Zhangca1bf942016-04-27 16:47:13 -0400131 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100132 }
133 }
134 }
135
136 return SPV_ERROR_INVALID_LOOKUP;
137}
138
Dejan Mircevski50babb22015-09-29 10:56:32 -0400139const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100140 switch (type) {
141 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400142 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400143 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500144 case SPV_OPERAND_TYPE_TYPE_ID:
145 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100146 case SPV_OPERAND_TYPE_RESULT_ID:
147 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400148 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500149 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
150 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100151 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500152 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
153 return "possibly multi-word literal integer";
154 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
155 return "possibly multi-word literal number";
156 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
157 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500158 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
159 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100160 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500161 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100162 return "literal string";
163 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400164 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100165 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
166 return "execution model";
167 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
168 return "addressing model";
169 case SPV_OPERAND_TYPE_MEMORY_MODEL:
170 return "memory model";
171 case SPV_OPERAND_TYPE_EXECUTION_MODE:
172 return "execution mode";
173 case SPV_OPERAND_TYPE_STORAGE_CLASS:
174 return "storage class";
175 case SPV_OPERAND_TYPE_DIMENSIONALITY:
176 return "dimensionality";
177 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500178 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100179 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
180 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400181 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400182 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100183 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400184 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100185 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400186 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100187 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
188 return "linkage type";
189 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500190 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100191 return "access qualifier";
192 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
193 return "function parameter attribute";
194 case SPV_OPERAND_TYPE_DECORATION:
195 return "decoration";
196 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400197 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100198 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
199 return "selection control";
200 case SPV_OPERAND_TYPE_LOOP_CONTROL:
201 return "loop control";
202 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
203 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500204 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500205 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500206 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400207 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100208 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500209 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500210 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100211 case SPV_OPERAND_TYPE_GROUP_OPERATION:
212 return "group operation";
213 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
214 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400215 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100216 return "kernel profiling info";
217 case SPV_OPERAND_TYPE_CAPABILITY:
218 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500219 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400220 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500221 return "image";
David Neto201caf72015-11-04 17:38:17 -0500222 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
223 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500224 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
225 return "debug info flags";
226 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
227 return "debug base type encoding";
228 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
229 return "debug composite type";
230 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
231 return "debug type qualifier";
232 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
233 return "debug operation";
David Neto64f36ea2019-12-19 17:16:26 -0500234 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
235 return "OpenCL.DebugInfo.100 debug info flags";
236 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
237 return "OpenCL.DebugInfo.100 debug base type encoding";
238 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
239 return "OpenCL.DebugInfo.100 debug composite type";
240 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
241 return "OpenCL.DebugInfo.100 debug type qualifier";
242 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
243 return "OpenCL.DebugInfo.100 debug operation";
244 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
245 return "OpenCL.DebugInfo.100 debug imported entity";
David Neto201caf72015-11-04 17:38:17 -0500246
247 // The next values are for values returned from an instruction, not actually
248 // an operand. So the specific strings don't matter. But let's add them
249 // for completeness and ease of testing.
250 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
251 return "image channel order";
252 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
253 return "image channel data type";
254
David Neto78c3b432015-08-27 13:03:52 -0400255 case SPV_OPERAND_TYPE_NONE:
256 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100257 default:
258 assert(0 && "Unhandled operand type!");
259 break;
260 }
261 return "unknown";
262}
David Neto78c3b432015-08-27 13:03:52 -0400263
Chris Forbes78338d52017-06-27 16:28:22 -0700264void spvPushOperandTypes(const spv_operand_type_t* types,
265 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400266 const spv_operand_type_t* endTypes;
dan sinclair84846b72018-07-10 13:09:46 -0400267 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
268 }
269
Chris Forbes78338d52017-06-27 16:28:22 -0700270 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400271 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700272 }
David Neto78c3b432015-08-27 13:03:52 -0400273}
274
Lei Zhang1ef6b192018-03-14 13:06:18 -0400275void spvPushOperandTypesForMask(spv_target_env env,
276 const spv_operand_table operandTable,
Chris Forbes78338d52017-06-27 16:28:22 -0700277 const spv_operand_type_t type,
278 const uint32_t mask,
279 spv_operand_pattern_t* pattern) {
280 // Scan from highest bits to lowest bits because we will append in LIFO
281 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400282 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
283 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400284 if (candidate_bit & mask) {
285 spv_operand_desc entry = nullptr;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400286 if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
David Neto5bf88fc2015-09-17 17:06:10 -0400287 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700288 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400289 }
290 }
291 }
292}
293
David Neto0dbe1842017-12-03 14:26:16 -0500294bool spvOperandIsConcrete(spv_operand_type_t type) {
295 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
296 return true;
297 }
298 switch (type) {
299 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
300 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
301 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
302 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
303 case SPV_OPERAND_TYPE_LITERAL_STRING:
304 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
305 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
306 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
307 case SPV_OPERAND_TYPE_MEMORY_MODEL:
308 case SPV_OPERAND_TYPE_EXECUTION_MODE:
309 case SPV_OPERAND_TYPE_STORAGE_CLASS:
310 case SPV_OPERAND_TYPE_DIMENSIONALITY:
311 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
312 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
313 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
314 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
315 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
316 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
317 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
318 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
319 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
320 case SPV_OPERAND_TYPE_DECORATION:
321 case SPV_OPERAND_TYPE_BUILT_IN:
322 case SPV_OPERAND_TYPE_GROUP_OPERATION:
323 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
324 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
325 case SPV_OPERAND_TYPE_CAPABILITY:
David Neto59de6102017-12-03 12:30:08 -0500326 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
327 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
328 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
329 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
David Neto64f36ea2019-12-19 17:16:26 -0500330 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
331 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
332 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
333 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
334 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
David Neto0dbe1842017-12-03 14:26:16 -0500335 return true;
336 default:
337 break;
338 }
339 return false;
340}
341
David Netob5267562016-02-02 12:05:34 -0500342bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500343 switch (type) {
344 case SPV_OPERAND_TYPE_IMAGE:
345 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
346 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
347 case SPV_OPERAND_TYPE_LOOP_CONTROL:
348 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
349 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto59de6102017-12-03 12:30:08 -0500350 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
David Neto64f36ea2019-12-19 17:16:26 -0500351 case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
David Neto0dbe1842017-12-03 14:26:16 -0500352 return true;
353 default:
354 break;
355 }
356 return false;
David Netob5267562016-02-02 12:05:34 -0500357}
358
David Neto78c3b432015-08-27 13:03:52 -0400359bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500360 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
361 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400362}
363
364bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500365 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
366 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400367}
368
David Neto78c3b432015-08-27 13:03:52 -0400369bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
370 spv_operand_pattern_t* pattern) {
371 switch (type) {
372 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700373 pattern->push_back(type);
374 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400375 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400376 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
Chris Forbes78338d52017-06-27 16:28:22 -0700377 pattern->push_back(type);
378 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400379 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400380 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500381 // Represents Zero or more (Literal number, Id) pairs,
382 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700383 pattern->push_back(type);
384 pattern->push_back(SPV_OPERAND_TYPE_ID);
385 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400386 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400387 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400388 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700389 pattern->push_back(type);
390 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
391 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400392 return true;
David Neto78c3b432015-08-27 13:03:52 -0400393 default:
394 break;
395 }
396 return false;
397}
398
Dejan Mircevski50babb22015-09-29 10:56:32 -0400399spv_operand_type_t spvTakeFirstMatchableOperand(
400 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400401 assert(!pattern->empty());
402 spv_operand_type_t result;
403 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700404 result = pattern->back();
405 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400406 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400407 return result;
408}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400409
Dejan Mircevski897bff92015-09-29 10:38:18 -0400410spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
411 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400412 auto it =
413 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700414 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400415 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
416 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700417 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
418 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400419 }
Chris Forbes78338d52017-06-27 16:28:22 -0700420
Dejan Mircevski897bff92015-09-29 10:38:18 -0400421 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400422 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400423}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500424
425bool spvIsIdType(spv_operand_type_t type) {
426 switch (type) {
427 case SPV_OPERAND_TYPE_ID:
428 case SPV_OPERAND_TYPE_TYPE_ID:
429 case SPV_OPERAND_TYPE_RESULT_ID:
430 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
431 case SPV_OPERAND_TYPE_SCOPE_ID:
432 return true;
433 default:
434 return false;
435 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500436}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400437
Alastair Donaldson3b130402018-11-26 22:06:21 +0000438bool spvIsInIdType(spv_operand_type_t type) {
439 if (!spvIsIdType(type)) {
440 // If it is not an ID it cannot be an input ID.
441 return false;
442 }
443 switch (type) {
444 // Blacklist non-input IDs.
445 case SPV_OPERAND_TYPE_TYPE_ID:
446 case SPV_OPERAND_TYPE_RESULT_ID:
447 return false;
448 default:
449 return true;
450 }
451}
452
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400453std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
454 SpvOp opcode) {
455 std::function<bool(unsigned index)> out;
456 switch (opcode) {
457 case SpvOpExecutionMode:
Lei Zhangefcc33e2018-05-16 08:43:50 -0400458 case SpvOpExecutionModeId:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400459 case SpvOpEntryPoint:
460 case SpvOpName:
461 case SpvOpMemberName:
462 case SpvOpSelectionMerge:
463 case SpvOpDecorate:
464 case SpvOpMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500465 case SpvOpDecorateId:
466 case SpvOpDecorateStringGOOGLE:
467 case SpvOpMemberDecorateStringGOOGLE:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400468 case SpvOpTypeStruct:
469 case SpvOpBranch:
470 case SpvOpLoopMerge:
471 out = [](unsigned) { return true; };
472 break;
473 case SpvOpGroupDecorate:
474 case SpvOpGroupMemberDecorate:
475 case SpvOpBranchConditional:
476 case SpvOpSwitch:
477 out = [](unsigned index) { return index != 0; };
478 break;
479
480 case SpvOpFunctionCall:
481 // The Function parameter.
482 out = [](unsigned index) { return index == 2; };
483 break;
484
485 case SpvOpPhi:
486 out = [](unsigned index) { return index > 1; };
487 break;
488
489 case SpvOpEnqueueKernel:
490 // The Invoke parameter.
491 out = [](unsigned index) { return index == 8; };
492 break;
493
494 case SpvOpGetKernelNDrangeSubGroupCount:
495 case SpvOpGetKernelNDrangeMaxSubGroupSize:
496 // The Invoke parameter.
497 out = [](unsigned index) { return index == 3; };
498 break;
499
500 case SpvOpGetKernelWorkGroupSize:
501 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
502 // The Invoke parameter.
503 out = [](unsigned index) { return index == 2; };
504 break;
505 case SpvOpTypeForwardPointer:
506 out = [](unsigned index) { return index == 0; };
507 break;
alan-baker899735f2020-01-07 13:55:46 -0500508 case SpvOpTypeArray:
509 out = [](unsigned index) { return index == 1; };
510 break;
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400511 default:
512 out = [](unsigned) { return false; };
513 break;
514 }
515 return out;
516}
Jaebaek Seodd37d732020-01-23 17:04:30 -0500517
518std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
519 spv_ext_inst_type_t ext_type, uint32_t key) {
520 // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
521 // references for debug info instructions are still in discussion. We must
522 // update the following lines of code when we conclude the spec.
523 std::function<bool(unsigned index)> out;
524 if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
525 switch (OpenCLDebugInfo100Instructions(key)) {
526 case OpenCLDebugInfo100DebugFunction:
527 out = [](unsigned index) { return index == 13; };
528 break;
529 case OpenCLDebugInfo100DebugTypeComposite:
530 out = [](unsigned index) { return index >= 13; };
531 break;
532 default:
533 out = [](unsigned) { return false; };
534 break;
535 }
536 } else {
537 switch (DebugInfoInstructions(key)) {
538 case DebugInfoDebugFunction:
539 out = [](unsigned index) { return index == 13; };
540 break;
541 case DebugInfoDebugTypeComposite:
542 out = [](unsigned index) { return index >= 12; };
543 break;
544 default:
545 out = [](unsigned) { return false; };
546 break;
547 }
548 }
549 return out;
550}