operand.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. // Copyright (c) 2015-2020 The Khronos Group Inc.
  2. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
  3. // reserved.
  4. //
  5. // 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
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // 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.
  16. #include "source/operand.h"
  17. #include <assert.h>
  18. #include <string.h>
  19. #include <algorithm>
  20. #include "DebugInfo.h"
  21. #include "OpenCLDebugInfo100.h"
  22. #include "source/macro.h"
  23. #include "source/opcode.h"
  24. #include "source/spirv_constant.h"
  25. // For now, assume unified1 contains up to SPIR-V 1.3 and no later
  26. // SPIR-V version.
  27. // TODO(dneto): Make one set of tables, but with version tags on a
  28. // per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
  29. #include "operand.kinds-unified1.inc"
  30. #include "spirv-tools/libspirv.h"
  31. static const spv_operand_table_t kOperandTable = {
  32. ARRAY_SIZE(pygen_variable_OperandInfoTable),
  33. pygen_variable_OperandInfoTable};
  34. spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
  35. spv_target_env) {
  36. if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
  37. *pOperandTable = &kOperandTable;
  38. return SPV_SUCCESS;
  39. }
  40. spv_result_t spvOperandTableNameLookup(spv_target_env,
  41. const spv_operand_table table,
  42. const spv_operand_type_t type,
  43. const char* name,
  44. const size_t nameLength,
  45. spv_operand_desc* pEntry) {
  46. if (!table) return SPV_ERROR_INVALID_TABLE;
  47. if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
  48. for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
  49. const auto& group = table->types[typeIndex];
  50. if (type != group.type) continue;
  51. for (uint64_t index = 0; index < group.count; ++index) {
  52. const auto& entry = group.entries[index];
  53. // We consider the current operand as available as long as
  54. // it is in the grammar. It might not be *valid* to use,
  55. // but that should be checked by the validator, not by parsing.
  56. //
  57. // Exact match case
  58. if (nameLength == strlen(entry.name) &&
  59. !strncmp(entry.name, name, nameLength)) {
  60. *pEntry = &entry;
  61. return SPV_SUCCESS;
  62. }
  63. // Check the aliases. Ideally we would have a version of the table sorted
  64. // by name and then we could iterate between the lower and upper bounds to
  65. // restrict the amount comparisons. Fortunately, name-based lookups are
  66. // mostly restricted to the assembler.
  67. if (entry.numAliases > 0) {
  68. for (uint32_t aliasIndex = 0; aliasIndex < entry.numAliases;
  69. aliasIndex++) {
  70. const auto alias = entry.aliases[aliasIndex];
  71. const size_t aliasLength = strlen(alias);
  72. if (nameLength == aliasLength && !strncmp(name, alias, nameLength)) {
  73. *pEntry = &entry;
  74. return SPV_SUCCESS;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. return SPV_ERROR_INVALID_LOOKUP;
  81. }
  82. spv_result_t spvOperandTableValueLookup(spv_target_env,
  83. const spv_operand_table table,
  84. const spv_operand_type_t type,
  85. const uint32_t value,
  86. spv_operand_desc* pEntry) {
  87. if (!table) return SPV_ERROR_INVALID_TABLE;
  88. if (!pEntry) return SPV_ERROR_INVALID_POINTER;
  89. spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr,
  90. 0, nullptr, {}, ~0u, ~0u};
  91. auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
  92. return lhs.value < rhs.value;
  93. };
  94. for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
  95. const auto& group = table->types[typeIndex];
  96. if (type != group.type) continue;
  97. const auto beg = group.entries;
  98. const auto end = group.entries + group.count;
  99. // Assumes the underlying table is already sorted ascendingly according to
  100. // opcode value.
  101. auto it = std::lower_bound(beg, end, needle, comp);
  102. if (it != end && it->value == value) {
  103. // The current operand is considered available as long as
  104. // it is in the grammar. It might not be *valid* to use,
  105. // but that should be checked by the validator, not by parsing.
  106. *pEntry = it;
  107. return SPV_SUCCESS;
  108. }
  109. }
  110. return SPV_ERROR_INVALID_LOOKUP;
  111. }
  112. const char* spvOperandTypeStr(spv_operand_type_t type) {
  113. switch (type) {
  114. case SPV_OPERAND_TYPE_ID:
  115. case SPV_OPERAND_TYPE_OPTIONAL_ID:
  116. return "ID";
  117. case SPV_OPERAND_TYPE_TYPE_ID:
  118. return "type ID";
  119. case SPV_OPERAND_TYPE_RESULT_ID:
  120. return "result ID";
  121. case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  122. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  123. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
  124. case SPV_OPERAND_TYPE_LITERAL_FLOAT:
  125. return "literal number";
  126. case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  127. return "possibly multi-word literal integer";
  128. case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  129. return "possibly multi-word literal number";
  130. case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
  131. return "extension instruction number";
  132. case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
  133. return "OpSpecConstantOp opcode";
  134. case SPV_OPERAND_TYPE_LITERAL_STRING:
  135. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
  136. return "literal string";
  137. case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  138. return "source language";
  139. case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  140. return "execution model";
  141. case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  142. return "addressing model";
  143. case SPV_OPERAND_TYPE_MEMORY_MODEL:
  144. return "memory model";
  145. case SPV_OPERAND_TYPE_EXECUTION_MODE:
  146. return "execution mode";
  147. case SPV_OPERAND_TYPE_STORAGE_CLASS:
  148. return "storage class";
  149. case SPV_OPERAND_TYPE_DIMENSIONALITY:
  150. return "dimensionality";
  151. case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  152. return "sampler addressing mode";
  153. case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  154. return "sampler filter mode";
  155. case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  156. return "image format";
  157. case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  158. return "floating-point fast math mode";
  159. case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  160. return "floating-point rounding mode";
  161. case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  162. return "linkage type";
  163. case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  164. case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  165. return "access qualifier";
  166. case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  167. return "function parameter attribute";
  168. case SPV_OPERAND_TYPE_DECORATION:
  169. return "decoration";
  170. case SPV_OPERAND_TYPE_BUILT_IN:
  171. return "built-in";
  172. case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  173. return "selection control";
  174. case SPV_OPERAND_TYPE_LOOP_CONTROL:
  175. return "loop control";
  176. case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  177. return "function control";
  178. case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  179. return "memory semantics ID";
  180. case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  181. case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  182. return "memory access";
  183. case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
  184. return "shading rate";
  185. case SPV_OPERAND_TYPE_SCOPE_ID:
  186. return "scope ID";
  187. case SPV_OPERAND_TYPE_GROUP_OPERATION:
  188. return "group operation";
  189. case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  190. return "kernel enqeue flags";
  191. case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  192. return "kernel profiling info";
  193. case SPV_OPERAND_TYPE_CAPABILITY:
  194. return "capability";
  195. case SPV_OPERAND_TYPE_RAY_FLAGS:
  196. return "ray flags";
  197. case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  198. return "ray query intersection";
  199. case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  200. return "ray query committed intersection type";
  201. case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  202. return "ray query candidate intersection type";
  203. case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  204. case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
  205. return "packed vector format";
  206. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
  207. case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
  208. return "cooperative matrix operands";
  209. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
  210. return "cooperative matrix layout";
  211. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
  212. return "cooperative matrix use";
  213. case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE:
  214. return "tensor clamp mode";
  215. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
  216. return "cooperative matrix reduce";
  217. case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
  218. return "tensor addressing operands";
  219. case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
  220. case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
  221. return "matrix multiply accumulate operands";
  222. case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
  223. return "initialization mode qualifier";
  224. case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
  225. return "host access qualifier";
  226. case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
  227. return "load cache control";
  228. case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
  229. return "store cache control";
  230. case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
  231. return "named maximum number of registers";
  232. case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
  233. case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
  234. return "raw access chain operands";
  235. case SPV_OPERAND_TYPE_IMAGE:
  236. case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  237. return "image";
  238. case SPV_OPERAND_TYPE_OPTIONAL_CIV:
  239. return "context-insensitive value";
  240. 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";
  250. 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";
  262. case SPV_OPERAND_TYPE_FPENCODING:
  263. case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
  264. return "FP encoding";
  265. // The next values are for values returned from an instruction, not actually
  266. // an operand. So the specific strings don't matter. But let's add them
  267. // for completeness and ease of testing.
  268. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
  269. return "image channel order";
  270. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
  271. return "image channel data type";
  272. case SPV_OPERAND_TYPE_FPDENORM_MODE:
  273. return "FP denorm mode";
  274. case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  275. return "FP operation mode";
  276. case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  277. return "quantization mode";
  278. case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  279. return "overflow mode";
  280. case SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT:
  281. return "cooperative vector matrix layout";
  282. case SPV_OPERAND_TYPE_COMPONENT_TYPE:
  283. return "component type";
  284. case SPV_OPERAND_TYPE_NONE:
  285. return "NONE";
  286. default:
  287. break;
  288. }
  289. return "unknown";
  290. }
  291. void spvPushOperandTypes(const spv_operand_type_t* types,
  292. spv_operand_pattern_t* pattern) {
  293. const spv_operand_type_t* endTypes;
  294. for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
  295. }
  296. while (endTypes-- != types) {
  297. pattern->push_back(*endTypes);
  298. }
  299. }
  300. void spvPushOperandTypesForMask(spv_target_env env,
  301. const spv_operand_table operandTable,
  302. const spv_operand_type_t type,
  303. const uint32_t mask,
  304. spv_operand_pattern_t* pattern) {
  305. // Scan from highest bits to lowest bits because we will append in LIFO
  306. // fashion, and we need the operands for lower order bits to be consumed first
  307. for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
  308. candidate_bit >>= 1) {
  309. if (candidate_bit & mask) {
  310. spv_operand_desc entry = nullptr;
  311. if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
  312. candidate_bit, &entry)) {
  313. spvPushOperandTypes(entry->operandTypes, pattern);
  314. }
  315. }
  316. }
  317. }
  318. bool 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_LITERAL_FLOAT:
  325. case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
  326. case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
  327. case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  328. case SPV_OPERAND_TYPE_LITERAL_STRING:
  329. case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  330. case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  331. case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  332. case SPV_OPERAND_TYPE_MEMORY_MODEL:
  333. case SPV_OPERAND_TYPE_EXECUTION_MODE:
  334. case SPV_OPERAND_TYPE_STORAGE_CLASS:
  335. case SPV_OPERAND_TYPE_DIMENSIONALITY:
  336. case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  337. case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  338. case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  339. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
  340. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
  341. case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  342. case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  343. case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  344. case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  345. case SPV_OPERAND_TYPE_DECORATION:
  346. case SPV_OPERAND_TYPE_BUILT_IN:
  347. case SPV_OPERAND_TYPE_GROUP_OPERATION:
  348. case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  349. case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  350. case SPV_OPERAND_TYPE_CAPABILITY:
  351. case SPV_OPERAND_TYPE_RAY_FLAGS:
  352. case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  353. case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  354. case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  355. case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  356. case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
  357. case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
  358. case SPV_OPERAND_TYPE_DEBUG_OPERATION:
  359. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  360. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
  361. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
  362. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
  363. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
  364. case SPV_OPERAND_TYPE_FPDENORM_MODE:
  365. case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  366. case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  367. case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  368. case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  369. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
  370. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
  371. case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
  372. case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
  373. case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
  374. case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
  375. case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
  376. case SPV_OPERAND_TYPE_FPENCODING:
  377. case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE:
  378. case SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT:
  379. case SPV_OPERAND_TYPE_COMPONENT_TYPE:
  380. return true;
  381. default:
  382. break;
  383. }
  384. return false;
  385. }
  386. bool spvOperandIsConcreteMask(spv_operand_type_t type) {
  387. switch (type) {
  388. case SPV_OPERAND_TYPE_IMAGE:
  389. case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  390. case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  391. case SPV_OPERAND_TYPE_LOOP_CONTROL:
  392. case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  393. case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  394. case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
  395. case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
  396. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
  397. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
  398. case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
  399. case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
  400. case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
  401. case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
  402. return true;
  403. default:
  404. break;
  405. }
  406. return false;
  407. }
  408. bool spvOperandIsOptional(spv_operand_type_t type) {
  409. switch (type) {
  410. case SPV_OPERAND_TYPE_OPTIONAL_ID:
  411. case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  412. case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  413. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  414. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
  415. case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  416. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
  417. case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  418. case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
  419. case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
  420. case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
  421. case SPV_OPERAND_TYPE_OPTIONAL_CIV:
  422. case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
  423. case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
  424. return true;
  425. default:
  426. break;
  427. }
  428. // Any variable operand is also optional.
  429. return spvOperandIsVariable(type);
  430. }
  431. bool spvOperandIsVariable(spv_operand_type_t type) {
  432. switch (type) {
  433. case SPV_OPERAND_TYPE_VARIABLE_ID:
  434. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
  435. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
  436. case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
  437. return true;
  438. default:
  439. break;
  440. }
  441. return false;
  442. }
  443. bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
  444. spv_operand_pattern_t* pattern) {
  445. switch (type) {
  446. case SPV_OPERAND_TYPE_VARIABLE_ID:
  447. pattern->push_back(type);
  448. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
  449. return true;
  450. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
  451. pattern->push_back(type);
  452. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
  453. return true;
  454. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
  455. // Represents Zero or more (Literal number, Id) pairs,
  456. // where the literal number must be a scalar integer.
  457. pattern->push_back(type);
  458. pattern->push_back(SPV_OPERAND_TYPE_ID);
  459. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
  460. return true;
  461. case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
  462. // Represents Zero or more (Id, Literal number) pairs.
  463. pattern->push_back(type);
  464. pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
  465. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
  466. return true;
  467. default:
  468. break;
  469. }
  470. return false;
  471. }
  472. spv_operand_type_t spvTakeFirstMatchableOperand(
  473. spv_operand_pattern_t* pattern) {
  474. assert(!pattern->empty());
  475. spv_operand_type_t result;
  476. do {
  477. result = pattern->back();
  478. pattern->pop_back();
  479. } while (spvExpandOperandSequenceOnce(result, pattern));
  480. return result;
  481. }
  482. spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
  483. const spv_operand_pattern_t& pattern) {
  484. auto it =
  485. std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
  486. if (it != pattern.crend()) {
  487. spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
  488. SPV_OPERAND_TYPE_OPTIONAL_CIV);
  489. alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
  490. return alternatePattern;
  491. }
  492. // No result-id found, so just expect CIVs.
  493. return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
  494. }
  495. bool spvIsIdType(spv_operand_type_t type) {
  496. switch (type) {
  497. case SPV_OPERAND_TYPE_ID:
  498. case SPV_OPERAND_TYPE_TYPE_ID:
  499. case SPV_OPERAND_TYPE_RESULT_ID:
  500. case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  501. case SPV_OPERAND_TYPE_SCOPE_ID:
  502. return true;
  503. default:
  504. return false;
  505. }
  506. }
  507. bool spvIsInIdType(spv_operand_type_t type) {
  508. if (!spvIsIdType(type)) {
  509. // If it is not an ID it cannot be an input ID.
  510. return false;
  511. }
  512. switch (type) {
  513. // Deny non-input IDs.
  514. case SPV_OPERAND_TYPE_TYPE_ID:
  515. case SPV_OPERAND_TYPE_RESULT_ID:
  516. return false;
  517. default:
  518. return true;
  519. }
  520. }
  521. std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
  522. spv::Op opcode) {
  523. std::function<bool(unsigned index)> out;
  524. if (spvOpcodeGeneratesType(opcode)) {
  525. // All types can use forward pointers.
  526. out = [](unsigned) { return true; };
  527. return out;
  528. }
  529. switch (opcode) {
  530. case spv::Op::OpExecutionMode:
  531. case spv::Op::OpExecutionModeId:
  532. case spv::Op::OpEntryPoint:
  533. case spv::Op::OpName:
  534. case spv::Op::OpMemberName:
  535. case spv::Op::OpSelectionMerge:
  536. case spv::Op::OpDecorate:
  537. case spv::Op::OpMemberDecorate:
  538. case spv::Op::OpDecorateId:
  539. case spv::Op::OpDecorateStringGOOGLE:
  540. case spv::Op::OpMemberDecorateStringGOOGLE:
  541. case spv::Op::OpBranch:
  542. case spv::Op::OpLoopMerge:
  543. out = [](unsigned) { return true; };
  544. break;
  545. case spv::Op::OpGroupDecorate:
  546. case spv::Op::OpGroupMemberDecorate:
  547. case spv::Op::OpBranchConditional:
  548. case spv::Op::OpSwitch:
  549. out = [](unsigned index) { return index != 0; };
  550. break;
  551. case spv::Op::OpFunctionCall:
  552. // The Function parameter.
  553. out = [](unsigned index) { return index == 2; };
  554. break;
  555. case spv::Op::OpPhi:
  556. out = [](unsigned index) { return index > 1; };
  557. break;
  558. case spv::Op::OpEnqueueKernel:
  559. // The Invoke parameter.
  560. out = [](unsigned index) { return index == 8; };
  561. break;
  562. case spv::Op::OpGetKernelNDrangeSubGroupCount:
  563. case spv::Op::OpGetKernelNDrangeMaxSubGroupSize:
  564. // The Invoke parameter.
  565. out = [](unsigned index) { return index == 3; };
  566. break;
  567. case spv::Op::OpGetKernelWorkGroupSize:
  568. case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple:
  569. // The Invoke parameter.
  570. out = [](unsigned index) { return index == 2; };
  571. break;
  572. case spv::Op::OpTypeForwardPointer:
  573. out = [](unsigned index) { return index == 0; };
  574. break;
  575. case spv::Op::OpTypeArray:
  576. out = [](unsigned index) { return index == 1; };
  577. break;
  578. case spv::Op::OpCooperativeMatrixPerElementOpNV:
  579. out = [](unsigned index) { return index == 3; };
  580. break;
  581. case spv::Op::OpCooperativeMatrixReduceNV:
  582. out = [](unsigned index) { return index == 4; };
  583. break;
  584. case spv::Op::OpCooperativeMatrixLoadTensorNV:
  585. // approximate, due to variable operands
  586. out = [](unsigned index) { return index > 6; };
  587. break;
  588. default:
  589. out = [](unsigned) { return false; };
  590. break;
  591. }
  592. return out;
  593. }
  594. std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
  595. spv::Op opcode, spv_ext_inst_type_t ext_type, uint32_t key) {
  596. // The Vulkan debug info extended instruction set is non-semantic so allows no
  597. // forward references except if used through OpExtInstWithForwardRefsKHR.
  598. if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
  599. return [opcode](unsigned) {
  600. return opcode == spv::Op::OpExtInstWithForwardRefsKHR;
  601. };
  602. }
  603. // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
  604. // references for debug info instructions are still in discussion. We must
  605. // update the following lines of code when we conclude the spec.
  606. std::function<bool(unsigned index)> out;
  607. if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  608. switch (OpenCLDebugInfo100Instructions(key)) {
  609. case OpenCLDebugInfo100DebugFunction:
  610. out = [](unsigned index) { return index == 13; };
  611. break;
  612. case OpenCLDebugInfo100DebugTypeComposite:
  613. out = [](unsigned index) { return index >= 13; };
  614. break;
  615. default:
  616. out = [](unsigned) { return false; };
  617. break;
  618. }
  619. } else {
  620. switch (DebugInfoInstructions(key)) {
  621. case DebugInfoDebugFunction:
  622. out = [](unsigned index) { return index == 13; };
  623. break;
  624. case DebugInfoDebugTypeComposite:
  625. out = [](unsigned index) { return index >= 12; };
  626. break;
  627. default:
  628. out = [](unsigned) { return false; };
  629. break;
  630. }
  631. }
  632. return out;
  633. }