diff options
| author | Mukund Keshava <mkeshava@nvidia.com> | 2025-03-11 21:40:05 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-11 16:10:05 +0000 |
| commit | f59e0ef409844f2514435a8df8ceeff3663e5db3 (patch) | |
| tree | 7f8f7514ed140a49f03923d84a549fdbfdcbcc84 /source/slang/slang-ir.cpp | |
| parent | ff55a569a0bff44a6f8abb105c07cbc2484bc007 (diff) | |
IR: Add SPIR-V disassembly for embedded downstream IR dumps (#6529)
* IR: Add SPIR-V disassembly for embedded downstream IR dumps
When dumping IR that contains embedded downstream SPIR-V code (via
EmbeddedDownstreamIR instructions), display the disassembled SPIR-V
instead of just showing "<binary blob>".
This CL also does:
- Adds a new interface for disassembly and get result.
- Modify export-library-generics.slang test test to check for the
disassembled SPIR-V
Fixes #6513
* Add module-dual-target-verify test
Fixes #6517
Adds a new test to verify that dxil and spirv targets are stored
separately in the precompiled blob.
* Fix review comments from cheneym2
* format code
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-ir.cpp')
| -rw-r--r-- | source/slang/slang-ir.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 72313217b..92e51fe3b 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -7117,6 +7117,76 @@ void dumpIRGeneric(IRDumpContext* context, IRGeneric* witnessTable) dump(context, "}\n"); } +static void dumpEmbeddedDownstream(IRDumpContext* context, IRInst* inst) +{ + auto targetInst = inst->getOperand(0); + auto blobInst = inst->getOperand(1); + + // Get the target value + auto targetLit = as<IRIntLit>(targetInst); + if (!targetLit) + { + dump(context, "EmbeddedDownstreamIR(invalid target)"); + return; + } + + // Get the blob + auto blobLitInst = as<IRBlobLit>(blobInst); + if (!blobLitInst) + { + dump(context, "EmbeddedDownstreamIR(invalid blob)"); + return; + } + + dump(context, "EmbeddedDownstreamIR("); + dump(context, targetLit->getValue()); + dump(context, " : Int, "); + + // If target is SPIR-V (6), disassemble the blob + if (targetLit->getValue() == (IRIntegerValue)CodeGenTarget::SPIRV) + { + auto blob = blobLitInst->getStringSlice(); + const uint32_t* spirvCode = (const uint32_t*)blob.begin(); + const size_t spirvWordCount = blob.getLength() / sizeof(uint32_t); + + // Get the compiler from the session through the module + auto module = inst->getModule(); + auto session = module->getSession(); + IDownstreamCompiler* compiler = + session->getOrLoadDownstreamCompiler(PassThroughMode::SpirvDis, nullptr); + + if (compiler) + { + // Use glslang interface to disassemble with string output + String disassemblyOutput; + if (SLANG_SUCCEEDED(compiler->disassembleWithResult( + spirvCode, + int(spirvWordCount), + disassemblyOutput))) + { + // Dump the captured disassembly + dump(context, "\n"); + dumpIndent(context); + dump(context, disassemblyOutput); + } + else + { + dump(context, "<disassembly failed>"); + } + } + else + { + dump(context, "<unavailable disassembler>"); + } + } + else + { + // TODO: Add DXIL disassembly call here. + dump(context, "<binary blob>"); + } + dump(context, ")"); +} + static void dumpInstExpr(IRDumpContext* context, IRInst* inst) { if (!inst) @@ -7166,6 +7236,13 @@ static void dumpInstExpr(IRDumpContext* context, IRInst* inst) } } + // Special case EmbeddedDownstreamIR to show SPIR-V disassembly + if (op == kIROp_EmbeddedDownstreamIR) + { + dumpEmbeddedDownstream(context, inst); + return; + } + // Special case the SPIR-V asm operands as the distinction here is // clear anyway to the user switch (op) |
