SpirvInstruction.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. //===- SpirvInstruction.cpp - SPIR-V Instruction Representation -*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the in-memory representation of SPIR-V instructions.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/SPIRV/SpirvInstruction.h"
  13. #include "clang/SPIRV/BitwiseCast.h"
  14. #include "clang/SPIRV/SpirvBasicBlock.h"
  15. #include "clang/SPIRV/SpirvFunction.h"
  16. #include "clang/SPIRV/SpirvType.h"
  17. #include "clang/SPIRV/SpirvVisitor.h"
  18. #include "clang/SPIRV/String.h"
  19. namespace clang {
  20. namespace spirv {
  21. #define DEFINE_INVOKE_VISITOR_FOR_CLASS(cls) \
  22. bool cls::invokeVisitor(Visitor *v) { return v->visit(this); }
  23. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvCapability)
  24. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvExtension)
  25. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvExtInstImport)
  26. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvMemoryModel)
  27. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvEntryPoint)
  28. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvExecutionMode)
  29. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvString)
  30. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSource)
  31. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvModuleProcessed)
  32. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvDecoration)
  33. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvVariable)
  34. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvFunctionParameter)
  35. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvLoopMerge)
  36. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSelectionMerge)
  37. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvBranch)
  38. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvBranchConditional)
  39. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvKill)
  40. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvReturn)
  41. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSwitch)
  42. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvUnreachable)
  43. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvAccessChain)
  44. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvAtomic)
  45. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvBarrier)
  46. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvBinaryOp)
  47. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvBitFieldExtract)
  48. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvBitFieldInsert)
  49. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvConstantBoolean)
  50. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvConstantInteger)
  51. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvConstantFloat)
  52. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvConstantComposite)
  53. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvConstantNull)
  54. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvCompositeConstruct)
  55. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvCompositeExtract)
  56. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvCompositeInsert)
  57. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvEmitVertex)
  58. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvEndPrimitive)
  59. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvExtInst)
  60. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvFunctionCall)
  61. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvNonUniformBinaryOp)
  62. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvNonUniformElect)
  63. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvNonUniformUnaryOp)
  64. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvImageOp)
  65. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvImageQuery)
  66. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvImageSparseTexelsResident)
  67. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvImageTexelPointer)
  68. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvLoad)
  69. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvCopyObject)
  70. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSampledImage)
  71. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSelect)
  72. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSpecConstantBinaryOp)
  73. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvSpecConstantUnaryOp)
  74. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvStore)
  75. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvUnaryOp)
  76. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvVectorShuffle)
  77. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvArrayLength)
  78. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvRayTracingOpNV)
  79. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvDemoteToHelperInvocationEXT)
  80. DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvRayQueryOpKHR)
  81. #undef DEFINE_INVOKE_VISITOR_FOR_CLASS
  82. SpirvInstruction::SpirvInstruction(Kind k, spv::Op op, QualType astType,
  83. SourceLocation loc)
  84. : kind(k), opcode(op), astResultType(astType), resultId(0), srcLoc(loc),
  85. debugName(), resultType(nullptr), resultTypeId(0),
  86. layoutRule(SpirvLayoutRule::Void), containsAlias(false),
  87. storageClass(spv::StorageClass::Function), isRValue_(false),
  88. isRelaxedPrecision_(false), isNonUniform_(false), isPrecise_(false) {}
  89. bool SpirvInstruction::isArithmeticInstruction() const {
  90. switch (opcode) {
  91. case spv::Op::OpSNegate:
  92. case spv::Op::OpFNegate:
  93. case spv::Op::OpIAdd:
  94. case spv::Op::OpFAdd:
  95. case spv::Op::OpISub:
  96. case spv::Op::OpFSub:
  97. case spv::Op::OpIMul:
  98. case spv::Op::OpFMul:
  99. case spv::Op::OpUDiv:
  100. case spv::Op::OpSDiv:
  101. case spv::Op::OpFDiv:
  102. case spv::Op::OpUMod:
  103. case spv::Op::OpSRem:
  104. case spv::Op::OpSMod:
  105. case spv::Op::OpFRem:
  106. case spv::Op::OpFMod:
  107. case spv::Op::OpVectorTimesScalar:
  108. case spv::Op::OpMatrixTimesScalar:
  109. case spv::Op::OpVectorTimesMatrix:
  110. case spv::Op::OpMatrixTimesVector:
  111. case spv::Op::OpMatrixTimesMatrix:
  112. case spv::Op::OpOuterProduct:
  113. case spv::Op::OpDot:
  114. case spv::Op::OpIAddCarry:
  115. case spv::Op::OpISubBorrow:
  116. case spv::Op::OpUMulExtended:
  117. case spv::Op::OpSMulExtended:
  118. return true;
  119. default:
  120. return false;
  121. }
  122. }
  123. SpirvCapability::SpirvCapability(SourceLocation loc, spv::Capability cap)
  124. : SpirvInstruction(IK_Capability, spv::Op::OpCapability, QualType(), loc),
  125. capability(cap) {}
  126. bool SpirvCapability::operator==(const SpirvCapability &that) const {
  127. return capability == that.capability;
  128. }
  129. SpirvExtension::SpirvExtension(SourceLocation loc,
  130. llvm::StringRef extensionName)
  131. : SpirvInstruction(IK_Extension, spv::Op::OpExtension, QualType(), loc),
  132. extName(extensionName) {}
  133. bool SpirvExtension::operator==(const SpirvExtension &that) const {
  134. return extName == that.extName;
  135. }
  136. SpirvExtInstImport::SpirvExtInstImport(SourceLocation loc,
  137. llvm::StringRef extensionName)
  138. : SpirvInstruction(IK_ExtInstImport, spv::Op::OpExtInstImport, QualType(),
  139. loc),
  140. extName(extensionName) {}
  141. SpirvMemoryModel::SpirvMemoryModel(spv::AddressingModel addrModel,
  142. spv::MemoryModel memModel)
  143. : SpirvInstruction(IK_MemoryModel, spv::Op::OpMemoryModel, QualType(),
  144. /*SrcLoc*/ {}),
  145. addressModel(addrModel), memoryModel(memModel) {}
  146. SpirvEntryPoint::SpirvEntryPoint(SourceLocation loc,
  147. spv::ExecutionModel executionModel,
  148. SpirvFunction *entryPointFn,
  149. llvm::StringRef nameStr,
  150. llvm::ArrayRef<SpirvVariable *> iface)
  151. : SpirvInstruction(IK_EntryPoint, spv::Op::OpEntryPoint, QualType(), loc),
  152. execModel(executionModel), entryPoint(entryPointFn), name(nameStr),
  153. interfaceVec(iface.begin(), iface.end()) {}
  154. // OpExecutionMode and OpExecutionModeId instructions
  155. SpirvExecutionMode::SpirvExecutionMode(SourceLocation loc, SpirvFunction *entry,
  156. spv::ExecutionMode em,
  157. llvm::ArrayRef<uint32_t> paramsVec,
  158. bool usesIdParams)
  159. : SpirvInstruction(IK_ExecutionMode,
  160. usesIdParams ? spv::Op::OpExecutionModeId
  161. : spv::Op::OpExecutionMode,
  162. QualType(), loc),
  163. entryPoint(entry), execMode(em),
  164. params(paramsVec.begin(), paramsVec.end()) {}
  165. SpirvString::SpirvString(SourceLocation loc, llvm::StringRef stringLiteral)
  166. : SpirvInstruction(IK_String, spv::Op::OpString, QualType(), loc),
  167. str(stringLiteral) {}
  168. SpirvSource::SpirvSource(SourceLocation loc, spv::SourceLanguage language,
  169. uint32_t ver, SpirvString *fileString,
  170. llvm::StringRef src)
  171. : SpirvInstruction(IK_Source, spv::Op::OpSource, QualType(), loc),
  172. lang(language), version(ver), file(fileString), source(src) {}
  173. SpirvModuleProcessed::SpirvModuleProcessed(SourceLocation loc,
  174. llvm::StringRef processStr)
  175. : SpirvInstruction(IK_ModuleProcessed, spv::Op::OpModuleProcessed,
  176. QualType(), loc),
  177. process(processStr) {}
  178. SpirvDecoration::SpirvDecoration(SourceLocation loc,
  179. SpirvInstruction *targetInst,
  180. spv::Decoration decor,
  181. llvm::ArrayRef<uint32_t> p,
  182. llvm::Optional<uint32_t> idx)
  183. : SpirvInstruction(IK_Decoration, getDecorateOpcode(decor, idx),
  184. /*type*/ {}, loc),
  185. target(targetInst), decoration(decor), index(idx),
  186. params(p.begin(), p.end()), idParams() {}
  187. SpirvDecoration::SpirvDecoration(SourceLocation loc,
  188. SpirvInstruction *targetInst,
  189. spv::Decoration decor,
  190. llvm::StringRef strParam,
  191. llvm::Optional<uint32_t> idx)
  192. : SpirvInstruction(IK_Decoration, getDecorateOpcode(decor, idx),
  193. /*type*/ {}, loc),
  194. target(targetInst), decoration(decor), index(idx), params(), idParams() {
  195. const auto &stringWords = string::encodeSPIRVString(strParam);
  196. params.insert(params.end(), stringWords.begin(), stringWords.end());
  197. }
  198. SpirvDecoration::SpirvDecoration(SourceLocation loc,
  199. SpirvInstruction *targetInst,
  200. spv::Decoration decor,
  201. llvm::ArrayRef<SpirvInstruction *> ids)
  202. : SpirvInstruction(IK_Decoration, spv::Op::OpDecorateId,
  203. /*type*/ {}, loc),
  204. target(targetInst), decoration(decor), index(llvm::None), params(),
  205. idParams(ids.begin(), ids.end()) {}
  206. spv::Op SpirvDecoration::getDecorateOpcode(
  207. spv::Decoration decoration, const llvm::Optional<uint32_t> &memberIndex) {
  208. if (decoration == spv::Decoration::HlslSemanticGOOGLE ||
  209. decoration == spv::Decoration::UserTypeGOOGLE)
  210. return memberIndex.hasValue() ? spv::Op::OpMemberDecorateStringGOOGLE
  211. : spv::Op::OpDecorateStringGOOGLE;
  212. return memberIndex.hasValue() ? spv::Op::OpMemberDecorate
  213. : spv::Op::OpDecorate;
  214. }
  215. bool SpirvDecoration::operator==(const SpirvDecoration &that) const {
  216. return target == that.target && decoration == that.decoration &&
  217. params == that.params && idParams == that.idParams &&
  218. index.hasValue() == that.index.hasValue() &&
  219. (!index.hasValue() || index.getValue() == that.index.getValue());
  220. }
  221. SpirvVariable::SpirvVariable(QualType resultType, SourceLocation loc,
  222. spv::StorageClass sc, bool precise,
  223. SpirvInstruction *initializerInst)
  224. : SpirvInstruction(IK_Variable, spv::Op::OpVariable, resultType, loc),
  225. initializer(initializerInst), descriptorSet(-1), binding(-1),
  226. hlslUserType("") {
  227. setStorageClass(sc);
  228. setPrecise(precise);
  229. }
  230. SpirvFunctionParameter::SpirvFunctionParameter(QualType resultType,
  231. bool isPrecise,
  232. SourceLocation loc)
  233. : SpirvInstruction(IK_FunctionParameter, spv::Op::OpFunctionParameter,
  234. resultType, loc) {
  235. setPrecise(isPrecise);
  236. }
  237. SpirvMerge::SpirvMerge(Kind kind, spv::Op op, SourceLocation loc,
  238. SpirvBasicBlock *mergeLabel)
  239. : SpirvInstruction(kind, op, QualType(), loc), mergeBlock(mergeLabel) {}
  240. SpirvLoopMerge::SpirvLoopMerge(SourceLocation loc, SpirvBasicBlock *mergeBlock,
  241. SpirvBasicBlock *contTarget,
  242. spv::LoopControlMask mask)
  243. : SpirvMerge(IK_LoopMerge, spv::Op::OpLoopMerge, loc, mergeBlock),
  244. continueTarget(contTarget), loopControlMask(mask) {}
  245. SpirvSelectionMerge::SpirvSelectionMerge(SourceLocation loc,
  246. SpirvBasicBlock *mergeBlock,
  247. spv::SelectionControlMask mask)
  248. : SpirvMerge(IK_SelectionMerge, spv::Op::OpSelectionMerge, loc, mergeBlock),
  249. selControlMask(mask) {}
  250. SpirvTerminator::SpirvTerminator(Kind kind, spv::Op op, SourceLocation loc)
  251. : SpirvInstruction(kind, op, QualType(), loc) {}
  252. SpirvBranching::SpirvBranching(Kind kind, spv::Op op, SourceLocation loc)
  253. : SpirvTerminator(kind, op, loc) {}
  254. SpirvBranch::SpirvBranch(SourceLocation loc, SpirvBasicBlock *target)
  255. : SpirvBranching(IK_Branch, spv::Op::OpBranch, loc), targetLabel(target) {}
  256. SpirvBranchConditional::SpirvBranchConditional(SourceLocation loc,
  257. SpirvInstruction *cond,
  258. SpirvBasicBlock *trueInst,
  259. SpirvBasicBlock *falseInst)
  260. : SpirvBranching(IK_BranchConditional, spv::Op::OpBranchConditional, loc),
  261. condition(cond), trueLabel(trueInst), falseLabel(falseInst) {}
  262. SpirvKill::SpirvKill(SourceLocation loc)
  263. : SpirvTerminator(IK_Kill, spv::Op::OpKill, loc) {}
  264. SpirvReturn::SpirvReturn(SourceLocation loc, SpirvInstruction *retVal)
  265. : SpirvTerminator(IK_Return,
  266. retVal ? spv::Op::OpReturnValue : spv::Op::OpReturn, loc),
  267. returnValue(retVal) {}
  268. SpirvSwitch::SpirvSwitch(
  269. SourceLocation loc, SpirvInstruction *selectorInst,
  270. SpirvBasicBlock *defaultLbl,
  271. llvm::ArrayRef<std::pair<uint32_t, SpirvBasicBlock *>> &targetsVec)
  272. : SpirvBranching(IK_Switch, spv::Op::OpSwitch, loc), selector(selectorInst),
  273. defaultLabel(defaultLbl), targets(targetsVec.begin(), targetsVec.end()) {}
  274. // Switch instruction methods.
  275. SpirvBasicBlock *SpirvSwitch::getTargetLabelForLiteral(uint32_t lit) const {
  276. for (auto pair : targets)
  277. if (pair.first == lit)
  278. return pair.second;
  279. return defaultLabel;
  280. }
  281. llvm::ArrayRef<SpirvBasicBlock *> SpirvSwitch::getTargetBranches() const {
  282. llvm::SmallVector<SpirvBasicBlock *, 4> branches;
  283. for (auto pair : targets)
  284. branches.push_back(pair.second);
  285. branches.push_back(defaultLabel);
  286. return branches;
  287. }
  288. SpirvUnreachable::SpirvUnreachable(SourceLocation loc)
  289. : SpirvTerminator(IK_Unreachable, spv::Op::OpUnreachable, loc) {}
  290. SpirvAccessChain::SpirvAccessChain(QualType resultType, SourceLocation loc,
  291. SpirvInstruction *baseInst,
  292. llvm::ArrayRef<SpirvInstruction *> indexVec)
  293. : SpirvInstruction(IK_AccessChain, spv::Op::OpAccessChain, resultType, loc),
  294. base(baseInst), indices(indexVec.begin(), indexVec.end()) {}
  295. SpirvAtomic::SpirvAtomic(spv::Op op, QualType resultType, SourceLocation loc,
  296. SpirvInstruction *pointerInst, spv::Scope s,
  297. spv::MemorySemanticsMask mask,
  298. SpirvInstruction *valueInst)
  299. : SpirvInstruction(IK_Atomic, op, resultType, loc), pointer(pointerInst),
  300. scope(s), memorySemantic(mask),
  301. memorySemanticUnequal(spv::MemorySemanticsMask::MaskNone),
  302. value(valueInst), comparator(nullptr) {
  303. assert(
  304. op == spv::Op::OpAtomicLoad || op == spv::Op::OpAtomicIIncrement ||
  305. op == spv::Op::OpAtomicIDecrement || op == spv::Op::OpAtomicFlagClear ||
  306. op == spv::Op::OpAtomicFlagTestAndSet || op == spv::Op::OpAtomicStore ||
  307. op == spv::Op::OpAtomicAnd || op == spv::Op::OpAtomicOr ||
  308. op == spv::Op::OpAtomicXor || op == spv::Op::OpAtomicIAdd ||
  309. op == spv::Op::OpAtomicISub || op == spv::Op::OpAtomicSMin ||
  310. op == spv::Op::OpAtomicUMin || op == spv::Op::OpAtomicSMax ||
  311. op == spv::Op::OpAtomicUMax || op == spv::Op::OpAtomicExchange);
  312. }
  313. SpirvAtomic::SpirvAtomic(spv::Op op, QualType resultType, SourceLocation loc,
  314. SpirvInstruction *pointerInst, spv::Scope s,
  315. spv::MemorySemanticsMask semanticsEqual,
  316. spv::MemorySemanticsMask semanticsUnequal,
  317. SpirvInstruction *valueInst,
  318. SpirvInstruction *comparatorInst)
  319. : SpirvInstruction(IK_Atomic, op, resultType, loc), pointer(pointerInst),
  320. scope(s), memorySemantic(semanticsEqual),
  321. memorySemanticUnequal(semanticsUnequal), value(valueInst),
  322. comparator(comparatorInst) {
  323. assert(op == spv::Op::OpAtomicCompareExchange);
  324. }
  325. SpirvBarrier::SpirvBarrier(SourceLocation loc, spv::Scope memScope,
  326. spv::MemorySemanticsMask memSemantics,
  327. llvm::Optional<spv::Scope> execScope)
  328. : SpirvInstruction(IK_Barrier,
  329. execScope.hasValue() ? spv::Op::OpControlBarrier
  330. : spv::Op::OpMemoryBarrier,
  331. QualType(), loc),
  332. memoryScope(memScope), memorySemantics(memSemantics),
  333. executionScope(execScope) {}
  334. SpirvBinaryOp::SpirvBinaryOp(spv::Op opcode, QualType resultType,
  335. SourceLocation loc, SpirvInstruction *op1,
  336. SpirvInstruction *op2)
  337. : SpirvInstruction(IK_BinaryOp, opcode, resultType, loc), operand1(op1),
  338. operand2(op2) {}
  339. SpirvBitField::SpirvBitField(Kind kind, spv::Op op, QualType resultType,
  340. SourceLocation loc, SpirvInstruction *baseInst,
  341. SpirvInstruction *offsetInst,
  342. SpirvInstruction *countInst)
  343. : SpirvInstruction(kind, op, resultType, loc), base(baseInst),
  344. offset(offsetInst), count(countInst) {}
  345. SpirvBitFieldExtract::SpirvBitFieldExtract(
  346. QualType resultType, SourceLocation loc, SpirvInstruction *baseInst,
  347. SpirvInstruction *offsetInst, SpirvInstruction *countInst, bool isSigned)
  348. : SpirvBitField(IK_BitFieldExtract,
  349. isSigned ? spv::Op::OpBitFieldSExtract
  350. : spv::Op::OpBitFieldUExtract,
  351. resultType, loc, baseInst, offsetInst, countInst) {}
  352. SpirvBitFieldInsert::SpirvBitFieldInsert(QualType resultType,
  353. SourceLocation loc,
  354. SpirvInstruction *baseInst,
  355. SpirvInstruction *insertInst,
  356. SpirvInstruction *offsetInst,
  357. SpirvInstruction *countInst)
  358. : SpirvBitField(IK_BitFieldInsert, spv::Op::OpBitFieldInsert, resultType,
  359. loc, baseInst, offsetInst, countInst),
  360. insert(insertInst) {}
  361. SpirvCompositeConstruct::SpirvCompositeConstruct(
  362. QualType resultType, SourceLocation loc,
  363. llvm::ArrayRef<SpirvInstruction *> constituentsVec)
  364. : SpirvInstruction(IK_CompositeConstruct, spv::Op::OpCompositeConstruct,
  365. resultType, loc),
  366. consituents(constituentsVec.begin(), constituentsVec.end()) {}
  367. SpirvConstant::SpirvConstant(Kind kind, spv::Op op, const SpirvType *spvType)
  368. : SpirvInstruction(kind, op, QualType(),
  369. /*SourceLocation*/ {}) {
  370. setResultType(spvType);
  371. }
  372. SpirvConstant::SpirvConstant(Kind kind, spv::Op op, QualType resultType)
  373. : SpirvInstruction(kind, op, resultType,
  374. /*SourceLocation*/ {}) {}
  375. bool SpirvConstant::isSpecConstant() const {
  376. return opcode == spv::Op::OpSpecConstant ||
  377. opcode == spv::Op::OpSpecConstantTrue ||
  378. opcode == spv::Op::OpSpecConstantFalse ||
  379. opcode == spv::Op::OpSpecConstantComposite;
  380. }
  381. SpirvConstantBoolean::SpirvConstantBoolean(QualType type, bool val,
  382. bool isSpecConst)
  383. : SpirvConstant(IK_ConstantBoolean,
  384. val ? (isSpecConst ? spv::Op::OpSpecConstantTrue
  385. : spv::Op::OpConstantTrue)
  386. : (isSpecConst ? spv::Op::OpSpecConstantFalse
  387. : spv::Op::OpConstantFalse),
  388. type),
  389. value(val) {}
  390. bool SpirvConstantBoolean::operator==(const SpirvConstantBoolean &that) const {
  391. return resultType == that.resultType && astResultType == that.astResultType &&
  392. value == that.value && opcode == that.opcode;
  393. }
  394. SpirvConstantInteger::SpirvConstantInteger(QualType type, llvm::APInt val,
  395. bool isSpecConst)
  396. : SpirvConstant(IK_ConstantInteger,
  397. isSpecConst ? spv::Op::OpSpecConstant : spv::Op::OpConstant,
  398. type),
  399. value(val) {
  400. assert(type->isIntegerType());
  401. }
  402. bool SpirvConstantInteger::operator==(const SpirvConstantInteger &that) const {
  403. return resultType == that.resultType && astResultType == that.astResultType &&
  404. value == that.value && opcode == that.opcode;
  405. }
  406. SpirvConstantFloat::SpirvConstantFloat(QualType type, llvm::APFloat val,
  407. bool isSpecConst)
  408. : SpirvConstant(IK_ConstantFloat,
  409. isSpecConst ? spv::Op::OpSpecConstant : spv::Op::OpConstant,
  410. type),
  411. value(val) {
  412. assert(type->isFloatingType());
  413. }
  414. bool SpirvConstantFloat::operator==(const SpirvConstantFloat &that) const {
  415. return resultType == that.resultType && astResultType == that.astResultType &&
  416. value.bitwiseIsEqual(that.value) && opcode == that.opcode;
  417. }
  418. SpirvConstantComposite::SpirvConstantComposite(
  419. QualType type, llvm::ArrayRef<SpirvConstant *> constituentsVec,
  420. bool isSpecConst)
  421. : SpirvConstant(IK_ConstantComposite,
  422. isSpecConst ? spv::Op::OpSpecConstantComposite
  423. : spv::Op::OpConstantComposite,
  424. type),
  425. constituents(constituentsVec.begin(), constituentsVec.end()) {}
  426. SpirvConstantNull::SpirvConstantNull(QualType type)
  427. : SpirvConstant(IK_ConstantNull, spv::Op::OpConstantNull, type) {}
  428. bool SpirvConstantNull::operator==(const SpirvConstantNull &that) const {
  429. return opcode == that.opcode && resultType == that.resultType &&
  430. astResultType == that.astResultType;
  431. }
  432. SpirvCompositeExtract::SpirvCompositeExtract(QualType resultType,
  433. SourceLocation loc,
  434. SpirvInstruction *compositeInst,
  435. llvm::ArrayRef<uint32_t> indexVec)
  436. : SpirvInstruction(IK_CompositeExtract, spv::Op::OpCompositeExtract,
  437. resultType, loc),
  438. composite(compositeInst), indices(indexVec.begin(), indexVec.end()) {}
  439. SpirvCompositeInsert::SpirvCompositeInsert(QualType resultType,
  440. SourceLocation loc,
  441. SpirvInstruction *compositeInst,
  442. SpirvInstruction *objectInst,
  443. llvm::ArrayRef<uint32_t> indexVec)
  444. : SpirvInstruction(IK_CompositeInsert, spv::Op::OpCompositeInsert,
  445. resultType, loc),
  446. composite(compositeInst), object(objectInst),
  447. indices(indexVec.begin(), indexVec.end()) {}
  448. SpirvEmitVertex::SpirvEmitVertex(SourceLocation loc)
  449. : SpirvInstruction(IK_EmitVertex, spv::Op::OpEmitVertex, QualType(), loc) {}
  450. SpirvEndPrimitive::SpirvEndPrimitive(SourceLocation loc)
  451. : SpirvInstruction(IK_EndPrimitive, spv::Op::OpEndPrimitive, QualType(),
  452. loc) {}
  453. SpirvExtInst::SpirvExtInst(QualType resultType, SourceLocation loc,
  454. SpirvExtInstImport *set, uint32_t inst,
  455. llvm::ArrayRef<SpirvInstruction *> operandsVec)
  456. : SpirvInstruction(IK_ExtInst, spv::Op::OpExtInst, resultType, loc),
  457. instructionSet(set), instruction(inst),
  458. operands(operandsVec.begin(), operandsVec.end()) {}
  459. SpirvFunctionCall::SpirvFunctionCall(QualType resultType, SourceLocation loc,
  460. SpirvFunction *fn,
  461. llvm::ArrayRef<SpirvInstruction *> argsVec)
  462. : SpirvInstruction(IK_FunctionCall, spv::Op::OpFunctionCall, resultType,
  463. loc),
  464. function(fn), args(argsVec.begin(), argsVec.end()) {}
  465. SpirvGroupNonUniformOp::SpirvGroupNonUniformOp(Kind kind, spv::Op op,
  466. QualType resultType,
  467. SourceLocation loc,
  468. spv::Scope scope)
  469. : SpirvInstruction(kind, op, resultType, loc), execScope(scope) {}
  470. SpirvNonUniformBinaryOp::SpirvNonUniformBinaryOp(
  471. spv::Op op, QualType resultType, SourceLocation loc, spv::Scope scope,
  472. SpirvInstruction *arg1Inst, SpirvInstruction *arg2Inst)
  473. : SpirvGroupNonUniformOp(IK_GroupNonUniformBinaryOp, op, resultType, loc,
  474. scope),
  475. arg1(arg1Inst), arg2(arg2Inst) {
  476. assert(op == spv::Op::OpGroupNonUniformBroadcast ||
  477. op == spv::Op::OpGroupNonUniformBallotBitExtract ||
  478. op == spv::Op::OpGroupNonUniformShuffle ||
  479. op == spv::Op::OpGroupNonUniformShuffleXor ||
  480. op == spv::Op::OpGroupNonUniformShuffleUp ||
  481. op == spv::Op::OpGroupNonUniformShuffleDown ||
  482. op == spv::Op::OpGroupNonUniformQuadBroadcast ||
  483. op == spv::Op::OpGroupNonUniformQuadSwap);
  484. }
  485. SpirvNonUniformElect::SpirvNonUniformElect(QualType resultType,
  486. SourceLocation loc, spv::Scope scope)
  487. : SpirvGroupNonUniformOp(IK_GroupNonUniformElect,
  488. spv::Op::OpGroupNonUniformElect, resultType, loc,
  489. scope) {}
  490. SpirvNonUniformUnaryOp::SpirvNonUniformUnaryOp(
  491. spv::Op op, QualType resultType, SourceLocation loc, spv::Scope scope,
  492. llvm::Optional<spv::GroupOperation> group, SpirvInstruction *argInst)
  493. : SpirvGroupNonUniformOp(IK_GroupNonUniformUnaryOp, op, resultType, loc,
  494. scope),
  495. arg(argInst), groupOp(group) {
  496. assert(op == spv::Op::OpGroupNonUniformAll ||
  497. op == spv::Op::OpGroupNonUniformAny ||
  498. op == spv::Op::OpGroupNonUniformAllEqual ||
  499. op == spv::Op::OpGroupNonUniformBroadcastFirst ||
  500. op == spv::Op::OpGroupNonUniformBallot ||
  501. op == spv::Op::OpGroupNonUniformInverseBallot ||
  502. op == spv::Op::OpGroupNonUniformBallotBitCount ||
  503. op == spv::Op::OpGroupNonUniformBallotFindLSB ||
  504. op == spv::Op::OpGroupNonUniformBallotFindMSB ||
  505. op == spv::Op::OpGroupNonUniformIAdd ||
  506. op == spv::Op::OpGroupNonUniformFAdd ||
  507. op == spv::Op::OpGroupNonUniformIMul ||
  508. op == spv::Op::OpGroupNonUniformFMul ||
  509. op == spv::Op::OpGroupNonUniformSMin ||
  510. op == spv::Op::OpGroupNonUniformUMin ||
  511. op == spv::Op::OpGroupNonUniformFMin ||
  512. op == spv::Op::OpGroupNonUniformSMax ||
  513. op == spv::Op::OpGroupNonUniformUMax ||
  514. op == spv::Op::OpGroupNonUniformFMax ||
  515. op == spv::Op::OpGroupNonUniformBitwiseAnd ||
  516. op == spv::Op::OpGroupNonUniformBitwiseOr ||
  517. op == spv::Op::OpGroupNonUniformBitwiseXor ||
  518. op == spv::Op::OpGroupNonUniformLogicalAnd ||
  519. op == spv::Op::OpGroupNonUniformLogicalOr ||
  520. op == spv::Op::OpGroupNonUniformLogicalXor);
  521. }
  522. SpirvImageOp::SpirvImageOp(
  523. spv::Op op, QualType resultType, SourceLocation loc,
  524. SpirvInstruction *imageInst, SpirvInstruction *coordinateInst,
  525. spv::ImageOperandsMask mask, SpirvInstruction *drefInst,
  526. SpirvInstruction *biasInst, SpirvInstruction *lodInst,
  527. SpirvInstruction *gradDxInst, SpirvInstruction *gradDyInst,
  528. SpirvInstruction *constOffsetInst, SpirvInstruction *offsetInst,
  529. SpirvInstruction *constOffsetsInst, SpirvInstruction *sampleInst,
  530. SpirvInstruction *minLodInst, SpirvInstruction *componentInst,
  531. SpirvInstruction *texelToWriteInst)
  532. : SpirvInstruction(IK_ImageOp, op, resultType, loc), image(imageInst),
  533. coordinate(coordinateInst), dref(drefInst), bias(biasInst), lod(lodInst),
  534. gradDx(gradDxInst), gradDy(gradDyInst), constOffset(constOffsetInst),
  535. offset(offsetInst), constOffsets(constOffsetsInst), sample(sampleInst),
  536. minLod(minLodInst), component(componentInst),
  537. texelToWrite(texelToWriteInst), operandsMask(mask) {
  538. assert(op == spv::Op::OpImageSampleImplicitLod ||
  539. op == spv::Op::OpImageSampleExplicitLod ||
  540. op == spv::Op::OpImageSampleDrefImplicitLod ||
  541. op == spv::Op::OpImageSampleDrefExplicitLod ||
  542. op == spv::Op::OpImageSparseSampleImplicitLod ||
  543. op == spv::Op::OpImageSparseSampleExplicitLod ||
  544. op == spv::Op::OpImageSparseSampleDrefImplicitLod ||
  545. op == spv::Op::OpImageSparseSampleDrefExplicitLod ||
  546. op == spv::Op::OpImageFetch || op == spv::Op::OpImageSparseFetch ||
  547. op == spv::Op::OpImageGather || op == spv::Op::OpImageSparseGather ||
  548. op == spv::Op::OpImageDrefGather ||
  549. op == spv::Op::OpImageSparseDrefGather || op == spv::Op::OpImageRead ||
  550. op == spv::Op::OpImageSparseRead || op == spv::Op::OpImageWrite);
  551. if (op == spv::Op::OpImageSampleExplicitLod ||
  552. op == spv::Op::OpImageSampleDrefExplicitLod ||
  553. op == spv::Op::OpImageSparseSampleExplicitLod ||
  554. op == spv::Op::OpImageSparseSampleDrefExplicitLod) {
  555. assert(lod || (gradDx && gradDy));
  556. }
  557. if (op == spv::Op::OpImageSampleDrefImplicitLod ||
  558. op == spv::Op::OpImageSampleDrefExplicitLod ||
  559. op == spv::Op::OpImageSparseSampleDrefImplicitLod ||
  560. op == spv::Op::OpImageSparseSampleDrefExplicitLod ||
  561. op == spv::Op::OpImageDrefGather ||
  562. op == spv::Op::OpImageSparseDrefGather) {
  563. assert(dref);
  564. }
  565. if (op == spv::Op::OpImageWrite) {
  566. assert(texelToWrite);
  567. }
  568. if (op == spv::Op::OpImageGather || op == spv::Op::OpImageSparseGather) {
  569. assert(component);
  570. }
  571. }
  572. bool SpirvImageOp::isSparse() const {
  573. return opcode == spv::Op::OpImageSparseSampleImplicitLod ||
  574. opcode == spv::Op::OpImageSparseSampleExplicitLod ||
  575. opcode == spv::Op::OpImageSparseSampleDrefImplicitLod ||
  576. opcode == spv::Op::OpImageSparseSampleDrefExplicitLod ||
  577. opcode == spv::Op::OpImageSparseFetch ||
  578. opcode == spv::Op::OpImageSparseGather ||
  579. opcode == spv::Op::OpImageSparseDrefGather ||
  580. opcode == spv::Op::OpImageSparseRead;
  581. }
  582. SpirvImageQuery::SpirvImageQuery(spv::Op op, QualType resultType,
  583. SourceLocation loc, SpirvInstruction *img,
  584. SpirvInstruction *lodInst,
  585. SpirvInstruction *coordInst)
  586. : SpirvInstruction(IK_ImageQuery, op, resultType, loc), image(img),
  587. lod(lodInst), coordinate(coordInst) {
  588. assert(op == spv::Op::OpImageQueryFormat ||
  589. op == spv::Op::OpImageQueryOrder || op == spv::Op::OpImageQuerySize ||
  590. op == spv::Op::OpImageQueryLevels ||
  591. op == spv::Op::OpImageQuerySamples || op == spv::Op::OpImageQueryLod ||
  592. op == spv::Op::OpImageQuerySizeLod);
  593. if (lodInst)
  594. assert(op == spv::Op::OpImageQuerySizeLod);
  595. if (coordInst)
  596. assert(op == spv::Op::OpImageQueryLod);
  597. }
  598. SpirvImageSparseTexelsResident::SpirvImageSparseTexelsResident(
  599. QualType resultType, SourceLocation loc, SpirvInstruction *resCode)
  600. : SpirvInstruction(IK_ImageSparseTexelsResident,
  601. spv::Op::OpImageSparseTexelsResident, resultType, loc),
  602. residentCode(resCode) {}
  603. SpirvImageTexelPointer::SpirvImageTexelPointer(QualType resultType,
  604. SourceLocation loc,
  605. SpirvInstruction *imageInst,
  606. SpirvInstruction *coordinateInst,
  607. SpirvInstruction *sampleInst)
  608. : SpirvInstruction(IK_ImageTexelPointer, spv::Op::OpImageTexelPointer,
  609. resultType, loc),
  610. image(imageInst), coordinate(coordinateInst), sample(sampleInst) {}
  611. SpirvLoad::SpirvLoad(QualType resultType, SourceLocation loc,
  612. SpirvInstruction *pointerInst,
  613. llvm::Optional<spv::MemoryAccessMask> mask)
  614. : SpirvInstruction(IK_Load, spv::Op::OpLoad, resultType, loc),
  615. pointer(pointerInst), memoryAccess(mask) {}
  616. SpirvCopyObject::SpirvCopyObject(QualType resultType, SourceLocation loc,
  617. SpirvInstruction *pointerInst)
  618. : SpirvInstruction(IK_CopyObject, spv::Op::OpCopyObject, resultType, loc),
  619. pointer(pointerInst) {}
  620. SpirvSampledImage::SpirvSampledImage(QualType resultType, SourceLocation loc,
  621. SpirvInstruction *imageInst,
  622. SpirvInstruction *samplerInst)
  623. : SpirvInstruction(IK_SampledImage, spv::Op::OpSampledImage, resultType,
  624. loc),
  625. image(imageInst), sampler(samplerInst) {}
  626. SpirvSelect::SpirvSelect(QualType resultType, SourceLocation loc,
  627. SpirvInstruction *cond, SpirvInstruction *trueInst,
  628. SpirvInstruction *falseInst)
  629. : SpirvInstruction(IK_Select, spv::Op::OpSelect, resultType, loc),
  630. condition(cond), trueObject(trueInst), falseObject(falseInst) {}
  631. SpirvSpecConstantBinaryOp::SpirvSpecConstantBinaryOp(spv::Op specConstantOp,
  632. QualType resultType,
  633. SourceLocation loc,
  634. SpirvInstruction *op1,
  635. SpirvInstruction *op2)
  636. : SpirvInstruction(IK_SpecConstantBinaryOp, spv::Op::OpSpecConstantOp,
  637. resultType, loc),
  638. specOp(specConstantOp), operand1(op1), operand2(op2) {}
  639. SpirvSpecConstantUnaryOp::SpirvSpecConstantUnaryOp(spv::Op specConstantOp,
  640. QualType resultType,
  641. SourceLocation loc,
  642. SpirvInstruction *op)
  643. : SpirvInstruction(IK_SpecConstantUnaryOp, spv::Op::OpSpecConstantOp,
  644. resultType, loc),
  645. specOp(specConstantOp), operand(op) {}
  646. SpirvStore::SpirvStore(SourceLocation loc, SpirvInstruction *pointerInst,
  647. SpirvInstruction *objectInst,
  648. llvm::Optional<spv::MemoryAccessMask> mask)
  649. : SpirvInstruction(IK_Store, spv::Op::OpStore, QualType(), loc),
  650. pointer(pointerInst), object(objectInst), memoryAccess(mask) {}
  651. SpirvUnaryOp::SpirvUnaryOp(spv::Op opcode, QualType resultType,
  652. SourceLocation loc, SpirvInstruction *op)
  653. : SpirvInstruction(IK_UnaryOp, opcode, resultType, loc), operand(op) {}
  654. bool SpirvUnaryOp::isConversionOp() const {
  655. return opcode == spv::Op::OpConvertFToU || opcode == spv::Op::OpConvertFToS ||
  656. opcode == spv::Op::OpConvertSToF || opcode == spv::Op::OpConvertUToF ||
  657. opcode == spv::Op::OpUConvert || opcode == spv::Op::OpSConvert ||
  658. opcode == spv::Op::OpFConvert || opcode == spv::Op::OpQuantizeToF16 ||
  659. opcode == spv::Op::OpBitcast;
  660. }
  661. SpirvVectorShuffle::SpirvVectorShuffle(QualType resultType, SourceLocation loc,
  662. SpirvInstruction *vec1Inst,
  663. SpirvInstruction *vec2Inst,
  664. llvm::ArrayRef<uint32_t> componentsVec)
  665. : SpirvInstruction(IK_VectorShuffle, spv::Op::OpVectorShuffle, resultType,
  666. loc),
  667. vec1(vec1Inst), vec2(vec2Inst),
  668. components(componentsVec.begin(), componentsVec.end()) {}
  669. SpirvArrayLength::SpirvArrayLength(QualType resultType, SourceLocation loc,
  670. SpirvInstruction *structure_,
  671. uint32_t memberLiteral)
  672. : SpirvInstruction(IK_ArrayLength, spv::Op::OpArrayLength, resultType, loc),
  673. structure(structure_), arrayMember(memberLiteral) {}
  674. SpirvRayTracingOpNV::SpirvRayTracingOpNV(
  675. QualType resultType, spv::Op opcode,
  676. llvm::ArrayRef<SpirvInstruction *> vecOperands, SourceLocation loc)
  677. : SpirvInstruction(IK_RayTracingOpNV, opcode, resultType, loc),
  678. operands(vecOperands.begin(), vecOperands.end()) {}
  679. SpirvDemoteToHelperInvocationEXT::SpirvDemoteToHelperInvocationEXT(
  680. SourceLocation loc)
  681. : SpirvInstruction(IK_DemoteToHelperInvocationEXT,
  682. spv::Op::OpDemoteToHelperInvocationEXT, /*QualType*/ {},
  683. loc) {}
  684. SpirvRayQueryOpKHR::SpirvRayQueryOpKHR(
  685. QualType resultType, spv::Op opcode,
  686. llvm::ArrayRef<SpirvInstruction *> vecOperands, bool flags,
  687. SourceLocation loc)
  688. : SpirvInstruction(IK_RayQueryOpKHR, opcode, resultType, loc),
  689. operands(vecOperands.begin(), vecOperands.end()), cullFlags(flags) {}
  690. } // namespace spirv
  691. } // namespace clang