EmitVisitor.cpp 84 KB

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