operand.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  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. #include "source/spirv_target_env.h"
  26. // For now, assume unified1 contains up to SPIR-V 1.3 and no later
  27. // SPIR-V version.
  28. // TODO(dneto): Make one set of tables, but with version tags on a
  29. // per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
  30. #include "operand.kinds-unified1.inc"
  31. #include "spirv-tools/libspirv.h"
  32. static const spv_operand_table_t kOperandTable = {
  33. ARRAY_SIZE(pygen_variable_OperandInfoTable),
  34. pygen_variable_OperandInfoTable};
  35. spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
  36. spv_target_env) {
  37. if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
  38. *pOperandTable = &kOperandTable;
  39. return SPV_SUCCESS;
  40. }
  41. spv_result_t spvOperandTableNameLookup(spv_target_env env,
  42. const spv_operand_table table,
  43. const spv_operand_type_t type,
  44. const char* name,
  45. const size_t nameLength,
  46. spv_operand_desc* pEntry) {
  47. if (!table) return SPV_ERROR_INVALID_TABLE;
  48. if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
  49. const auto version = spvVersionForTargetEnv(env);
  50. for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
  51. const auto& group = table->types[typeIndex];
  52. if (type != group.type) continue;
  53. for (uint64_t index = 0; index < group.count; ++index) {
  54. const auto& entry = group.entries[index];
  55. // We consider the current operand as available as long as
  56. // 1. The target environment satisfies the minimal requirement of the
  57. // operand; or
  58. // 2. There is at least one extension enabling this operand; or
  59. // 3. There is at least one capability enabling this operand.
  60. //
  61. // Note that the second rule assumes the extension enabling this operand
  62. // is indeed requested in the SPIR-V code; checking that should be
  63. // validator's work.
  64. if (nameLength == strlen(entry.name) &&
  65. !strncmp(entry.name, name, nameLength)) {
  66. if ((version >= entry.minVersion && version <= entry.lastVersion) ||
  67. entry.numExtensions > 0u || entry.numCapabilities > 0u) {
  68. *pEntry = &entry;
  69. return SPV_SUCCESS;
  70. } else {
  71. // if there is no extension/capability then the version is wrong
  72. return SPV_ERROR_WRONG_VERSION;
  73. }
  74. }
  75. }
  76. }
  77. return SPV_ERROR_INVALID_LOOKUP;
  78. }
  79. spv_result_t spvOperandTableValueLookup(spv_target_env env,
  80. const spv_operand_table table,
  81. const spv_operand_type_t type,
  82. const uint32_t value,
  83. spv_operand_desc* pEntry) {
  84. if (!table) return SPV_ERROR_INVALID_TABLE;
  85. if (!pEntry) return SPV_ERROR_INVALID_POINTER;
  86. spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u};
  87. auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
  88. return lhs.value < rhs.value;
  89. };
  90. for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
  91. const auto& group = table->types[typeIndex];
  92. if (type != group.type) continue;
  93. const auto beg = group.entries;
  94. const auto end = group.entries + group.count;
  95. // We need to loop here because there can exist multiple symbols for the
  96. // same operand value, and they can be introduced in different target
  97. // environments, which means they can have different minimal version
  98. // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
  99. // version as long as the SPV_KHR_shader_ballot extension is there; but
  100. // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
  101. // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
  102. // requirements.
  103. // Assumes the underlying table is already sorted ascendingly according to
  104. // opcode value.
  105. const auto version = spvVersionForTargetEnv(env);
  106. for (auto it = std::lower_bound(beg, end, needle, comp);
  107. it != end && it->value == value; ++it) {
  108. // We consider the current operand as available as long as
  109. // 1. The target environment satisfies the minimal requirement of the
  110. // operand; or
  111. // 2. There is at least one extension enabling this operand; or
  112. // 3. There is at least one capability enabling this operand.
  113. //
  114. // Note that the second rule assumes the extension enabling this operand
  115. // is indeed requested in the SPIR-V code; checking that should be
  116. // validator's work.
  117. if ((version >= it->minVersion && version <= it->lastVersion) ||
  118. it->numExtensions > 0u || it->numCapabilities > 0u) {
  119. *pEntry = it;
  120. return SPV_SUCCESS;
  121. }
  122. }
  123. }
  124. return SPV_ERROR_INVALID_LOOKUP;
  125. }
  126. const char* spvOperandTypeStr(spv_operand_type_t type) {
  127. switch (type) {
  128. case SPV_OPERAND_TYPE_ID:
  129. case SPV_OPERAND_TYPE_OPTIONAL_ID:
  130. return "ID";
  131. case SPV_OPERAND_TYPE_TYPE_ID:
  132. return "type ID";
  133. case SPV_OPERAND_TYPE_RESULT_ID:
  134. return "result ID";
  135. case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  136. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  137. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
  138. return "literal number";
  139. case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  140. return "possibly multi-word literal integer";
  141. case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  142. return "possibly multi-word literal number";
  143. case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
  144. return "extension instruction number";
  145. case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
  146. return "OpSpecConstantOp opcode";
  147. case SPV_OPERAND_TYPE_LITERAL_STRING:
  148. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
  149. return "literal string";
  150. case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  151. return "source language";
  152. case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  153. return "execution model";
  154. case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  155. return "addressing model";
  156. case SPV_OPERAND_TYPE_MEMORY_MODEL:
  157. return "memory model";
  158. case SPV_OPERAND_TYPE_EXECUTION_MODE:
  159. return "execution mode";
  160. case SPV_OPERAND_TYPE_STORAGE_CLASS:
  161. return "storage class";
  162. case SPV_OPERAND_TYPE_DIMENSIONALITY:
  163. return "dimensionality";
  164. case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  165. return "sampler addressing mode";
  166. case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  167. return "sampler filter mode";
  168. case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  169. return "image format";
  170. case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  171. return "floating-point fast math mode";
  172. case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  173. return "floating-point rounding mode";
  174. case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  175. return "linkage type";
  176. case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  177. case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  178. return "access qualifier";
  179. case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  180. return "function parameter attribute";
  181. case SPV_OPERAND_TYPE_DECORATION:
  182. return "decoration";
  183. case SPV_OPERAND_TYPE_BUILT_IN:
  184. return "built-in";
  185. case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  186. return "selection control";
  187. case SPV_OPERAND_TYPE_LOOP_CONTROL:
  188. return "loop control";
  189. case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  190. return "function control";
  191. case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  192. return "memory semantics ID";
  193. case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  194. case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  195. return "memory access";
  196. case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
  197. return "shading rate";
  198. case SPV_OPERAND_TYPE_SCOPE_ID:
  199. return "scope ID";
  200. case SPV_OPERAND_TYPE_GROUP_OPERATION:
  201. return "group operation";
  202. case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  203. return "kernel enqeue flags";
  204. case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  205. return "kernel profiling info";
  206. case SPV_OPERAND_TYPE_CAPABILITY:
  207. return "capability";
  208. case SPV_OPERAND_TYPE_RAY_FLAGS:
  209. return "ray flags";
  210. case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  211. return "ray query intersection";
  212. case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  213. return "ray query committed intersection type";
  214. case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  215. return "ray query candidate intersection type";
  216. case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  217. case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
  218. return "packed vector format";
  219. case SPV_OPERAND_TYPE_IMAGE:
  220. case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  221. return "image";
  222. case SPV_OPERAND_TYPE_OPTIONAL_CIV:
  223. return "context-insensitive value";
  224. 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";
  234. 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";
  246. // The next values are for values returned from an instruction, not actually
  247. // an operand. So the specific strings don't matter. But let's add them
  248. // for completeness and ease of testing.
  249. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
  250. return "image channel order";
  251. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
  252. return "image channel data type";
  253. case SPV_OPERAND_TYPE_FPDENORM_MODE:
  254. return "FP denorm mode";
  255. case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  256. return "FP operation mode";
  257. case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  258. return "quantization mode";
  259. case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  260. return "overflow mode";
  261. case SPV_OPERAND_TYPE_NONE:
  262. return "NONE";
  263. default:
  264. break;
  265. }
  266. return "unknown";
  267. }
  268. void spvPushOperandTypes(const spv_operand_type_t* types,
  269. spv_operand_pattern_t* pattern) {
  270. const spv_operand_type_t* endTypes;
  271. for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
  272. }
  273. while (endTypes-- != types) {
  274. pattern->push_back(*endTypes);
  275. }
  276. }
  277. void spvPushOperandTypesForMask(spv_target_env env,
  278. const spv_operand_table operandTable,
  279. const spv_operand_type_t type,
  280. const uint32_t mask,
  281. spv_operand_pattern_t* pattern) {
  282. // Scan from highest bits to lowest bits because we will append in LIFO
  283. // fashion, and we need the operands for lower order bits to be consumed first
  284. for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
  285. candidate_bit >>= 1) {
  286. if (candidate_bit & mask) {
  287. spv_operand_desc entry = nullptr;
  288. if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
  289. candidate_bit, &entry)) {
  290. spvPushOperandTypes(entry->operandTypes, pattern);
  291. }
  292. }
  293. }
  294. }
  295. bool spvOperandIsConcrete(spv_operand_type_t type) {
  296. if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
  297. return true;
  298. }
  299. switch (type) {
  300. case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  301. case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
  302. case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
  303. case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  304. case SPV_OPERAND_TYPE_LITERAL_STRING:
  305. case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  306. case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  307. case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  308. case SPV_OPERAND_TYPE_MEMORY_MODEL:
  309. case SPV_OPERAND_TYPE_EXECUTION_MODE:
  310. case SPV_OPERAND_TYPE_STORAGE_CLASS:
  311. case SPV_OPERAND_TYPE_DIMENSIONALITY:
  312. case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  313. case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  314. case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  315. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
  316. case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
  317. case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  318. case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  319. case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  320. case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  321. case SPV_OPERAND_TYPE_DECORATION:
  322. case SPV_OPERAND_TYPE_BUILT_IN:
  323. case SPV_OPERAND_TYPE_GROUP_OPERATION:
  324. case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  325. case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  326. case SPV_OPERAND_TYPE_CAPABILITY:
  327. case SPV_OPERAND_TYPE_RAY_FLAGS:
  328. case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  329. case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  330. case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  331. case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  332. case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
  333. case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
  334. case SPV_OPERAND_TYPE_DEBUG_OPERATION:
  335. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  336. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
  337. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
  338. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
  339. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
  340. case SPV_OPERAND_TYPE_FPDENORM_MODE:
  341. case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  342. case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  343. case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  344. case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  345. return true;
  346. default:
  347. break;
  348. }
  349. return false;
  350. }
  351. bool spvOperandIsConcreteMask(spv_operand_type_t type) {
  352. switch (type) {
  353. case SPV_OPERAND_TYPE_IMAGE:
  354. case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  355. case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  356. case SPV_OPERAND_TYPE_LOOP_CONTROL:
  357. case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  358. case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  359. case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
  360. case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
  361. case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
  362. return true;
  363. default:
  364. break;
  365. }
  366. return false;
  367. }
  368. bool spvOperandIsOptional(spv_operand_type_t type) {
  369. switch (type) {
  370. case SPV_OPERAND_TYPE_OPTIONAL_ID:
  371. case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  372. case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  373. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  374. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
  375. case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  376. case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
  377. case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  378. case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
  379. case SPV_OPERAND_TYPE_OPTIONAL_CIV:
  380. return true;
  381. default:
  382. break;
  383. }
  384. // Any variable operand is also optional.
  385. return spvOperandIsVariable(type);
  386. }
  387. bool spvOperandIsVariable(spv_operand_type_t type) {
  388. switch (type) {
  389. case SPV_OPERAND_TYPE_VARIABLE_ID:
  390. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
  391. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
  392. case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
  393. return true;
  394. default:
  395. break;
  396. }
  397. return false;
  398. }
  399. bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
  400. spv_operand_pattern_t* pattern) {
  401. switch (type) {
  402. case SPV_OPERAND_TYPE_VARIABLE_ID:
  403. pattern->push_back(type);
  404. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
  405. return true;
  406. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
  407. pattern->push_back(type);
  408. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
  409. return true;
  410. case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
  411. // Represents Zero or more (Literal number, Id) pairs,
  412. // where the literal number must be a scalar integer.
  413. pattern->push_back(type);
  414. pattern->push_back(SPV_OPERAND_TYPE_ID);
  415. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
  416. return true;
  417. case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
  418. // Represents Zero or more (Id, Literal number) pairs.
  419. pattern->push_back(type);
  420. pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
  421. pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
  422. return true;
  423. default:
  424. break;
  425. }
  426. return false;
  427. }
  428. spv_operand_type_t spvTakeFirstMatchableOperand(
  429. spv_operand_pattern_t* pattern) {
  430. assert(!pattern->empty());
  431. spv_operand_type_t result;
  432. do {
  433. result = pattern->back();
  434. pattern->pop_back();
  435. } while (spvExpandOperandSequenceOnce(result, pattern));
  436. return result;
  437. }
  438. spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
  439. const spv_operand_pattern_t& pattern) {
  440. auto it =
  441. std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
  442. if (it != pattern.crend()) {
  443. spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
  444. SPV_OPERAND_TYPE_OPTIONAL_CIV);
  445. alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
  446. return alternatePattern;
  447. }
  448. // No result-id found, so just expect CIVs.
  449. return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
  450. }
  451. bool spvIsIdType(spv_operand_type_t type) {
  452. switch (type) {
  453. case SPV_OPERAND_TYPE_ID:
  454. case SPV_OPERAND_TYPE_TYPE_ID:
  455. case SPV_OPERAND_TYPE_RESULT_ID:
  456. case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  457. case SPV_OPERAND_TYPE_SCOPE_ID:
  458. return true;
  459. default:
  460. return false;
  461. }
  462. }
  463. bool spvIsInIdType(spv_operand_type_t type) {
  464. if (!spvIsIdType(type)) {
  465. // If it is not an ID it cannot be an input ID.
  466. return false;
  467. }
  468. switch (type) {
  469. // Deny non-input IDs.
  470. case SPV_OPERAND_TYPE_TYPE_ID:
  471. case SPV_OPERAND_TYPE_RESULT_ID:
  472. return false;
  473. default:
  474. return true;
  475. }
  476. }
  477. std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
  478. spv::Op opcode) {
  479. std::function<bool(unsigned index)> out;
  480. if (spvOpcodeGeneratesType(opcode)) {
  481. // All types can use forward pointers.
  482. out = [](unsigned) { return true; };
  483. return out;
  484. }
  485. switch (opcode) {
  486. case spv::Op::OpExecutionMode:
  487. case spv::Op::OpExecutionModeId:
  488. case spv::Op::OpEntryPoint:
  489. case spv::Op::OpName:
  490. case spv::Op::OpMemberName:
  491. case spv::Op::OpSelectionMerge:
  492. case spv::Op::OpDecorate:
  493. case spv::Op::OpMemberDecorate:
  494. case spv::Op::OpDecorateId:
  495. case spv::Op::OpDecorateStringGOOGLE:
  496. case spv::Op::OpMemberDecorateStringGOOGLE:
  497. case spv::Op::OpBranch:
  498. case spv::Op::OpLoopMerge:
  499. out = [](unsigned) { return true; };
  500. break;
  501. case spv::Op::OpGroupDecorate:
  502. case spv::Op::OpGroupMemberDecorate:
  503. case spv::Op::OpBranchConditional:
  504. case spv::Op::OpSwitch:
  505. out = [](unsigned index) { return index != 0; };
  506. break;
  507. case spv::Op::OpFunctionCall:
  508. // The Function parameter.
  509. out = [](unsigned index) { return index == 2; };
  510. break;
  511. case spv::Op::OpPhi:
  512. out = [](unsigned index) { return index > 1; };
  513. break;
  514. case spv::Op::OpEnqueueKernel:
  515. // The Invoke parameter.
  516. out = [](unsigned index) { return index == 8; };
  517. break;
  518. case spv::Op::OpGetKernelNDrangeSubGroupCount:
  519. case spv::Op::OpGetKernelNDrangeMaxSubGroupSize:
  520. // The Invoke parameter.
  521. out = [](unsigned index) { return index == 3; };
  522. break;
  523. case spv::Op::OpGetKernelWorkGroupSize:
  524. case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple:
  525. // The Invoke parameter.
  526. out = [](unsigned index) { return index == 2; };
  527. break;
  528. case spv::Op::OpTypeForwardPointer:
  529. out = [](unsigned index) { return index == 0; };
  530. break;
  531. case spv::Op::OpTypeArray:
  532. out = [](unsigned index) { return index == 1; };
  533. break;
  534. default:
  535. out = [](unsigned) { return false; };
  536. break;
  537. }
  538. return out;
  539. }
  540. std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
  541. spv_ext_inst_type_t ext_type, uint32_t key) {
  542. // The Vulkan debug info extended instruction set is non-semantic so allows no
  543. // forward references ever
  544. if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
  545. return [](unsigned) { return false; };
  546. }
  547. // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
  548. // references for debug info instructions are still in discussion. We must
  549. // update the following lines of code when we conclude the spec.
  550. std::function<bool(unsigned index)> out;
  551. if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  552. switch (OpenCLDebugInfo100Instructions(key)) {
  553. case OpenCLDebugInfo100DebugFunction:
  554. out = [](unsigned index) { return index == 13; };
  555. break;
  556. case OpenCLDebugInfo100DebugTypeComposite:
  557. out = [](unsigned index) { return index >= 13; };
  558. break;
  559. default:
  560. out = [](unsigned) { return false; };
  561. break;
  562. }
  563. } else {
  564. switch (DebugInfoInstructions(key)) {
  565. case DebugInfoDebugFunction:
  566. out = [](unsigned index) { return index == 13; };
  567. break;
  568. case DebugInfoDebugTypeComposite:
  569. out = [](unsigned index) { return index >= 12; };
  570. break;
  571. default:
  572. out = [](unsigned) { return false; };
  573. break;
  574. }
  575. }
  576. return out;
  577. }