EmitVisitor.cpp 82 KB

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