diff options
| author | cheneym2 <acheney@nvidia.com> | 2025-03-20 11:38:46 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-20 23:38:46 +0800 |
| commit | de6cc94e3b7fa5d1b8eeb53993dbf3ca2cec1cc1 (patch) | |
| tree | 0913d39d83c4beff06a854b6503bd05d395077b4 /source/slang/slang-options.cpp | |
| parent | 96de7f6a9dccabd1801dcbf1eb76e0967d7f5fe8 (diff) | |
Add -dump-module command to slangc (#6638)
* Add -dump-module command to slangc
The new -dump-module command to slangc will load and disassemble a slang module, similar to what would be seen by the -dump-ir command, except that -dump-ir tells slangc to print IR as it performs some compilation command. That is, -dump-ir requires
some larger compilation task.
-dump-module on the otherhand requires no additional goal and will simply load a module and print its IR to stdout independently from other compilation steps.
Its intended purpose is to inspect .slang-module files on disk.
It can also be used on .slang files which will be parsed and lowered
if slang does not find an associated ".slang-module" version of the
module on disk.
The compilation API is extended with a new IModule::disassemble()
method which retrieves the string representation of the dumped IR.
Closes #6599
* format code
* Use FileStream not FILE
* format code
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
Diffstat (limited to 'source/slang/slang-options.cpp')
| -rw-r--r-- | source/slang/slang-options.cpp | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 977cf322c..ed7775e84 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -802,7 +802,8 @@ void initCommandOptions(CommandOptions& options) {OptionKind::VerifyDebugSerialIr, "-verify-debug-serial-ir", nullptr, - "Verify IR in the front-end."}}; + "Verify IR in the front-end."}, + {OptionKind::DumpModule, "-dump-module", nullptr, "Disassemble and print the module IR."}}; _addOptions(makeConstArrayView(debuggingOpts), options); /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Experimental !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ @@ -2949,6 +2950,88 @@ SlangResult OptionsParser::_parse(int argc, char const* const* argv) linkage->m_optionSet.add(OptionKind::BindlessSpaceIndex, (int)index); break; } + case OptionKind::DumpModule: + { + CommandLineArg fileName; + SLANG_RETURN_ON_FAIL(m_reader.expectArg(fileName)); + auto desc = slang::SessionDesc(); + ComPtr<slang::ISession> session; + m_session->createSession(desc, session.writeRef()); + ComPtr<slang::IBlob> diagnostics; + + // Coerce Slang to load from the given file, without letting it automatically + // choose .slang-module files over .slang files. + // First try to load as source string, and fall back to loading as an IR Blob. + // Avoid guessing based on filename or inspecting the file contents. + FileStream file; + if (SLANG_FAILED(file.init( + fileName.value, + FileMode::Open, + FileAccess::Read, + FileShare::None))) + { + m_sink->diagnose(arg.loc, Diagnostics::cannotOpenFile, fileName.value); + return SLANG_FAIL; + } + + List<uint8_t> buffer; + file.seek(SeekOrigin::End, 0); + const Int64 size = file.getPosition(); + buffer.setCount(size + 1); + file.seek(SeekOrigin::Start, 0); + SLANG_RETURN_ON_FAIL(file.readExactly(buffer.getBuffer(), (size_t)size)); + buffer[size] = 0; + file.close(); + + ComPtr<slang::IModule> module; + module = session->loadModuleFromSourceString( + "module", + "path", + (const char*)buffer.getBuffer(), + diagnostics.writeRef()); + if (!module) + { + // Load buffer as an IR blob + ComPtr<slang::IBlob> blob; + blob = RawBlob::create(buffer.getBuffer(), size); + + module = session->loadModuleFromIRBlob( + "module", + "path", + blob, + diagnostics.writeRef()); + } + + if (module) + { + ComPtr<slang::IBlob> disassemblyBlob; + if (SLANG_FAILED(module->disassemble(disassemblyBlob.writeRef()))) + { + m_sink->diagnose(arg.loc, Diagnostics::cannotDisassemble, fileName.value); + return SLANG_FAIL; + } + else + { + // success, print out the disassembly in a way that slang-test can read + m_sink->diagnoseRaw( + Severity::Note, + (const char*)disassemblyBlob->getBufferPointer()); + } + } + else + { + if (diagnostics) + { + m_sink->diagnoseRaw( + Severity::Error, + (const char*)diagnostics->getBufferPointer()); + } + return SLANG_FAIL; + } + + + break; + } default: { // Hmmm, we looked up and produced a valid enum, but it wasn't handled in the |
