summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang-record-replay/record/slang-module.cpp8
-rw-r--r--source/slang-record-replay/record/slang-module.h2
-rw-r--r--source/slang/slang-compiler.h12
-rw-r--r--source/slang/slang-ir.cpp19
-rw-r--r--source/slang/slang-ir.h6
-rw-r--r--source/slang/slang-options.cpp85
6 files changed, 125 insertions, 7 deletions
diff --git a/source/slang-record-replay/record/slang-module.cpp b/source/slang-record-replay/record/slang-module.cpp
index 2071a8491..628a29c90 100644
--- a/source/slang-record-replay/record/slang-module.cpp
+++ b/source/slang-record-replay/record/slang-module.cpp
@@ -244,4 +244,12 @@ IEntryPointRecorder* ModuleRecorder::getEntryPointRecorder(slang::IEntryPoint* e
return result.detach();
}
}
+
+SlangResult ModuleRecorder::disassemble(ISlangBlob** outBlob)
+{
+ // No need to record this call as it is just a query.
+ slangRecordLog(LogLevel::Verbose, "%s\n", __PRETTY_FUNCTION__);
+ auto res = m_actualModule->disassemble(outBlob);
+ return res;
+}
} // namespace SlangRecord
diff --git a/source/slang-record-replay/record/slang-module.h b/source/slang-record-replay/record/slang-module.h
index 7608ac52d..d9c83576d 100644
--- a/source/slang-record-replay/record/slang-module.h
+++ b/source/slang-record-replay/record/slang-module.h
@@ -56,6 +56,8 @@ public:
ISlangBlob** outDiagnostics) override;
virtual SLANG_NO_THROW SlangInt32 SLANG_MCALL getDependencyFileCount() override;
virtual SLANG_NO_THROW char const* SLANG_MCALL getDependencyFilePath(SlangInt32 index) override;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL
+ disassemble(slang::IBlob** outDisassembly) override;
// Interfaces for `IComponentType`
virtual SLANG_NO_THROW slang::ISession* SLANG_MCALL getSession() override
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index cfcbe816f..d4e05bc48 100644
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1832,6 +1832,18 @@ private:
// Source files that have been pulled into the module with `__include`.
Dictionary<SourceFile*, FileDecl*> m_mapSourceFileToFileDecl;
+
+public:
+ SLANG_NO_THROW SlangResult SLANG_MCALL disassemble(slang::IBlob** outDisassembledBlob) override
+ {
+ if (!outDisassembledBlob)
+ return SLANG_E_INVALID_ARG;
+ String disassembly;
+ this->getIRModule()->getModuleInst()->dump(disassembly);
+ auto blob = StringUtil::createStringBlob(disassembly);
+ *outDisassembledBlob = blob.detach();
+ return SLANG_OK;
+ }
};
typedef Module LoadedModule;
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 92e51fe3b..6d1d76afc 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -8950,24 +8950,33 @@ void IRInst::addBlock(IRBlock* block)
block->insertAtEnd(this);
}
-void IRInst::dump()
+void IRInst::dump(String& outStr)
{
+ StringBuilder sb;
+
if (auto intLit = as<IRIntLit>(this))
{
- std::cout << intLit->getValue() << std::endl;
+ sb << intLit->getValue();
}
else if (auto stringLit = as<IRStringLit>(this))
{
- std::cout << stringLit->getStringSlice().begin() << std::endl;
+ sb << stringLit->getStringSlice();
}
else
{
- StringBuilder sb;
IRDumpOptions options;
StringWriter writer(&sb, Slang::WriterFlag::AutoFlush);
dumpIR(this, options, nullptr, &writer);
- std::cout << sb.toString().begin() << std::endl;
}
+
+ outStr = sb.toString();
+}
+
+void IRInst::dump()
+{
+ String s;
+ dump(s);
+ std::cout << s.begin() << std::endl;
}
} // namespace Slang
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index aa74c0704..64125be9a 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -813,10 +813,14 @@ struct IRInst
///
void _insertAt(IRInst* inPrev, IRInst* inNext, IRInst* inParent);
- /// Print the IR to stdout for debugging purposes
+ /// Print the IR to stdout for debugging purposes.
///
void dump();
+ /// Print the IR to a string for debugging purposes.
+ ///
+ void dump(String& outStr);
+
/// Insert a basic block at the end of this func/code containing inst.
void addBlock(IRBlock* block);
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