EmitVisitor.cpp 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740
  1. //===--- EmitVisitor.cpp - SPIR-V Emit Visitor Implementation ----*- 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. #include "EmitVisitor.h"
  10. #include "clang/SPIRV/BitwiseCast.h"
  11. #include "clang/SPIRV/SpirvBasicBlock.h"
  12. #include "clang/SPIRV/SpirvFunction.h"
  13. #include "clang/SPIRV/SpirvInstruction.h"
  14. #include "clang/SPIRV/SpirvType.h"
  15. #include "clang/SPIRV/String.h"
  16. namespace {
  17. /// Chops the given original string into multiple smaller ones to make sure they
  18. /// can be encoded in a sequence of OpSourceContinued instructions following an
  19. /// OpSource instruction.
  20. void chopString(llvm::StringRef original,
  21. llvm::SmallVectorImpl<llvm::StringRef> *chopped) {
  22. const uint32_t maxCharInOpSource = 0xFFFFu - 5u; // Minus operands and nul
  23. const uint32_t maxCharInContinue = 0xFFFFu - 2u; // Minus opcode and nul
  24. chopped->clear();
  25. if (original.size() > maxCharInOpSource) {
  26. chopped->push_back(llvm::StringRef(original.data(), maxCharInOpSource));
  27. original = llvm::StringRef(original.data() + maxCharInOpSource,
  28. original.size() - maxCharInOpSource);
  29. while (original.size() > maxCharInContinue) {
  30. chopped->push_back(llvm::StringRef(original.data(), maxCharInContinue));
  31. original = llvm::StringRef(original.data() + maxCharInContinue,
  32. original.size() - maxCharInContinue);
  33. }
  34. if (!original.empty()) {
  35. chopped->push_back(original);
  36. }
  37. } else if (!original.empty()) {
  38. chopped->push_back(original);
  39. }
  40. }
  41. /// Returns true if an OpLine instruction can be emitted for the given OpCode.
  42. /// According to the SPIR-V Spec section 2.4 (Logical Layout of a Module), the
  43. /// first section to allow use of OpLine debug information is after all
  44. /// annotation instructions.
  45. bool isOpLineLegalForOp(spv::Op op) {
  46. switch (op) {
  47. // Preamble binary
  48. case spv::Op::OpCapability:
  49. case spv::Op::OpExtension:
  50. case spv::Op::OpExtInstImport:
  51. case spv::Op::OpMemoryModel:
  52. case spv::Op::OpEntryPoint:
  53. case spv::Op::OpExecutionMode:
  54. case spv::Op::OpExecutionModeId:
  55. // Debug binary
  56. case spv::Op::OpString:
  57. case spv::Op::OpSource:
  58. case spv::Op::OpSourceExtension:
  59. case spv::Op::OpSourceContinued:
  60. case spv::Op::OpName:
  61. case spv::Op::OpMemberName:
  62. // Annotation binary
  63. case spv::Op::OpModuleProcessed:
  64. case spv::Op::OpDecorate:
  65. case spv::Op::OpDecorateId:
  66. case spv::Op::OpMemberDecorate:
  67. case spv::Op::OpGroupDecorate:
  68. case spv::Op::OpGroupMemberDecorate:
  69. case spv::Op::OpDecorationGroup:
  70. case spv::Op::OpDecorateStringGOOGLE:
  71. case spv::Op::OpMemberDecorateStringGOOGLE:
  72. return false;
  73. default:
  74. return true;
  75. }
  76. }
  77. // Returns SPIR-V version that will be used in SPIR-V header section.
  78. uint32_t getHeaderVersion(llvm::StringRef env) {
  79. if (env == "vulkan1.1")
  80. return 0x00010300u;
  81. if (env == "vulkan1.2")
  82. return 0x00010500u;
  83. return 0x00010000u;
  84. }
  85. // Returns true if the BufferBlock decoration is deprecated for the target
  86. // Vulkan environment.
  87. bool isBufferBlockDecorationDeprecated(
  88. const clang::spirv::SpirvCodeGenOptions &opts) {
  89. return opts.targetEnv.compare("vulkan1.2") >= 0;
  90. }
  91. constexpr uint32_t kGeneratorNumber = 14;
  92. constexpr uint32_t kToolVersion = 0;
  93. } // anonymous namespace
  94. namespace clang {
  95. namespace spirv {
  96. EmitVisitor::Header::Header(uint32_t bound_, uint32_t version_)
  97. // We are using the unfied header, which shows spv::Version as the newest
  98. // version. But we need to stick to 1.0 for Vulkan consumption by default.
  99. : magicNumber(spv::MagicNumber), version(version_),
  100. generator((kGeneratorNumber << 16) | kToolVersion), bound(bound_),
  101. reserved(0) {}
  102. std::vector<uint32_t> EmitVisitor::Header::takeBinary() {
  103. std::vector<uint32_t> words;
  104. words.push_back(magicNumber);
  105. words.push_back(version);
  106. words.push_back(generator);
  107. words.push_back(bound);
  108. words.push_back(reserved);
  109. return words;
  110. }
  111. void EmitVisitor::emitDebugNameForInstruction(uint32_t resultId,
  112. llvm::StringRef debugName) {
  113. // Most instructions do not have a debug name associated with them.
  114. if (debugName.empty())
  115. return;
  116. curInst.clear();
  117. curInst.push_back(static_cast<uint32_t>(spv::Op::OpName));
  118. curInst.push_back(resultId);
  119. encodeString(debugName);
  120. curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
  121. debugVariableBinary.insert(debugVariableBinary.end(), curInst.begin(),
  122. curInst.end());
  123. }
  124. void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc) {
  125. // Based on SPIR-V spec, OpSelectionMerge must immediately precede either an
  126. // OpBranchConditional or OpSwitch instruction. Similarly OpLoopMerge must
  127. // immediately precede either an OpBranch or OpBranchConditional instruction.
  128. if (lastOpWasMergeInst) {
  129. lastOpWasMergeInst = false;
  130. return;
  131. }
  132. if (op == spv::Op::OpSelectionMerge || op == spv::Op::OpLoopMerge)
  133. lastOpWasMergeInst = true;
  134. if (!isOpLineLegalForOp(op))
  135. return;
  136. if (!spvOptions.debugInfoLine)
  137. return;
  138. auto fileId = debugMainFileId;
  139. const auto &sm = astContext.getSourceManager();
  140. const char *fileName = sm.getPresumedLoc(loc).getFilename();
  141. if (fileName) {
  142. auto it = debugFileIdMap.find(fileName);
  143. if (it == debugFileIdMap.end()) {
  144. // Emit the OpString for this new fileName.
  145. SpirvString *inst =
  146. new (context) SpirvString(/*SourceLocation*/ {}, fileName);
  147. visit(inst);
  148. it = debugFileIdMap.find(fileName);
  149. }
  150. fileId = it->second;
  151. }
  152. if (!fileId) {
  153. emitError("spvOptions.debugInfoLine is true but no fileId was set");
  154. return;
  155. }
  156. uint32_t line = sm.getPresumedLineNumber(loc);
  157. uint32_t column = sm.getPresumedColumnNumber(loc);
  158. if (!line || !column)
  159. return;
  160. if (line == debugLine && column == debugColumn)
  161. return;
  162. // We must update these two values to emit the next Opline.
  163. debugLine = line;
  164. debugColumn = column;
  165. curInst.clear();
  166. curInst.push_back(static_cast<uint32_t>(spv::Op::OpLine));
  167. curInst.push_back(fileId);
  168. curInst.push_back(line);
  169. curInst.push_back(column);
  170. curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
  171. mainBinary.insert(mainBinary.end(), curInst.begin(), curInst.end());
  172. }
  173. void EmitVisitor::initInstruction(SpirvInstruction *inst) {
  174. // Emit the result type if the instruction has a result type.
  175. if (inst->hasResultType()) {
  176. const uint32_t resultTypeId = typeHandler.emitType(inst->getResultType());
  177. inst->setResultTypeId(resultTypeId);
  178. }
  179. // Emit NonUniformEXT decoration (if any).
  180. if (inst->isNonUniform()) {
  181. typeHandler.emitDecoration(getOrAssignResultId<SpirvInstruction>(inst),
  182. spv::Decoration::NonUniformEXT, {});
  183. }
  184. // Emit RelaxedPrecision decoration (if any).
  185. if (inst->isRelaxedPrecision()) {
  186. typeHandler.emitDecoration(getOrAssignResultId<SpirvInstruction>(inst),
  187. spv::Decoration::RelaxedPrecision, {});
  188. }
  189. // Emit NoContraction decoration (if any).
  190. if (inst->isPrecise() && inst->isArithmeticInstruction()) {
  191. typeHandler.emitDecoration(getOrAssignResultId<SpirvInstruction>(inst),
  192. spv::Decoration::NoContraction, {});
  193. }
  194. const auto op = inst->getopcode();
  195. emitDebugLine(op, inst->getSourceLocation());
  196. // Initialize the current instruction for emitting.
  197. curInst.clear();
  198. curInst.push_back(static_cast<uint32_t>(op));
  199. }
  200. void EmitVisitor::initInstruction(spv::Op op, const SourceLocation &loc) {
  201. emitDebugLine(op, loc);
  202. curInst.clear();
  203. curInst.push_back(static_cast<uint32_t>(op));
  204. }
  205. void EmitVisitor::finalizeInstruction() {
  206. const auto op = static_cast<spv::Op>(curInst[0]);
  207. curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
  208. switch (op) {
  209. case spv::Op::OpCapability:
  210. case spv::Op::OpExtension:
  211. case spv::Op::OpExtInstImport:
  212. case spv::Op::OpMemoryModel:
  213. case spv::Op::OpEntryPoint:
  214. case spv::Op::OpExecutionMode:
  215. case spv::Op::OpExecutionModeId:
  216. preambleBinary.insert(preambleBinary.end(), curInst.begin(), curInst.end());
  217. break;
  218. case spv::Op::OpString:
  219. case spv::Op::OpSource:
  220. case spv::Op::OpSourceExtension:
  221. case spv::Op::OpSourceContinued:
  222. debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
  223. curInst.end());
  224. break;
  225. case spv::Op::OpName:
  226. case spv::Op::OpMemberName:
  227. debugVariableBinary.insert(debugVariableBinary.end(), curInst.begin(),
  228. curInst.end());
  229. break;
  230. case spv::Op::OpModuleProcessed:
  231. case spv::Op::OpDecorate:
  232. case spv::Op::OpDecorateId:
  233. case spv::Op::OpMemberDecorate:
  234. case spv::Op::OpGroupDecorate:
  235. case spv::Op::OpGroupMemberDecorate:
  236. case spv::Op::OpDecorationGroup:
  237. case spv::Op::OpDecorateStringGOOGLE:
  238. case spv::Op::OpMemberDecorateStringGOOGLE:
  239. annotationsBinary.insert(annotationsBinary.end(), curInst.begin(),
  240. curInst.end());
  241. break;
  242. case spv::Op::OpConstant:
  243. case spv::Op::OpConstantNull:
  244. case spv::Op::OpConstantFalse:
  245. case spv::Op::OpConstantTrue:
  246. case spv::Op::OpSpecConstantTrue:
  247. case spv::Op::OpSpecConstantFalse:
  248. case spv::Op::OpSpecConstant:
  249. case spv::Op::OpSpecConstantOp:
  250. typeConstantBinary.insert(typeConstantBinary.end(), curInst.begin(),
  251. curInst.end());
  252. break;
  253. default:
  254. mainBinary.insert(mainBinary.end(), curInst.begin(), curInst.end());
  255. break;
  256. }
  257. }
  258. std::vector<uint32_t> EmitVisitor::takeBinary() {
  259. std::vector<uint32_t> result;
  260. Header header(takeNextId(), getHeaderVersion(spvOptions.targetEnv));
  261. auto headerBinary = header.takeBinary();
  262. result.insert(result.end(), headerBinary.begin(), headerBinary.end());
  263. result.insert(result.end(), preambleBinary.begin(), preambleBinary.end());
  264. result.insert(result.end(), debugFileBinary.begin(), debugFileBinary.end());
  265. result.insert(result.end(), debugVariableBinary.begin(),
  266. debugVariableBinary.end());
  267. result.insert(result.end(), annotationsBinary.begin(),
  268. annotationsBinary.end());
  269. result.insert(result.end(), typeConstantBinary.begin(),
  270. typeConstantBinary.end());
  271. result.insert(result.end(), mainBinary.begin(), mainBinary.end());
  272. return result;
  273. }
  274. void EmitVisitor::encodeString(llvm::StringRef value) {
  275. const auto &words = string::encodeSPIRVString(value);
  276. curInst.insert(curInst.end(), words.begin(), words.end());
  277. }
  278. bool EmitVisitor::visit(SpirvModule *, Phase) {
  279. // No pre-visit operations needed for SpirvModule.
  280. return true;
  281. }
  282. bool EmitVisitor::visit(SpirvFunction *fn, Phase phase) {
  283. assert(fn);
  284. // Before emitting the function
  285. if (phase == Visitor::Phase::Init) {
  286. const uint32_t returnTypeId = typeHandler.emitType(fn->getReturnType());
  287. const uint32_t functionTypeId = typeHandler.emitType(fn->getFunctionType());
  288. // Emit OpFunction
  289. initInstruction(spv::Op::OpFunction, fn->getSourceLocation());
  290. curInst.push_back(returnTypeId);
  291. curInst.push_back(getOrAssignResultId<SpirvFunction>(fn));
  292. curInst.push_back(
  293. static_cast<uint32_t>(spv::FunctionControlMask::MaskNone));
  294. curInst.push_back(functionTypeId);
  295. finalizeInstruction();
  296. emitDebugNameForInstruction(getOrAssignResultId<SpirvFunction>(fn),
  297. fn->getFunctionName());
  298. // RelaxedPrecision decoration may be applied to an OpFunction instruction.
  299. if (fn->isRelaxedPrecision())
  300. typeHandler.emitDecoration(getOrAssignResultId<SpirvFunction>(fn),
  301. spv::Decoration::RelaxedPrecision, {});
  302. }
  303. // After emitting the function
  304. else if (phase == Visitor::Phase::Done) {
  305. // Emit OpFunctionEnd
  306. initInstruction(spv::Op::OpFunctionEnd, /* SourceLocation */ {});
  307. finalizeInstruction();
  308. }
  309. return true;
  310. }
  311. bool EmitVisitor::visit(SpirvBasicBlock *bb, Phase phase) {
  312. assert(bb);
  313. // Before emitting the basic block.
  314. if (phase == Visitor::Phase::Init) {
  315. // Emit OpLabel
  316. initInstruction(spv::Op::OpLabel, /* SourceLocation */ {});
  317. curInst.push_back(getOrAssignResultId<SpirvBasicBlock>(bb));
  318. finalizeInstruction();
  319. emitDebugNameForInstruction(getOrAssignResultId<SpirvBasicBlock>(bb),
  320. bb->getName());
  321. }
  322. // After emitting the basic block
  323. else if (phase == Visitor::Phase::Done) {
  324. assert(bb->hasTerminator());
  325. }
  326. return true;
  327. }
  328. bool EmitVisitor::visit(SpirvCapability *cap) {
  329. initInstruction(cap);
  330. curInst.push_back(static_cast<uint32_t>(cap->getCapability()));
  331. finalizeInstruction();
  332. return true;
  333. }
  334. bool EmitVisitor::visit(SpirvExtension *ext) {
  335. initInstruction(ext);
  336. encodeString(ext->getExtensionName());
  337. finalizeInstruction();
  338. return true;
  339. }
  340. bool EmitVisitor::visit(SpirvExtInstImport *inst) {
  341. initInstruction(inst);
  342. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  343. encodeString(inst->getExtendedInstSetName());
  344. finalizeInstruction();
  345. return true;
  346. }
  347. bool EmitVisitor::visit(SpirvMemoryModel *inst) {
  348. initInstruction(inst);
  349. curInst.push_back(static_cast<uint32_t>(inst->getAddressingModel()));
  350. curInst.push_back(static_cast<uint32_t>(inst->getMemoryModel()));
  351. finalizeInstruction();
  352. return true;
  353. }
  354. bool EmitVisitor::visit(SpirvEntryPoint *inst) {
  355. initInstruction(inst);
  356. curInst.push_back(static_cast<uint32_t>(inst->getExecModel()));
  357. curInst.push_back(getOrAssignResultId<SpirvFunction>(inst->getEntryPoint()));
  358. encodeString(inst->getEntryPointName());
  359. for (auto *var : inst->getInterface())
  360. curInst.push_back(getOrAssignResultId<SpirvInstruction>(var));
  361. finalizeInstruction();
  362. return true;
  363. }
  364. bool EmitVisitor::visit(SpirvExecutionMode *inst) {
  365. initInstruction(inst);
  366. curInst.push_back(getOrAssignResultId<SpirvFunction>(inst->getEntryPoint()));
  367. curInst.push_back(static_cast<uint32_t>(inst->getExecutionMode()));
  368. curInst.insert(curInst.end(), inst->getParams().begin(),
  369. inst->getParams().end());
  370. finalizeInstruction();
  371. return true;
  372. }
  373. bool EmitVisitor::visit(SpirvString *inst) {
  374. initInstruction(inst);
  375. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  376. encodeString(inst->getString());
  377. finalizeInstruction();
  378. if (spvOptions.debugInfoLine) {
  379. if (debugFileIdMap.find(inst->getString()) != debugFileIdMap.end())
  380. return true;
  381. debugFileIdMap[inst->getString()] =
  382. getOrAssignResultId<SpirvInstruction>(inst);
  383. }
  384. return true;
  385. }
  386. bool EmitVisitor::visit(SpirvSource *inst) {
  387. // Emit the OpString for the file name.
  388. if (inst->hasFile()) {
  389. visit(inst->getFile());
  390. if (spvOptions.debugInfoLine && !debugMainFileId)
  391. debugMainFileId = debugFileIdMap[inst->getFile()->getString()];
  392. }
  393. // Chop up the source into multiple segments if it is too long.
  394. llvm::Optional<llvm::StringRef> firstSnippet = llvm::None;
  395. llvm::SmallVector<llvm::StringRef, 2> choppedSrcCode;
  396. if (!inst->getSource().empty()) {
  397. chopString(inst->getSource(), &choppedSrcCode);
  398. if (!choppedSrcCode.empty()) {
  399. firstSnippet = llvm::Optional<llvm::StringRef>(choppedSrcCode.front());
  400. }
  401. }
  402. initInstruction(inst);
  403. curInst.push_back(static_cast<uint32_t>(inst->getSourceLanguage()));
  404. curInst.push_back(static_cast<uint32_t>(inst->getVersion()));
  405. if (inst->hasFile()) {
  406. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getFile()));
  407. }
  408. if (firstSnippet.hasValue()) {
  409. // Note: in order to improve performance and avoid multiple copies, we
  410. // encode this (potentially large) string directly into the debugFileBinary.
  411. const auto &words = string::encodeSPIRVString(firstSnippet.getValue());
  412. const auto numWordsInInstr = curInst.size() + words.size();
  413. curInst[0] |= static_cast<uint32_t>(numWordsInInstr) << 16;
  414. debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
  415. curInst.end());
  416. debugFileBinary.insert(debugFileBinary.end(), words.begin(), words.end());
  417. } else {
  418. curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
  419. debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
  420. curInst.end());
  421. }
  422. // Now emit OpSourceContinued for the [second:last] snippet.
  423. for (uint32_t i = 1; i < choppedSrcCode.size(); ++i) {
  424. initInstruction(spv::Op::OpSourceContinued, /* SourceLocation */ {});
  425. // Note: in order to improve performance and avoid multiple copies, we
  426. // encode this (potentially large) string directly into the debugFileBinary.
  427. const auto &words = string::encodeSPIRVString(choppedSrcCode[i]);
  428. const auto numWordsInInstr = curInst.size() + words.size();
  429. curInst[0] |= static_cast<uint32_t>(numWordsInInstr) << 16;
  430. debugFileBinary.insert(debugFileBinary.end(), curInst.begin(),
  431. curInst.end());
  432. debugFileBinary.insert(debugFileBinary.end(), words.begin(), words.end());
  433. }
  434. return true;
  435. }
  436. bool EmitVisitor::visit(SpirvModuleProcessed *inst) {
  437. initInstruction(inst);
  438. encodeString(inst->getProcess());
  439. finalizeInstruction();
  440. return true;
  441. }
  442. bool EmitVisitor::visit(SpirvDecoration *inst) {
  443. initInstruction(inst);
  444. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getTarget()));
  445. if (inst->isMemberDecoration())
  446. curInst.push_back(inst->getMemberIndex());
  447. curInst.push_back(static_cast<uint32_t>(inst->getDecoration()));
  448. if (!inst->getParams().empty()) {
  449. curInst.insert(curInst.end(), inst->getParams().begin(),
  450. inst->getParams().end());
  451. }
  452. if (!inst->getIdParams().empty()) {
  453. for (auto *paramInstr : inst->getIdParams())
  454. curInst.push_back(getOrAssignResultId<SpirvInstruction>(paramInstr));
  455. }
  456. finalizeInstruction();
  457. return true;
  458. }
  459. bool EmitVisitor::visit(SpirvVariable *inst) {
  460. initInstruction(inst);
  461. curInst.push_back(inst->getResultTypeId());
  462. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  463. curInst.push_back(static_cast<uint32_t>(inst->getStorageClass()));
  464. if (inst->hasInitializer())
  465. curInst.push_back(
  466. getOrAssignResultId<SpirvInstruction>(inst->getInitializer()));
  467. finalizeInstruction();
  468. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  469. inst->getDebugName());
  470. if (spvOptions.enableReflect && inst->hasBinding() &&
  471. !inst->getHlslUserType().empty()) {
  472. typeHandler.emitDecoration(
  473. getOrAssignResultId<SpirvInstruction>(inst),
  474. spv::Decoration::UserTypeGOOGLE,
  475. string::encodeSPIRVString(inst->getHlslUserType().lower()));
  476. }
  477. return true;
  478. }
  479. bool EmitVisitor::visit(SpirvFunctionParameter *inst) {
  480. initInstruction(inst);
  481. curInst.push_back(inst->getResultTypeId());
  482. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  483. finalizeInstruction();
  484. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  485. inst->getDebugName());
  486. return true;
  487. }
  488. bool EmitVisitor::visit(SpirvLoopMerge *inst) {
  489. initInstruction(inst);
  490. curInst.push_back(
  491. getOrAssignResultId<SpirvBasicBlock>(inst->getMergeBlock()));
  492. curInst.push_back(
  493. getOrAssignResultId<SpirvBasicBlock>(inst->getContinueTarget()));
  494. curInst.push_back(static_cast<uint32_t>(inst->getLoopControlMask()));
  495. finalizeInstruction();
  496. return true;
  497. }
  498. bool EmitVisitor::visit(SpirvSelectionMerge *inst) {
  499. initInstruction(inst);
  500. curInst.push_back(
  501. getOrAssignResultId<SpirvBasicBlock>(inst->getMergeBlock()));
  502. curInst.push_back(static_cast<uint32_t>(inst->getSelectionControlMask()));
  503. finalizeInstruction();
  504. return true;
  505. }
  506. bool EmitVisitor::visit(SpirvBranch *inst) {
  507. initInstruction(inst);
  508. curInst.push_back(
  509. getOrAssignResultId<SpirvBasicBlock>(inst->getTargetLabel()));
  510. finalizeInstruction();
  511. return true;
  512. }
  513. bool EmitVisitor::visit(SpirvBranchConditional *inst) {
  514. initInstruction(inst);
  515. curInst.push_back(
  516. getOrAssignResultId<SpirvInstruction>(inst->getCondition()));
  517. curInst.push_back(getOrAssignResultId<SpirvBasicBlock>(inst->getTrueLabel()));
  518. curInst.push_back(
  519. getOrAssignResultId<SpirvBasicBlock>(inst->getFalseLabel()));
  520. finalizeInstruction();
  521. return true;
  522. }
  523. bool EmitVisitor::visit(SpirvKill *inst) {
  524. initInstruction(inst);
  525. finalizeInstruction();
  526. return true;
  527. }
  528. bool EmitVisitor::visit(SpirvReturn *inst) {
  529. initInstruction(inst);
  530. if (inst->hasReturnValue()) {
  531. curInst.push_back(
  532. getOrAssignResultId<SpirvInstruction>(inst->getReturnValue()));
  533. }
  534. finalizeInstruction();
  535. return true;
  536. }
  537. bool EmitVisitor::visit(SpirvSwitch *inst) {
  538. initInstruction(inst);
  539. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getSelector()));
  540. curInst.push_back(
  541. getOrAssignResultId<SpirvBasicBlock>(inst->getDefaultLabel()));
  542. for (const auto &target : inst->getTargets()) {
  543. curInst.push_back(target.first);
  544. curInst.push_back(getOrAssignResultId<SpirvBasicBlock>(target.second));
  545. }
  546. finalizeInstruction();
  547. return true;
  548. }
  549. bool EmitVisitor::visit(SpirvUnreachable *inst) {
  550. initInstruction(inst);
  551. finalizeInstruction();
  552. return true;
  553. }
  554. bool EmitVisitor::visit(SpirvAccessChain *inst) {
  555. initInstruction(inst);
  556. curInst.push_back(inst->getResultTypeId());
  557. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  558. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getBase()));
  559. for (const auto index : inst->getIndexes())
  560. curInst.push_back(getOrAssignResultId<SpirvInstruction>(index));
  561. finalizeInstruction();
  562. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  563. inst->getDebugName());
  564. return true;
  565. }
  566. bool EmitVisitor::visit(SpirvAtomic *inst) {
  567. const auto op = inst->getopcode();
  568. initInstruction(inst);
  569. if (op != spv::Op::OpAtomicStore && op != spv::Op::OpAtomicFlagClear) {
  570. curInst.push_back(inst->getResultTypeId());
  571. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  572. }
  573. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getPointer()));
  574. curInst.push_back(typeHandler.getOrCreateConstantInt(
  575. llvm::APInt(32, static_cast<uint32_t>(inst->getScope())),
  576. context.getUIntType(32), /*isSpecConst */ false));
  577. curInst.push_back(typeHandler.getOrCreateConstantInt(
  578. llvm::APInt(32, static_cast<uint32_t>(inst->getMemorySemantics())),
  579. context.getUIntType(32), /*isSpecConst */ false));
  580. if (inst->hasComparator())
  581. curInst.push_back(typeHandler.getOrCreateConstantInt(
  582. llvm::APInt(32,
  583. static_cast<uint32_t>(inst->getMemorySemanticsUnequal())),
  584. context.getUIntType(32), /*isSpecConst */ false));
  585. if (inst->hasValue())
  586. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getValue()));
  587. if (inst->hasComparator())
  588. curInst.push_back(
  589. getOrAssignResultId<SpirvInstruction>(inst->getComparator()));
  590. finalizeInstruction();
  591. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  592. inst->getDebugName());
  593. return true;
  594. }
  595. bool EmitVisitor::visit(SpirvBarrier *inst) {
  596. const uint32_t executionScopeId =
  597. inst->isControlBarrier()
  598. ? typeHandler.getOrCreateConstantInt(
  599. llvm::APInt(32,
  600. static_cast<uint32_t>(inst->getExecutionScope())),
  601. context.getUIntType(32), /*isSpecConst */ false)
  602. : 0;
  603. const uint32_t memoryScopeId = typeHandler.getOrCreateConstantInt(
  604. llvm::APInt(32, static_cast<uint32_t>(inst->getMemoryScope())),
  605. context.getUIntType(32), /*isSpecConst */ false);
  606. const uint32_t memorySemanticsId = typeHandler.getOrCreateConstantInt(
  607. llvm::APInt(32, static_cast<uint32_t>(inst->getMemorySemantics())),
  608. context.getUIntType(32), /* isSpecConst */ false);
  609. initInstruction(inst);
  610. if (inst->isControlBarrier())
  611. curInst.push_back(executionScopeId);
  612. curInst.push_back(memoryScopeId);
  613. curInst.push_back(memorySemanticsId);
  614. finalizeInstruction();
  615. return true;
  616. }
  617. bool EmitVisitor::visit(SpirvBinaryOp *inst) {
  618. initInstruction(inst);
  619. curInst.push_back(inst->getResultTypeId());
  620. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  621. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOperand1()));
  622. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOperand2()));
  623. finalizeInstruction();
  624. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  625. inst->getDebugName());
  626. return true;
  627. }
  628. bool EmitVisitor::visit(SpirvBitFieldExtract *inst) {
  629. initInstruction(inst);
  630. curInst.push_back(inst->getResultTypeId());
  631. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  632. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getBase()));
  633. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOffset()));
  634. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getCount()));
  635. finalizeInstruction();
  636. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  637. inst->getDebugName());
  638. return true;
  639. }
  640. bool EmitVisitor::visit(SpirvBitFieldInsert *inst) {
  641. initInstruction(inst);
  642. curInst.push_back(inst->getResultTypeId());
  643. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  644. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getBase()));
  645. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getInsert()));
  646. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOffset()));
  647. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getCount()));
  648. finalizeInstruction();
  649. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  650. inst->getDebugName());
  651. return true;
  652. }
  653. bool EmitVisitor::visit(SpirvConstantBoolean *inst) {
  654. typeHandler.getOrCreateConstant(inst);
  655. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  656. inst->getDebugName());
  657. return true;
  658. }
  659. bool EmitVisitor::visit(SpirvConstantInteger *inst) {
  660. // Note: Since array types need to create uint 32-bit constants for result-id
  661. // of array length, the typeHandler keeps track of uint32 constant uniqueness.
  662. // Therefore emitting uint32 constants should be handled by the typeHandler.
  663. typeHandler.getOrCreateConstant(inst);
  664. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  665. inst->getDebugName());
  666. return true;
  667. }
  668. bool EmitVisitor::visit(SpirvConstantFloat *inst) {
  669. typeHandler.getOrCreateConstant(inst);
  670. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  671. inst->getDebugName());
  672. return true;
  673. }
  674. bool EmitVisitor::visit(SpirvConstantComposite *inst) {
  675. typeHandler.getOrCreateConstant(inst);
  676. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  677. inst->getDebugName());
  678. return true;
  679. }
  680. bool EmitVisitor::visit(SpirvConstantNull *inst) {
  681. typeHandler.getOrCreateConstant(inst);
  682. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  683. inst->getDebugName());
  684. return true;
  685. }
  686. bool EmitVisitor::visit(SpirvCompositeConstruct *inst) {
  687. initInstruction(inst);
  688. curInst.push_back(inst->getResultTypeId());
  689. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  690. for (const auto constituent : inst->getConstituents())
  691. curInst.push_back(getOrAssignResultId<SpirvInstruction>(constituent));
  692. finalizeInstruction();
  693. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  694. inst->getDebugName());
  695. return true;
  696. }
  697. bool EmitVisitor::visit(SpirvCompositeExtract *inst) {
  698. initInstruction(inst);
  699. curInst.push_back(inst->getResultTypeId());
  700. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  701. curInst.push_back(
  702. getOrAssignResultId<SpirvInstruction>(inst->getComposite()));
  703. for (const auto constituent : inst->getIndexes())
  704. curInst.push_back(constituent);
  705. finalizeInstruction();
  706. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  707. inst->getDebugName());
  708. return true;
  709. }
  710. bool EmitVisitor::visit(SpirvCompositeInsert *inst) {
  711. initInstruction(inst);
  712. curInst.push_back(inst->getResultTypeId());
  713. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  714. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getObject()));
  715. curInst.push_back(
  716. getOrAssignResultId<SpirvInstruction>(inst->getComposite()));
  717. for (const auto constituent : inst->getIndexes())
  718. curInst.push_back(constituent);
  719. finalizeInstruction();
  720. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  721. inst->getDebugName());
  722. return true;
  723. }
  724. bool EmitVisitor::visit(SpirvEmitVertex *inst) {
  725. initInstruction(inst);
  726. finalizeInstruction();
  727. return true;
  728. }
  729. bool EmitVisitor::visit(SpirvEndPrimitive *inst) {
  730. initInstruction(inst);
  731. finalizeInstruction();
  732. return true;
  733. }
  734. bool EmitVisitor::visit(SpirvExtInst *inst) {
  735. initInstruction(inst);
  736. curInst.push_back(inst->getResultTypeId());
  737. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  738. curInst.push_back(
  739. getOrAssignResultId<SpirvInstruction>(inst->getInstructionSet()));
  740. curInst.push_back(inst->getInstruction());
  741. for (const auto operand : inst->getOperands())
  742. curInst.push_back(getOrAssignResultId<SpirvInstruction>(operand));
  743. finalizeInstruction();
  744. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  745. inst->getDebugName());
  746. return true;
  747. }
  748. bool EmitVisitor::visit(SpirvFunctionCall *inst) {
  749. initInstruction(inst);
  750. curInst.push_back(inst->getResultTypeId());
  751. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  752. curInst.push_back(getOrAssignResultId<SpirvFunction>(inst->getFunction()));
  753. for (const auto arg : inst->getArgs())
  754. curInst.push_back(getOrAssignResultId<SpirvInstruction>(arg));
  755. finalizeInstruction();
  756. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  757. inst->getDebugName());
  758. return true;
  759. }
  760. bool EmitVisitor::visit(SpirvNonUniformBinaryOp *inst) {
  761. initInstruction(inst);
  762. curInst.push_back(inst->getResultTypeId());
  763. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  764. curInst.push_back(typeHandler.getOrCreateConstantInt(
  765. llvm::APInt(32, static_cast<uint32_t>(inst->getExecutionScope())),
  766. context.getUIntType(32), /* isSpecConst */ false));
  767. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getArg1()));
  768. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getArg2()));
  769. finalizeInstruction();
  770. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  771. inst->getDebugName());
  772. return true;
  773. }
  774. bool EmitVisitor::visit(SpirvNonUniformElect *inst) {
  775. initInstruction(inst);
  776. curInst.push_back(inst->getResultTypeId());
  777. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  778. curInst.push_back(typeHandler.getOrCreateConstantInt(
  779. llvm::APInt(32, static_cast<uint32_t>(inst->getExecutionScope())),
  780. context.getUIntType(32), /* isSpecConst */ false));
  781. finalizeInstruction();
  782. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  783. inst->getDebugName());
  784. return true;
  785. }
  786. bool EmitVisitor::visit(SpirvNonUniformUnaryOp *inst) {
  787. initInstruction(inst);
  788. curInst.push_back(inst->getResultTypeId());
  789. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  790. curInst.push_back(typeHandler.getOrCreateConstantInt(
  791. llvm::APInt(32, static_cast<uint32_t>(inst->getExecutionScope())),
  792. context.getUIntType(32), /* isSpecConst */ false));
  793. if (inst->hasGroupOp())
  794. curInst.push_back(static_cast<uint32_t>(inst->getGroupOp()));
  795. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getArg()));
  796. finalizeInstruction();
  797. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  798. inst->getDebugName());
  799. return true;
  800. }
  801. bool EmitVisitor::visit(SpirvImageOp *inst) {
  802. initInstruction(inst);
  803. if (!inst->isImageWrite()) {
  804. curInst.push_back(inst->getResultTypeId());
  805. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  806. }
  807. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getImage()));
  808. curInst.push_back(
  809. getOrAssignResultId<SpirvInstruction>(inst->getCoordinate()));
  810. if (inst->isImageWrite())
  811. curInst.push_back(
  812. getOrAssignResultId<SpirvInstruction>(inst->getTexelToWrite()));
  813. if (inst->hasDref())
  814. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getDref()));
  815. if (inst->hasComponent())
  816. curInst.push_back(
  817. getOrAssignResultId<SpirvInstruction>(inst->getComponent()));
  818. curInst.push_back(static_cast<uint32_t>(inst->getImageOperandsMask()));
  819. if (inst->getImageOperandsMask() != spv::ImageOperandsMask::MaskNone) {
  820. if (inst->hasBias())
  821. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getBias()));
  822. if (inst->hasLod())
  823. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getLod()));
  824. if (inst->hasGrad()) {
  825. curInst.push_back(
  826. getOrAssignResultId<SpirvInstruction>(inst->getGradDx()));
  827. curInst.push_back(
  828. getOrAssignResultId<SpirvInstruction>(inst->getGradDy()));
  829. }
  830. if (inst->hasConstOffset())
  831. curInst.push_back(
  832. getOrAssignResultId<SpirvInstruction>(inst->getConstOffset()));
  833. if (inst->hasOffset())
  834. curInst.push_back(
  835. getOrAssignResultId<SpirvInstruction>(inst->getOffset()));
  836. if (inst->hasConstOffsets())
  837. curInst.push_back(
  838. getOrAssignResultId<SpirvInstruction>(inst->getConstOffsets()));
  839. if (inst->hasSample())
  840. curInst.push_back(
  841. getOrAssignResultId<SpirvInstruction>(inst->getSample()));
  842. if (inst->hasMinLod())
  843. curInst.push_back(
  844. getOrAssignResultId<SpirvInstruction>(inst->getMinLod()));
  845. }
  846. finalizeInstruction();
  847. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  848. inst->getDebugName());
  849. return true;
  850. }
  851. bool EmitVisitor::visit(SpirvImageQuery *inst) {
  852. initInstruction(inst);
  853. curInst.push_back(inst->getResultTypeId());
  854. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  855. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getImage()));
  856. if (inst->hasCoordinate())
  857. curInst.push_back(
  858. getOrAssignResultId<SpirvInstruction>(inst->getCoordinate()));
  859. if (inst->hasLod())
  860. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getLod()));
  861. finalizeInstruction();
  862. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  863. inst->getDebugName());
  864. return true;
  865. }
  866. bool EmitVisitor::visit(SpirvImageSparseTexelsResident *inst) {
  867. initInstruction(inst);
  868. curInst.push_back(inst->getResultTypeId());
  869. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  870. curInst.push_back(
  871. getOrAssignResultId<SpirvInstruction>(inst->getResidentCode()));
  872. finalizeInstruction();
  873. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  874. inst->getDebugName());
  875. return true;
  876. }
  877. bool EmitVisitor::visit(SpirvImageTexelPointer *inst) {
  878. initInstruction(inst);
  879. curInst.push_back(inst->getResultTypeId());
  880. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  881. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getImage()));
  882. curInst.push_back(
  883. getOrAssignResultId<SpirvInstruction>(inst->getCoordinate()));
  884. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getSample()));
  885. finalizeInstruction();
  886. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  887. inst->getDebugName());
  888. return true;
  889. }
  890. bool EmitVisitor::visit(SpirvLoad *inst) {
  891. initInstruction(inst);
  892. curInst.push_back(inst->getResultTypeId());
  893. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  894. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getPointer()));
  895. if (inst->hasMemoryAccessSemantics())
  896. curInst.push_back(static_cast<uint32_t>(inst->getMemoryAccess()));
  897. finalizeInstruction();
  898. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  899. inst->getDebugName());
  900. return true;
  901. }
  902. bool EmitVisitor::visit(SpirvCopyObject *inst) {
  903. initInstruction(inst);
  904. curInst.push_back(inst->getResultTypeId());
  905. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  906. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getPointer()));
  907. finalizeInstruction();
  908. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  909. inst->getDebugName());
  910. return true;
  911. }
  912. bool EmitVisitor::visit(SpirvSampledImage *inst) {
  913. initInstruction(inst);
  914. curInst.push_back(inst->getResultTypeId());
  915. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  916. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getImage()));
  917. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getSampler()));
  918. finalizeInstruction();
  919. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  920. inst->getDebugName());
  921. return true;
  922. }
  923. bool EmitVisitor::visit(SpirvSelect *inst) {
  924. initInstruction(inst);
  925. curInst.push_back(inst->getResultTypeId());
  926. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  927. curInst.push_back(
  928. getOrAssignResultId<SpirvInstruction>(inst->getCondition()));
  929. curInst.push_back(
  930. getOrAssignResultId<SpirvInstruction>(inst->getTrueObject()));
  931. curInst.push_back(
  932. getOrAssignResultId<SpirvInstruction>(inst->getFalseObject()));
  933. finalizeInstruction();
  934. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  935. inst->getDebugName());
  936. return true;
  937. }
  938. bool EmitVisitor::visit(SpirvSpecConstantBinaryOp *inst) {
  939. initInstruction(inst);
  940. curInst.push_back(inst->getResultTypeId());
  941. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  942. curInst.push_back(static_cast<uint32_t>(inst->getSpecConstantopcode()));
  943. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOperand1()));
  944. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOperand2()));
  945. finalizeInstruction();
  946. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  947. inst->getDebugName());
  948. return true;
  949. }
  950. bool EmitVisitor::visit(SpirvSpecConstantUnaryOp *inst) {
  951. initInstruction(inst);
  952. curInst.push_back(inst->getResultTypeId());
  953. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  954. curInst.push_back(static_cast<uint32_t>(inst->getSpecConstantopcode()));
  955. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOperand()));
  956. finalizeInstruction();
  957. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  958. inst->getDebugName());
  959. return true;
  960. }
  961. bool EmitVisitor::visit(SpirvStore *inst) {
  962. initInstruction(inst);
  963. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getPointer()));
  964. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getObject()));
  965. if (inst->hasMemoryAccessSemantics())
  966. curInst.push_back(static_cast<uint32_t>(inst->getMemoryAccess()));
  967. finalizeInstruction();
  968. return true;
  969. }
  970. bool EmitVisitor::visit(SpirvUnaryOp *inst) {
  971. initInstruction(inst);
  972. curInst.push_back(inst->getResultTypeId());
  973. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  974. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getOperand()));
  975. finalizeInstruction();
  976. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  977. inst->getDebugName());
  978. return true;
  979. }
  980. bool EmitVisitor::visit(SpirvVectorShuffle *inst) {
  981. initInstruction(inst);
  982. curInst.push_back(inst->getResultTypeId());
  983. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  984. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getVec1()));
  985. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst->getVec2()));
  986. for (const auto component : inst->getComponents())
  987. curInst.push_back(component);
  988. finalizeInstruction();
  989. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  990. inst->getDebugName());
  991. return true;
  992. }
  993. bool EmitVisitor::visit(SpirvArrayLength *inst) {
  994. initInstruction(inst);
  995. curInst.push_back(inst->getResultTypeId());
  996. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  997. curInst.push_back(
  998. getOrAssignResultId<SpirvInstruction>(inst->getStructure()));
  999. curInst.push_back(inst->getArrayMember());
  1000. finalizeInstruction();
  1001. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  1002. inst->getDebugName());
  1003. return true;
  1004. }
  1005. bool EmitVisitor::visit(SpirvRayTracingOpNV *inst) {
  1006. initInstruction(inst);
  1007. if (inst->hasResultType()) {
  1008. curInst.push_back(inst->getResultTypeId());
  1009. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  1010. }
  1011. for (const auto operand : inst->getOperands())
  1012. curInst.push_back(getOrAssignResultId<SpirvInstruction>(operand));
  1013. finalizeInstruction();
  1014. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  1015. inst->getDebugName());
  1016. return true;
  1017. }
  1018. bool EmitVisitor::visit(SpirvDemoteToHelperInvocationEXT *inst) {
  1019. initInstruction(inst);
  1020. finalizeInstruction();
  1021. return true;
  1022. }
  1023. bool EmitVisitor::visit(SpirvRayQueryOpKHR *inst) {
  1024. initInstruction(inst);
  1025. if (inst->hasResultType()) {
  1026. curInst.push_back(inst->getResultTypeId());
  1027. curInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  1028. }
  1029. for (const auto operand : inst->getOperands())
  1030. curInst.push_back(getOrAssignResultId<SpirvInstruction>(operand));
  1031. finalizeInstruction();
  1032. emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(inst),
  1033. inst->getDebugName());
  1034. return true;
  1035. }
  1036. // EmitTypeHandler ------
  1037. void EmitTypeHandler::initTypeInstruction(spv::Op op) {
  1038. curTypeInst.clear();
  1039. curTypeInst.push_back(static_cast<uint32_t>(op));
  1040. }
  1041. void EmitTypeHandler::finalizeTypeInstruction() {
  1042. curTypeInst[0] |= static_cast<uint32_t>(curTypeInst.size()) << 16;
  1043. typeConstantBinary->insert(typeConstantBinary->end(), curTypeInst.begin(),
  1044. curTypeInst.end());
  1045. }
  1046. uint32_t EmitTypeHandler::getResultIdForType(const SpirvType *type,
  1047. bool *alreadyExists) {
  1048. assert(alreadyExists);
  1049. auto foundType = emittedTypes.find(type);
  1050. if (foundType != emittedTypes.end()) {
  1051. *alreadyExists = true;
  1052. return foundType->second;
  1053. }
  1054. *alreadyExists = false;
  1055. const uint32_t id = takeNextIdFunction();
  1056. emittedTypes[type] = id;
  1057. return id;
  1058. }
  1059. uint32_t EmitTypeHandler::getOrCreateConstant(SpirvConstant *inst) {
  1060. if (auto *constInt = dyn_cast<SpirvConstantInteger>(inst)) {
  1061. return getOrCreateConstantInt(constInt->getValue(),
  1062. constInt->getResultType(),
  1063. inst->isSpecConstant(), inst);
  1064. } else if (auto *constFloat = dyn_cast<SpirvConstantFloat>(inst)) {
  1065. return getOrCreateConstantFloat(constFloat);
  1066. } else if (auto *constComposite = dyn_cast<SpirvConstantComposite>(inst)) {
  1067. return getOrCreateConstantComposite(constComposite);
  1068. } else if (auto *constNull = dyn_cast<SpirvConstantNull>(inst)) {
  1069. return getOrCreateConstantNull(constNull);
  1070. } else if (auto *constBool = dyn_cast<SpirvConstantBoolean>(inst)) {
  1071. return getOrCreateConstantBool(constBool);
  1072. }
  1073. llvm_unreachable("cannot emit unknown constant type");
  1074. }
  1075. uint32_t EmitTypeHandler::getOrCreateConstantBool(SpirvConstantBoolean *inst) {
  1076. const auto index = static_cast<uint32_t>(inst->getValue());
  1077. const bool isSpecConst = inst->isSpecConstant();
  1078. // SpecConstants are not unique. We should not reuse them. e.g. it is possible
  1079. // to have multiple OpSpecConstantTrue instructions.
  1080. if (!isSpecConst && emittedConstantBools[index]) {
  1081. // Already emitted this constant. Reuse.
  1082. inst->setResultId(emittedConstantBools[index]->getResultId());
  1083. } else {
  1084. // Constant wasn't emitted in the past.
  1085. const uint32_t typeId = emitType(inst->getResultType());
  1086. initTypeInstruction(inst->getopcode());
  1087. curTypeInst.push_back(typeId);
  1088. curTypeInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  1089. finalizeTypeInstruction();
  1090. // Remember this constant for the future (if not a spec constant)
  1091. if (!isSpecConst)
  1092. emittedConstantBools[index] = inst;
  1093. }
  1094. return inst->getResultId();
  1095. }
  1096. uint32_t EmitTypeHandler::getOrCreateConstantNull(SpirvConstantNull *inst) {
  1097. auto found =
  1098. std::find_if(emittedConstantNulls.begin(), emittedConstantNulls.end(),
  1099. [inst](SpirvConstantNull *cachedConstant) {
  1100. return *cachedConstant == *inst;
  1101. });
  1102. if (found != emittedConstantNulls.end()) {
  1103. // We have already emitted this constant. Reuse.
  1104. inst->setResultId((*found)->getResultId());
  1105. } else {
  1106. // Constant wasn't emitted in the past.
  1107. const uint32_t typeId = emitType(inst->getResultType());
  1108. initTypeInstruction(spv::Op::OpConstantNull);
  1109. curTypeInst.push_back(typeId);
  1110. curTypeInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  1111. finalizeTypeInstruction();
  1112. // Remember this constant for the future
  1113. emittedConstantNulls.push_back(inst);
  1114. }
  1115. return inst->getResultId();
  1116. }
  1117. uint32_t EmitTypeHandler::getOrCreateConstantFloat(SpirvConstantFloat *inst) {
  1118. llvm::APFloat value = inst->getValue();
  1119. const SpirvType *type = inst->getResultType();
  1120. const bool isSpecConst = inst->isSpecConstant();
  1121. assert(isa<FloatType>(type));
  1122. const auto *floatType = dyn_cast<FloatType>(type);
  1123. const auto typeBitwidth = floatType->getBitwidth();
  1124. const auto valueBitwidth = llvm::APFloat::getSizeInBits(value.getSemantics());
  1125. auto valueToUse = value;
  1126. // If the type and the value have different widths, we need to convert the
  1127. // value to the width of the type. Error out if the conversion is lossy.
  1128. if (valueBitwidth != typeBitwidth) {
  1129. bool losesInfo = false;
  1130. const llvm::fltSemantics &targetSemantics =
  1131. typeBitwidth == 16 ? llvm::APFloat::IEEEhalf
  1132. : typeBitwidth == 32 ? llvm::APFloat::IEEEsingle
  1133. : llvm::APFloat::IEEEdouble;
  1134. const auto status = valueToUse.convert(
  1135. targetSemantics, llvm::APFloat::roundingMode::rmTowardZero, &losesInfo);
  1136. if (status != llvm::APFloat::opStatus::opOK &&
  1137. status != llvm::APFloat::opStatus::opInexact) {
  1138. emitError(
  1139. "evaluating float literal %0 at a lower bitwidth loses information",
  1140. {})
  1141. // Converting from 16bit to 32/64-bit won't lose information.
  1142. // So only 32/64-bit values can reach here.
  1143. << std::to_string(valueBitwidth == 32 ? valueToUse.convertToFloat()
  1144. : valueToUse.convertToDouble());
  1145. return 0;
  1146. }
  1147. }
  1148. auto valueTypePair = std::pair<uint64_t, const SpirvType *>(
  1149. valueToUse.bitcastToAPInt().getZExtValue(), type);
  1150. // SpecConstant instructions are not unique, so we should not re-use existing
  1151. // spec constants.
  1152. if (!isSpecConst) {
  1153. // If this constant has already been emitted, return its result-id.
  1154. auto foundResultId = emittedConstantFloats.find(valueTypePair);
  1155. if (foundResultId != emittedConstantFloats.end()) {
  1156. const uint32_t existingConstantResultId = foundResultId->second;
  1157. inst->setResultId(existingConstantResultId);
  1158. return existingConstantResultId;
  1159. }
  1160. }
  1161. // Start constructing the instruction
  1162. const uint32_t typeId = emitType(type);
  1163. initTypeInstruction(inst->getopcode());
  1164. curTypeInst.push_back(typeId);
  1165. const uint32_t constantResultId = getOrAssignResultId<SpirvInstruction>(inst);
  1166. curTypeInst.push_back(constantResultId);
  1167. // Start constructing the value word / words
  1168. if (typeBitwidth == 16) {
  1169. // According to the SPIR-V Spec:
  1170. // When the type's bit width is less than 32-bits, the literal's value
  1171. // appears in the low-order bits of the word, and the high-order bits must
  1172. // be 0 for a floating-point type.
  1173. curTypeInst.push_back(
  1174. static_cast<uint32_t>(valueToUse.bitcastToAPInt().getZExtValue()));
  1175. } else if (typeBitwidth == 32) {
  1176. curTypeInst.push_back(
  1177. cast::BitwiseCast<uint32_t, float>(valueToUse.convertToFloat()));
  1178. } else {
  1179. // TODO: The ordering of the 2 words depends on the endian-ness of the
  1180. // host machine.
  1181. struct wideFloat {
  1182. uint32_t word0;
  1183. uint32_t word1;
  1184. };
  1185. wideFloat words =
  1186. cast::BitwiseCast<wideFloat, double>(valueToUse.convertToDouble());
  1187. curTypeInst.push_back(words.word0);
  1188. curTypeInst.push_back(words.word1);
  1189. }
  1190. finalizeTypeInstruction();
  1191. // Remember this constant for future (if not a SpecConstant)
  1192. if (!isSpecConst)
  1193. emittedConstantFloats[valueTypePair] = constantResultId;
  1194. return constantResultId;
  1195. }
  1196. uint32_t
  1197. EmitTypeHandler::getOrCreateConstantInt(llvm::APInt value,
  1198. const SpirvType *type, bool isSpecConst,
  1199. SpirvInstruction *constantInstruction) {
  1200. auto valueTypePair =
  1201. std::pair<uint64_t, const SpirvType *>(value.getZExtValue(), type);
  1202. // SpecConstant instructions are not unique, so we should not re-use existing
  1203. // spec constants.
  1204. if (!isSpecConst) {
  1205. // If this constant has already been emitted, return its result-id.
  1206. auto foundResultId = emittedConstantInts.find(valueTypePair);
  1207. if (foundResultId != emittedConstantInts.end()) {
  1208. const uint32_t existingConstantResultId = foundResultId->second;
  1209. if (constantInstruction)
  1210. constantInstruction->setResultId(existingConstantResultId);
  1211. return existingConstantResultId;
  1212. }
  1213. }
  1214. assert(isa<IntegerType>(type));
  1215. const auto *intType = dyn_cast<IntegerType>(type);
  1216. const auto bitwidth = intType->getBitwidth();
  1217. const auto isSigned = intType->isSignedInt();
  1218. // Start constructing the instruction
  1219. const uint32_t typeId = emitType(type);
  1220. initTypeInstruction(isSpecConst ? spv::Op::OpSpecConstant
  1221. : spv::Op::OpConstant);
  1222. curTypeInst.push_back(typeId);
  1223. // Assign a result-id if one has not been provided.
  1224. uint32_t constantResultId = 0;
  1225. if (constantInstruction)
  1226. constantResultId =
  1227. getOrAssignResultId<SpirvInstruction>(constantInstruction);
  1228. else
  1229. constantResultId = takeNextIdFunction();
  1230. curTypeInst.push_back(constantResultId);
  1231. // Start constructing the value word / words
  1232. // For 16-bit and 32-bit cases, the value occupies 1 word in the instruction
  1233. if (bitwidth == 16 || bitwidth == 32) {
  1234. if (isSigned) {
  1235. curTypeInst.push_back(static_cast<int32_t>(value.getSExtValue()));
  1236. } else {
  1237. curTypeInst.push_back(static_cast<uint32_t>(value.getZExtValue()));
  1238. }
  1239. }
  1240. // 64-bit cases
  1241. else {
  1242. struct wideInt {
  1243. uint32_t word0;
  1244. uint32_t word1;
  1245. };
  1246. wideInt words;
  1247. if (isSigned) {
  1248. words = cast::BitwiseCast<wideInt, int64_t>(value.getSExtValue());
  1249. } else {
  1250. words = cast::BitwiseCast<wideInt, uint64_t>(value.getZExtValue());
  1251. }
  1252. curTypeInst.push_back(words.word0);
  1253. curTypeInst.push_back(words.word1);
  1254. }
  1255. finalizeTypeInstruction();
  1256. // Remember this constant for future (not needed for SpecConstants)
  1257. if (!isSpecConst)
  1258. emittedConstantInts[valueTypePair] = constantResultId;
  1259. return constantResultId;
  1260. }
  1261. uint32_t
  1262. EmitTypeHandler::getOrCreateConstantComposite(SpirvConstantComposite *inst) {
  1263. // First make sure all constituents have been visited and have a result-id.
  1264. for (auto constituent : inst->getConstituents())
  1265. getOrCreateConstant(constituent);
  1266. // SpecConstant instructions are not unique, so we should not re-use existing
  1267. // spec constants.
  1268. const bool isSpecConst = inst->isSpecConstant();
  1269. SpirvConstantComposite **found = nullptr;
  1270. if (!isSpecConst) {
  1271. found = std::find_if(
  1272. emittedConstantComposites.begin(), emittedConstantComposites.end(),
  1273. [inst](SpirvConstantComposite *cachedConstant) {
  1274. if (inst->getopcode() != cachedConstant->getopcode())
  1275. return false;
  1276. auto instConstituents = inst->getConstituents();
  1277. auto cachedConstituents = cachedConstant->getConstituents();
  1278. if (instConstituents.size() != cachedConstituents.size())
  1279. return false;
  1280. for (size_t i = 0; i < instConstituents.size(); ++i)
  1281. if (instConstituents[i]->getResultId() !=
  1282. cachedConstituents[i]->getResultId())
  1283. return false;
  1284. return true;
  1285. });
  1286. }
  1287. if (!isSpecConst && found != emittedConstantComposites.end()) {
  1288. // We have already emitted this constant. Reuse.
  1289. inst->setResultId((*found)->getResultId());
  1290. } else {
  1291. // Constant wasn't emitted in the past.
  1292. const uint32_t typeId = emitType(inst->getResultType());
  1293. initTypeInstruction(spv::Op::OpConstantComposite);
  1294. curTypeInst.push_back(typeId);
  1295. curTypeInst.push_back(getOrAssignResultId<SpirvInstruction>(inst));
  1296. for (auto constituent : inst->getConstituents())
  1297. curTypeInst.push_back(getOrAssignResultId<SpirvInstruction>(constituent));
  1298. finalizeTypeInstruction();
  1299. // Remember this constant for the future (if not a spec constant)
  1300. if (!isSpecConst)
  1301. emittedConstantComposites.push_back(inst);
  1302. }
  1303. return inst->getResultId();
  1304. }
  1305. uint32_t EmitTypeHandler::emitType(const SpirvType *type) {
  1306. // First get the decorations that would apply to this type.
  1307. bool alreadyExists = false;
  1308. const uint32_t id = getResultIdForType(type, &alreadyExists);
  1309. // If the type has already been emitted, we just need to return its
  1310. // <result-id>.
  1311. if (alreadyExists)
  1312. return id;
  1313. // Emit OpName for the type (if any).
  1314. emitNameForType(type->getName(), id);
  1315. if (isa<VoidType>(type)) {
  1316. initTypeInstruction(spv::Op::OpTypeVoid);
  1317. curTypeInst.push_back(id);
  1318. finalizeTypeInstruction();
  1319. }
  1320. // Boolean types
  1321. else if (isa<BoolType>(type)) {
  1322. initTypeInstruction(spv::Op::OpTypeBool);
  1323. curTypeInst.push_back(id);
  1324. finalizeTypeInstruction();
  1325. }
  1326. // Integer types
  1327. else if (const auto *intType = dyn_cast<IntegerType>(type)) {
  1328. initTypeInstruction(spv::Op::OpTypeInt);
  1329. curTypeInst.push_back(id);
  1330. curTypeInst.push_back(intType->getBitwidth());
  1331. curTypeInst.push_back(intType->isSignedInt() ? 1 : 0);
  1332. finalizeTypeInstruction();
  1333. }
  1334. // Float types
  1335. else if (const auto *floatType = dyn_cast<FloatType>(type)) {
  1336. initTypeInstruction(spv::Op::OpTypeFloat);
  1337. curTypeInst.push_back(id);
  1338. curTypeInst.push_back(floatType->getBitwidth());
  1339. finalizeTypeInstruction();
  1340. }
  1341. // Vector types
  1342. else if (const auto *vecType = dyn_cast<VectorType>(type)) {
  1343. const uint32_t elementTypeId = emitType(vecType->getElementType());
  1344. initTypeInstruction(spv::Op::OpTypeVector);
  1345. curTypeInst.push_back(id);
  1346. curTypeInst.push_back(elementTypeId);
  1347. curTypeInst.push_back(vecType->getElementCount());
  1348. finalizeTypeInstruction();
  1349. }
  1350. // Matrix types
  1351. else if (const auto *matType = dyn_cast<MatrixType>(type)) {
  1352. const uint32_t vecTypeId = emitType(matType->getVecType());
  1353. initTypeInstruction(spv::Op::OpTypeMatrix);
  1354. curTypeInst.push_back(id);
  1355. curTypeInst.push_back(vecTypeId);
  1356. curTypeInst.push_back(matType->getVecCount());
  1357. finalizeTypeInstruction();
  1358. // Note that RowMajor and ColMajor decorations only apply to structure
  1359. // members, and should not be handled here.
  1360. }
  1361. // Image types
  1362. else if (const auto *imageType = dyn_cast<ImageType>(type)) {
  1363. const uint32_t sampledTypeId = emitType(imageType->getSampledType());
  1364. initTypeInstruction(spv::Op::OpTypeImage);
  1365. curTypeInst.push_back(id);
  1366. curTypeInst.push_back(sampledTypeId);
  1367. curTypeInst.push_back(static_cast<uint32_t>(imageType->getDimension()));
  1368. curTypeInst.push_back(static_cast<uint32_t>(imageType->getDepth()));
  1369. curTypeInst.push_back(imageType->isArrayedImage() ? 1 : 0);
  1370. curTypeInst.push_back(imageType->isMSImage() ? 1 : 0);
  1371. curTypeInst.push_back(static_cast<uint32_t>(imageType->withSampler()));
  1372. curTypeInst.push_back(static_cast<uint32_t>(imageType->getImageFormat()));
  1373. finalizeTypeInstruction();
  1374. }
  1375. // Sampler types
  1376. else if (const auto *samplerType = dyn_cast<SamplerType>(type)) {
  1377. initTypeInstruction(spv::Op::OpTypeSampler);
  1378. curTypeInst.push_back(id);
  1379. finalizeTypeInstruction();
  1380. }
  1381. // SampledImage types
  1382. else if (const auto *sampledImageType = dyn_cast<SampledImageType>(type)) {
  1383. const uint32_t imageTypeId = emitType(sampledImageType->getImageType());
  1384. initTypeInstruction(spv::Op::OpTypeSampledImage);
  1385. curTypeInst.push_back(id);
  1386. curTypeInst.push_back(imageTypeId);
  1387. finalizeTypeInstruction();
  1388. }
  1389. // Array types
  1390. else if (const auto *arrayType = dyn_cast<ArrayType>(type)) {
  1391. // Emit the OpConstant instruction that is needed to get the result-id for
  1392. // the array length.
  1393. const auto length = getOrCreateConstantInt(
  1394. llvm::APInt(32, arrayType->getElementCount()), context.getUIntType(32),
  1395. /* isSpecConst */ false);
  1396. // Emit the OpTypeArray instruction
  1397. const uint32_t elemTypeId = emitType(arrayType->getElementType());
  1398. initTypeInstruction(spv::Op::OpTypeArray);
  1399. curTypeInst.push_back(id);
  1400. curTypeInst.push_back(elemTypeId);
  1401. curTypeInst.push_back(length);
  1402. finalizeTypeInstruction();
  1403. auto stride = arrayType->getStride();
  1404. if (stride.hasValue())
  1405. emitDecoration(id, spv::Decoration::ArrayStride, {stride.getValue()});
  1406. }
  1407. // RuntimeArray types
  1408. else if (const auto *raType = dyn_cast<RuntimeArrayType>(type)) {
  1409. const uint32_t elemTypeId = emitType(raType->getElementType());
  1410. initTypeInstruction(spv::Op::OpTypeRuntimeArray);
  1411. curTypeInst.push_back(id);
  1412. curTypeInst.push_back(elemTypeId);
  1413. finalizeTypeInstruction();
  1414. auto stride = raType->getStride();
  1415. if (stride.hasValue())
  1416. emitDecoration(id, spv::Decoration::ArrayStride, {stride.getValue()});
  1417. }
  1418. // Structure types
  1419. else if (const auto *structType = dyn_cast<StructType>(type)) {
  1420. llvm::ArrayRef<StructType::FieldInfo> fields = structType->getFields();
  1421. size_t numFields = fields.size();
  1422. // Emit OpMemberName for the struct members.
  1423. for (size_t i = 0; i < numFields; ++i)
  1424. emitNameForType(fields[i].name, id, i);
  1425. llvm::SmallVector<uint32_t, 4> fieldTypeIds;
  1426. for (auto &field : fields) {
  1427. fieldTypeIds.push_back(emitType(field.type));
  1428. }
  1429. for (size_t i = 0; i < numFields; ++i) {
  1430. auto &field = fields[i];
  1431. // Offset decorations
  1432. if (field.offset.hasValue())
  1433. emitDecoration(id, spv::Decoration::Offset, {field.offset.getValue()},
  1434. i);
  1435. // MatrixStride decorations
  1436. if (field.matrixStride.hasValue())
  1437. emitDecoration(id, spv::Decoration::MatrixStride,
  1438. {field.matrixStride.getValue()}, i);
  1439. // RowMajor/ColMajor decorations
  1440. if (field.isRowMajor.hasValue())
  1441. emitDecoration(id,
  1442. field.isRowMajor.getValue() ? spv::Decoration::RowMajor
  1443. : spv::Decoration::ColMajor,
  1444. {}, i);
  1445. // RelaxedPrecision decorations
  1446. if (field.isRelaxedPrecision)
  1447. emitDecoration(id, spv::Decoration::RelaxedPrecision, {}, i);
  1448. // NonWritable decorations
  1449. if (structType->isReadOnly())
  1450. emitDecoration(id, spv::Decoration::NonWritable, {}, i);
  1451. }
  1452. // Emit Block or BufferBlock decorations if necessary.
  1453. auto interfaceType = structType->getInterfaceType();
  1454. if (interfaceType == StructInterfaceType::StorageBuffer)
  1455. emitDecoration(id,
  1456. isBufferBlockDecorationDeprecated(spvOptions)
  1457. ? spv::Decoration::Block
  1458. : spv::Decoration::BufferBlock,
  1459. {});
  1460. else if (interfaceType == StructInterfaceType::UniformBuffer)
  1461. emitDecoration(id, spv::Decoration::Block, {});
  1462. initTypeInstruction(spv::Op::OpTypeStruct);
  1463. curTypeInst.push_back(id);
  1464. for (auto fieldTypeId : fieldTypeIds)
  1465. curTypeInst.push_back(fieldTypeId);
  1466. finalizeTypeInstruction();
  1467. }
  1468. // Pointer types
  1469. else if (const auto *ptrType = dyn_cast<SpirvPointerType>(type)) {
  1470. const uint32_t pointeeType = emitType(ptrType->getPointeeType());
  1471. initTypeInstruction(spv::Op::OpTypePointer);
  1472. curTypeInst.push_back(id);
  1473. curTypeInst.push_back(static_cast<uint32_t>(ptrType->getStorageClass()));
  1474. curTypeInst.push_back(pointeeType);
  1475. finalizeTypeInstruction();
  1476. }
  1477. // Function types
  1478. else if (const auto *fnType = dyn_cast<FunctionType>(type)) {
  1479. const uint32_t retTypeId = emitType(fnType->getReturnType());
  1480. llvm::SmallVector<uint32_t, 4> paramTypeIds;
  1481. for (auto *paramType : fnType->getParamTypes())
  1482. paramTypeIds.push_back(emitType(paramType));
  1483. initTypeInstruction(spv::Op::OpTypeFunction);
  1484. curTypeInst.push_back(id);
  1485. curTypeInst.push_back(retTypeId);
  1486. for (auto paramTypeId : paramTypeIds)
  1487. curTypeInst.push_back(paramTypeId);
  1488. finalizeTypeInstruction();
  1489. }
  1490. // Acceleration Structure NV type
  1491. else if (const auto *accType = dyn_cast<AccelerationStructureTypeNV>(type)) {
  1492. initTypeInstruction(spv::Op::OpTypeAccelerationStructureNV);
  1493. curTypeInst.push_back(id);
  1494. finalizeTypeInstruction();
  1495. }
  1496. // RayQueryProvisionalType KHR type
  1497. else if (const auto *rayQueryType =
  1498. dyn_cast<RayQueryProvisionalTypeKHR>(type)) {
  1499. initTypeInstruction(spv::Op::OpTypeRayQueryProvisionalKHR);
  1500. curTypeInst.push_back(id);
  1501. finalizeTypeInstruction();
  1502. }
  1503. // Hybrid Types
  1504. // Note: The type lowering pass should lower all types to SpirvTypes.
  1505. // Therefore, if we find a hybrid type when going through the emitting pass,
  1506. // that is clearly a bug.
  1507. else if (const auto *hybridType = dyn_cast<HybridType>(type)) {
  1508. llvm_unreachable("found hybrid type when emitting SPIR-V");
  1509. }
  1510. // Unhandled types
  1511. else {
  1512. llvm_unreachable("unhandled type in emitType");
  1513. }
  1514. return id;
  1515. }
  1516. void EmitTypeHandler::emitDecoration(uint32_t typeResultId,
  1517. spv::Decoration decoration,
  1518. llvm::ArrayRef<uint32_t> decorationParams,
  1519. llvm::Optional<uint32_t> memberIndex) {
  1520. spv::Op op =
  1521. memberIndex.hasValue() ? spv::Op::OpMemberDecorate : spv::Op::OpDecorate;
  1522. if (decoration == spv::Decoration::UserTypeGOOGLE) {
  1523. op = memberIndex.hasValue() ? spv::Op::OpMemberDecorateString
  1524. : spv::Op::OpDecorateString;
  1525. }
  1526. assert(curDecorationInst.empty());
  1527. curDecorationInst.push_back(static_cast<uint32_t>(op));
  1528. curDecorationInst.push_back(typeResultId);
  1529. if (memberIndex.hasValue())
  1530. curDecorationInst.push_back(memberIndex.getValue());
  1531. curDecorationInst.push_back(static_cast<uint32_t>(decoration));
  1532. for (auto param : decorationParams)
  1533. curDecorationInst.push_back(param);
  1534. curDecorationInst[0] |= static_cast<uint32_t>(curDecorationInst.size()) << 16;
  1535. // Add to the full annotations list
  1536. annotationsBinary->insert(annotationsBinary->end(), curDecorationInst.begin(),
  1537. curDecorationInst.end());
  1538. curDecorationInst.clear();
  1539. }
  1540. void EmitTypeHandler::emitNameForType(llvm::StringRef name,
  1541. uint32_t targetTypeId,
  1542. llvm::Optional<uint32_t> memberIndex) {
  1543. if (name.empty())
  1544. return;
  1545. std::vector<uint32_t> nameInstr;
  1546. auto op = memberIndex.hasValue() ? spv::Op::OpMemberName : spv::Op::OpName;
  1547. nameInstr.push_back(static_cast<uint32_t>(op));
  1548. nameInstr.push_back(targetTypeId);
  1549. if (memberIndex.hasValue())
  1550. nameInstr.push_back(memberIndex.getValue());
  1551. const auto &words = string::encodeSPIRVString(name);
  1552. nameInstr.insert(nameInstr.end(), words.begin(), words.end());
  1553. nameInstr[0] |= static_cast<uint32_t>(nameInstr.size()) << 16;
  1554. debugVariableBinary->insert(debugVariableBinary->end(), nameInstr.begin(),
  1555. nameInstr.end());
  1556. }
  1557. } // end namespace spirv
  1558. } // end namespace clang