diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-08-16 16:12:45 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-16 13:12:45 -0700 |
| commit | 42de00db3ffe07599fff6d47d0d7228181ee3082 (patch) | |
| tree | 84367b359cd2701212214379d4d604488c4fac91 /source/slang/slang-compiler.cpp | |
| parent | ac71724c03392b429e44641a3641b2bcf7cc55fc (diff) | |
Move metadata/diagnostics to associated types (#2358)
* #include an absolute path didn't work - because paths were taken to always be relative.
* WIP with hierarchical enums.
* Some small fixes and improvements around artifact desc related types.
* Improvements around hierarchical enum.
* Fixes to get Artifact types refactor to be able to execute tests.
* Attempt to better categorize PTX.
* Work around for potentially unused function warning.
* Typo fix.
* Simplify Artifact header.
* Small improvements around Artifact kind/payload/style.
* Added IDestroyable/ICastable
* Add IArtifactList.
* First impl of IArtifactUtil.
* Use the ICastable interface for IArtifactRepresentation.
* Added IArtifactRepresentation & IArtifactAssociated.
* Add SLANG_OVERRIDE to avoid gcc/clang warning.
* Fix calling convention issue on win32.
* Fix missing SLANG_OVERRIDE.
* First attempt at file abstraction around Artifact.
* Added creation of lock file.
* Move functionality for determining file paths to the IArtifactUtil.
Add casting to ICastable.
* Added some casting/finding mechanisms.
* Simplify IArtifact interface, and use Items for file reps.
* Fix problem with libraries on DXIL.
* Split out ArtifactRepresentation.
* Move ArtifactDesc functionality to ArtifactDescUtil. ArtifactInfoUtil becomes ArtifactDescUtil.
* Split implementations from the interfaces for Artifact.
* Use TypeTextUtil for target name outputting.
* Add artifact impls.
* Add ICastableList
* Added UnknownCastableAdapter
* Make ISlangSharedLibrary derive from ICastable, and remain backwards compatible with slang-llvm.
* Refactor Representation on Artifact.
* Make our ISlangBlobs also derive from ICastable.
Make ISlangBlob atomic ref counted.
* Split out CastableList and related types, and placed in core.
* Small fixes around IArtifact.
Improve IArtifact docs.
First impl of getChildren for IArtifact.
* Documentation improvements for Artifact related types.
* Fix typo.
* Special case adding a ICastableList to a LazyCastableList.
* Small simplification of LazyCastableList, by adding State member.
* Removed the ILockFile interface because IFileArtifactRepresentation can be used.
* Implement DiagnosticsArtifactRepresentation.
* Added PostEmitMetadataArtifactRepresentation
* Add searching by predicate.
Added handling of accessing Artifact as ISharedLibrary
* Fix typo.
* Add find to IArtifacgtList.
Fix some missing SLANG_NO_THROW.
* Small improvements around ArtifactDesc types.
* Another small change around ArtifactKind.
* Some more shuffling of ArtifactDesc.
* Make IArtifact castable
Remove IArtifactList
Made IArtifactContainer derive from IArtifact
Made ModuleLibrary atomic ref counted/given IModuleLibrary interface.
* Must call _requireChildren before any children access.
* Fix missing SLANG_MCALL on castAs.
* Fix missing SLANG_OVERRIDE.
* Added IArtifactHandler
* Use ICastable for basis of scope/lookup.
* WIP first attempt to remove CompileResult.
* Fix support for for downstream compiler shared library adapter.
* Fix issues found when replacing CompileResult.
* Fix typo.
* Fix getting items form 'significant' member of an Artifact.
* Split out ArtifactUtil & ArtifactHandler.
* Work around for problem on Visual studio.
* Improve searching.
* Add missing files.
* Split out Artifact associated types.
Don't produce a container by default - use associated for 'metadata'.
* Remove no longer used ArtifactPayload type.
* Generalized converting representations.
Small improvements to artifacts.
* Fix intermediate dumping issue.
* Removed #if 0 out CompileResult.
Remove DownstreamCompileResult maybeDumpIntermediate.
* Pull out functionality for dumping artifact output into ArtifactOutputUtil
Fixed a bug in naming files based on ArtifactDesc.
* std::atomic issue.
* Fix outputting as text bug.
Some small improvements.
* Add fix around prefix for dumping.
Improved how handling for extensions work form ArtifactDesc.
* Dump assembly if available.
Diffstat (limited to 'source/slang/slang-compiler.cpp')
| -rw-r--r-- | source/slang/slang-compiler.cpp | 594 |
1 files changed, 71 insertions, 523 deletions
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index e49b67af2..02d312b61 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -19,6 +19,10 @@ #include "../compiler-core/slang-artifact-representation-impl.h" #include "../compiler-core/slang-artifact-impl.h" #include "../compiler-core/slang-artifact-util.h" +#include "../compiler-core/slang-artifact-associated.h" + +// Artifact output +#include "slang-artifact-output-util.h" #include "slang-lower-to-ir.h" #include "slang-mangle.h" @@ -31,33 +35,10 @@ #include "slang-emit-cuda.h" #include "slang-serialize-container.h" -// - -// Includes to allow us to control console -// output when writing assembly dumps. -#include <fcntl.h> -#ifdef _WIN32 -#include <io.h> -#else -#include <unistd.h> -#endif - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include <Windows.h> -#undef WIN32_LEAN_AND_MEAN -#undef NOMINMAX -#endif - -#ifdef _MSC_VER -#pragma warning(disable: 4996) -#endif namespace Slang { - // !!!!!!!!!!!!!!!!!!!!!! free functions for DiagnosicSink !!!!!!!!!!!!!!!!!!!!!!!!!!!!! bool isHeterogeneousTarget(CodeGenTarget target) @@ -77,77 +58,6 @@ namespace Slang sb << TypeTextUtil::getPassThroughName(SlangPassThrough(val)); } - // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CompileResult !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -#if 0 - SlangResult CompileResult::getSharedLibrary(ComPtr<ISlangSharedLibrary>& outSharedLibrary) - { - if (downstreamResult) - { - // TODO(JS): Work around for not knowing actual interface this is returning, - // and needing to support deps interface - - ComPtr<ISlangSharedLibrary> lib; - SLANG_RETURN_ON_FAIL(downstreamResult->getHostCallableSharedLibrary(lib)); - - if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary::getTypeGuid(), (void**)outSharedLibrary.writeRef()))) - { - return SLANG_OK; - } - - ComPtr<ISlangSharedLibrary_Dep1> libDep1; - if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary_Dep1::getTypeGuid(), (void**)libDep1.writeRef()))) - { - // Okay, we need to adapt for now - outSharedLibrary = new SharedLibraryDep1Adapter(libDep1); - return SLANG_OK; - } - } - return SLANG_FAIL; - } - - SlangResult CompileResult::getBlob(ComPtr<ISlangBlob>& outBlob) const - { - if(!blob) - { - switch(format) - { - default: - case ResultFormat::None: - { - // If no blob is returned, it's an error - return SLANG_FAIL; - } - case ResultFormat::Text: - { - blob = StringUtil::createStringBlob(outputString); - break; - } - case ResultFormat::Binary: - { - if (downstreamResult) - { - // TODO(JS): - // This seems a little questionable. As it stands downstreamResult, if it doesn't have a blob - // can try and read a file. How this currently works is that every getBlob will potentially try to read that file. - // Setting result to None would stop this, but is that reasonable as the state. - // Perhaps downstreamResult should hold some state that the read failed. - // For now we don't worry though. - - SLANG_RETURN_ON_FAIL(downstreamResult->getBinary(blob)); - } - break; - } - } - } - - outBlob = blob; - return SLANG_OK; - } - - -#endif - // // FrontEndEntryPointRequest // @@ -1072,7 +982,7 @@ namespace Slang } } - ComPtr<IArtifact> sourceContainerArtifact; + ComPtr<IArtifact> sourceArtifact; /* This is more convoluted than the other scenarios, because when we invoke C/C++ compiler we would ideally like to use the original file. We want to do this because we want includes relative to the source file to work, and @@ -1141,9 +1051,9 @@ namespace Slang CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker); - SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceContainerArtifact)); + SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceArtifact)); - sourceCodeGenContext.maybeDumpIntermediate(sourceContainerArtifact); + sourceCodeGenContext.maybeDumpIntermediate(sourceArtifact); } else { @@ -1161,25 +1071,17 @@ namespace Slang { CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker); - SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceContainerArtifact)); - sourceCodeGenContext.maybeDumpIntermediate(sourceContainerArtifact); + SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceArtifact)); + sourceCodeGenContext.maybeDumpIntermediate(sourceArtifact); sourceLanguage = (SourceLanguage)TypeConvertUtil::getSourceLanguageFromTarget((SlangCompileTarget)sourceTarget); } - ComPtr<IArtifact> metadata; - if (sourceContainerArtifact) + ComPtr<IPostEmitMetadata> metadata; + if (sourceArtifact) { - auto sourceArtifact = sourceContainerArtifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren, - ArtifactDesc::make(ArtifactKind::Source, ArtifactPayload::Base, ArtifactStyle::Base)); - if (!sourceArtifact) - { - return SLANG_FAIL; - } - - metadata = sourceContainerArtifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren, - ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::PostEmitMetadata, ArtifactStyle::Base)); - + metadata = findAssociated<IPostEmitMetadata>(sourceArtifact); + ComPtr<ISlangBlob> blob; SLANG_RETURN_ON_FAIL(sourceArtifact->loadBlob(ArtifactKeep::No, blob.writeRef())); @@ -1513,13 +1415,6 @@ namespace Slang return SLANG_FAIL; } - auto artifactContainer = ArtifactUtil::createResultsContainer(); - - if (metadata) - { - artifactContainer->addChild(metadata); - } - // Create the artifact that encapsulates the result auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target)); @@ -1527,54 +1422,16 @@ namespace Slang auto objRep = new ObjectArtifactRepresentation(DownstreamCompileResult::getTypeGuid(), downstreamCompileResult); artifact->addRepresentation(objRep); - // Set the artifact - outArtifact.swap(artifact); - return SLANG_OK; - } - - SlangResult CodeGenContext::dissassembleWithDownstream( - const void* data, - size_t dataSizeInBytes, - ISlangBlob** outBlob) - { - auto session = getSession(); - auto sink = getSink(); - auto target = getTargetFormat(); - - // Get the downstream compiler that can be used for this target - - // TODO(JS): - // This could perhaps be performed in some other manner if there was more than one way to produce - // disassembly from a binary. - auto downstreamCompiler = getDownstreamCompilerRequiredForTarget(target); - - // Get the required downstream compiler - DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(downstreamCompiler, sink); - - if (!compiler) + if (metadata) { - auto compilerName = TypeTextUtil::getPassThroughAsHumanText((SlangPassThrough)downstreamCompiler); - sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName); - return SLANG_FAIL; + artifact->addAssociated(metadata); } - ComPtr<ISlangBlob> dissassemblyBlob; - SLANG_RETURN_ON_FAIL(compiler->disassemble(SlangCompileTarget(target), data, dataSizeInBytes, dissassemblyBlob.writeRef())); - - *outBlob = dissassemblyBlob.detach(); + // Set the artifact + outArtifact.swap(artifact); return SLANG_OK; } - SlangResult CodeGenContext::dissassembleWithDownstream( - DownstreamCompileResult* downstreamResult, - ISlangBlob** outBlob) - { - - ComPtr<ISlangBlob> codeBlob; - SLANG_RETURN_ON_FAIL(downstreamResult->getBinary(codeBlob)); - return dissassembleWithDownstream(codeBlob->getBufferPointer(), codeBlob->getBufferSize(), outBlob); - } - SlangResult emitSPIRVForEntryPointsDirectly( CodeGenContext* codeGenContext, ComPtr<IArtifact>& outArtifact); @@ -1609,26 +1466,12 @@ namespace Slang SLANG_RETURN_ON_FAIL(intermediateContext._emitEntryPoints(intermediateArtifact)); intermediateContext.maybeDumpIntermediate(intermediateArtifact); - IArtifact* binaryArtifact = intermediateArtifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren, - ArtifactDesc::make(ArtifactKind::BinaryLike, ArtifactPayload::Base, ArtifactStyle::Base)); - if (!binaryArtifact) - { - return SLANG_FAIL; - } - - ComPtr<ISlangBlob> binaryBlob; - SLANG_RETURN_ON_FAIL(binaryArtifact->loadBlob(ArtifactKeep::No, binaryBlob.writeRef())); - // Then disassemble the intermediate binary result to get the desired output - // Output the disassembly - ComPtr<ISlangBlob> disassemblyBlob; - SLANG_RETURN_ON_FAIL(intermediateContext.dissassembleWithDownstream(binaryBlob->getBufferPointer(), binaryBlob->getBufferSize(), disassemblyBlob.writeRef())); - - auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target)); - artifact->addRepresentationUnknown(disassemblyBlob); - - outArtifact.swap(artifact); + // Output the disassemble + ComPtr<IArtifact> disassemblyArtifact; + SLANG_RETURN_ON_FAIL(ArtifactOutputUtil::dissassembleWithDownstream(getSession(), intermediateArtifact, getSink(), disassemblyArtifact.writeRef())); + outArtifact.swap(disassemblyArtifact); return SLANG_OK; } case CodeGenTarget::SPIRV: @@ -1714,168 +1557,16 @@ namespace Slang } } - enum class OutputFileKind - { - Text, - Binary, - }; - - static void writeOutputFile( - CodeGenContext* context, - FILE* file, - String const& path, - void const* data, - size_t size) - { - size_t count = fwrite(data, size, 1, file); - if (count != 1) - { - context->getSink()->diagnose( - SourceLoc(), - Diagnostics::cannotWriteOutputFile, - path); - } - } - - static void writeOutputFile( - CodeGenContext* context, - ISlangWriter* writer, - String const& path, - void const* data, - size_t size) + void EndToEndCompileRequest::writeArtifactToStandardOutput(IArtifact* artifact, DiagnosticSink* sink) { - - if (SLANG_FAILED(writer->write((const char*)data, size))) - { - context->getSink()->diagnose( - SourceLoc(), - Diagnostics::cannotWriteOutputFile, - path); - } - } - - static void writeOutputFile( - CodeGenContext* context, - String const& path, - void const* data, - size_t size, - OutputFileKind kind) - { - FILE* file = fopen( - path.getBuffer(), - kind == OutputFileKind::Binary ? "wb" : "w"); - if (!file) - { - context->getSink()->diagnose( - SourceLoc(), - Diagnostics::cannotWriteOutputFile, - path); - return; - } - - writeOutputFile(context, file, path, data, size); - fclose(file); - } - - static void writeCompileResultToFile( - CodeGenContext* context, - String const& outputPath, - IArtifact* inArtifact) - { - // The artifact can contain multiple things, we want to find something like 'source' or binary like - IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact); - if (!artifact) - { - return; - } - - ComPtr<ISlangBlob> blob; - if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()))) - { - // Unable to get blob - return; - } - - const auto outputKind = ArtifactDescUtil::isText(artifact->getDesc()) ? - OutputFileKind::Text : - OutputFileKind::Binary; - - writeOutputFile(context, - outputPath, - (const char*)blob->getBufferPointer(), - blob->getBufferSize(), - outputKind); - } - - static void writeOutputToConsole( - ISlangWriter* writer, - String const& text) - { - writer->write(text.getBuffer(), text.getLength()); - } - - static void writeCompileResultToStandardOutput( - CodeGenContext* codeGenContext, - EndToEndCompileRequest* endToEndReq, - IArtifact* inArtifact) - { - ISlangWriter* writer = endToEndReq->getWriter(WriterChannel::StdOutput); - - // The artifact can contain multiple things, we want to find something like 'source' or binary like - IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact); - if (!artifact) + // If it's host callable it's not available to write to output + if (isDerivedFrom(artifact->getDesc().kind, ArtifactKind::HostCallable)) { return; } - ComPtr<ISlangBlob> blob; - if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()))) - { - // Unable to get blob - return; - } - - // If is text, we can just output - if (ArtifactDescUtil::isText(artifact->getDesc())) - { - writer->write((const char*)blob->getBufferPointer(), blob->getBufferSize()); - return; - } - - if (writer->isConsole()) - { - switch (artifact->getDesc().payload) - { - case ArtifactPayload::SPIRV: - case ArtifactPayload::DXIL: - case ArtifactPayload::DXBC: - { - ComPtr<ISlangBlob> disassemblyBlob; - - if (SLANG_SUCCEEDED(codeGenContext->dissassembleWithDownstream(blob->getBufferPointer(), blob->getBufferSize(), disassemblyBlob.writeRef()))) - { - const UnownedStringSlice disassembly = StringUtil::getSlice(disassemblyBlob); - writeOutputToConsole(writer, disassembly); - } - return; - } - } - - // Else just dump as text - HexDumpUtil::dumpWithMarkers((const uint8_t*)blob->getBufferPointer(), blob->getBufferSize(), 24, writer); - } - else - { - // Redirecting stdout to a file, so do the usual thing - writer->setMode(SLANG_WRITER_MODE_BINARY); - - writeOutputFile( - codeGenContext, - writer, - "stdout", - blob->getBufferPointer(), - blob->getBufferSize()); - } + auto session = getSession(); + ArtifactOutputUtil::maybeConvertAndWrite(session, artifact, sink, toSlice("stdout"), getWriter(WriterChannel::StdOutput)); } void EndToEndCompileRequest::writeWholeProgramResult( @@ -1907,12 +1598,11 @@ namespace Slang String outputPath = targetInfo->wholeTargetOutputPath; if (outputPath != "") { - writeCompileResultToFile(&codeGenContext, outputPath, artifact); + ArtifactOutputUtil::writeToFile(artifact, codeGenContext.getSink(), outputPath); return; } } - - writeCompileResultToStandardOutput(&codeGenContext, this, artifact); + writeArtifactToStandardOutput(artifact, codeGenContext.getSink()); } void EndToEndCompileRequest::writeEntryPointResult( @@ -1946,12 +1636,12 @@ namespace Slang String outputPath; if(targetInfo->entryPointOutputPaths.TryGetValue(entryPointIndex, outputPath)) { - writeCompileResultToFile(&codeGenContext, outputPath, artifact); + ArtifactOutputUtil::writeToFile(artifact, codeGenContext.getSink(), outputPath); return; } } - writeCompileResultToStandardOutput(&codeGenContext, this, artifact); + writeArtifactToStandardOutput(artifact, codeGenContext.getSink()); } IArtifact* TargetProgram::_createWholeProgramResult( @@ -2336,219 +2026,77 @@ namespace Slang // Debug logic for dumping intermediate outputs - // - - void CodeGenContext::dumpIntermediate( - void const* data, - size_t size, - char const* ext, - bool isBinary) - { - // Try to generate a unique ID for the file to dump, - // even in cases where there might be multiple threads - // doing compilation. - // - // This is primarily a debugging aid, so we don't - // really need/want to do anything too elaborate - - static uint32_t counter = 0; -#ifdef _WIN32 - uint32_t id = InterlockedIncrement(&counter); -#else - // TODO: actually implement the case for other platforms - uint32_t id = counter++; -#endif - - String path; - path.append(getIntermediateDumpPrefix()); - path.append(id); - path.append(ext); - - FILE* file = fopen(path.getBuffer(), isBinary ? "wb" : "w"); - if (!file) return; - - fwrite(data, size, 1, file); - fclose(file); - } - - void CodeGenContext::dumpIntermediateText( - void const* data, - size_t size, - char const* ext) - { - dumpIntermediate(data, size, ext, false); - } - - void CodeGenContext::dumpIntermediateBinary( - void const* data, - size_t size, - char const* ext) - { - dumpIntermediate(data, size, ext, true); - } - - void CodeGenContext::maybeDumpIntermediate( - DownstreamCompileResult* compileResult) + + void CodeGenContext::_dumpIntermediateMaybeWithAssembly(IArtifact* artifact) { - if (!shouldDumpIntermediates()) - return; + _dumpIntermediate(artifact); - ComPtr<ISlangBlob> blob; - if (SLANG_SUCCEEDED(compileResult->getBinary(blob))) - { - maybeDumpIntermediate(blob->getBufferPointer(), blob->getBufferSize()); - } - } + ComPtr<IArtifact> assembly; + ArtifactOutputUtil::maybeDisassemble(getSession(), artifact, nullptr, assembly); - static const char* _getTargetExtension(CodeGenTarget target) - { - switch (target) + if (assembly) { - case CodeGenTarget::HLSL: return ".hlsl"; - case CodeGenTarget::GLSL: return ".glsl"; - case CodeGenTarget::SPIRV: return ".spv"; - case CodeGenTarget::DXBytecode: return ".dxbc"; - case CodeGenTarget::DXIL: return ".dxil"; - case CodeGenTarget::SPIRVAssembly: return ".spv.asm"; - case CodeGenTarget::DXBytecodeAssembly: return ".dxbc.asm"; - case CodeGenTarget::DXILAssembly: return ".dxil.asm"; - case CodeGenTarget::CSource: return ".c"; - case CodeGenTarget::CUDASource: return ".cu"; - case CodeGenTarget::CPPSource: return ".cpp"; - case CodeGenTarget::HostCPPSource: return ".cpp"; - - // What these should be called is target specific, but just use these exts to make clear for now - // for now - case CodeGenTarget::HostExecutable: - { - return ".exe"; - } - case CodeGenTarget::HostHostCallable: - case CodeGenTarget::ShaderHostCallable: - case CodeGenTarget::ShaderSharedLibrary: - { - return ".shared-lib"; - } - default: break; + _dumpIntermediate(assembly); } - return nullptr; } - void CodeGenContext::maybeDumpIntermediate(IArtifact* inArtifact) + void CodeGenContext::_dumpIntermediate(IArtifact* artifact) { - if (!shouldDumpIntermediates()) - return; - - IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact); - if (!artifact) - { - return; - } - ComPtr<ISlangBlob> blob; if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()))) { return; } + _dumpIntermediate(artifact->getDesc(), blob->getBufferPointer(), blob->getBufferSize()); + } - const auto desc = artifact->getDesc(); - String ext = ArtifactDescUtil::getDefaultExtension(desc); + void CodeGenContext::_dumpIntermediate( + const ArtifactDesc& desc, + void const* data, + size_t size) + { + // Try to generate a unique ID for the file to dump, + // even in cases where there might be multiple threads + // doing compilation. + // + // This is primarily a debugging aid, so we don't + // really need/want to do anything too elaborate + static std::atomic<uint32_t> counter(0); - if (ArtifactDescUtil::isText(artifact->getDesc())) - { - dumpIntermediateText(blob->getBufferPointer(), blob->getBufferSize(), ext.getBuffer()); - } - else - { - switch (artifact->getDesc().payload) - { - case ArtifactPayload::SPIRV: - case ArtifactPayload::DXIL: - case ArtifactPayload::DXBC: - { - ComPtr<ISlangBlob> disassemblyBlob; + const uint32_t id = ++counter; - if (SLANG_SUCCEEDED(dissassembleWithDownstream(blob->getBufferPointer(), blob->getBufferSize(), disassemblyBlob.writeRef()))) - { - ArtifactDesc assemblyDesc(desc); - assemblyDesc.kind = ArtifactKind::Assembly; + // Just use the counter for the 'base name' + StringBuilder basename; - ext = ArtifactDescUtil::getDefaultExtension(assemblyDesc); + // Add the prefix + basename << getIntermediateDumpPrefix(); - dumpIntermediateText(disassemblyBlob->getBufferPointer(), disassemblyBlob->getBufferSize(), ext.getBuffer()); - return; - } - } - default: break; - } + // Add the id + basename << int(id); - dumpIntermediateBinary(blob->getBufferPointer(), blob->getBufferSize(), ext.getBuffer()); - } - } + // Work out the filename based on the desc and the basename + StringBuilder filename; + ArtifactDescUtil::calcNameForDesc(desc, basename.getUnownedSlice(), filename); - void CodeGenContext::maybeDumpIntermediate( - void const* data, - size_t size) - { - if (!shouldDumpIntermediates()) - return; - - auto target = getTargetFormat(); - const auto desc = ArtifactDescUtil::makeDescFromCompileTarget(asExternal(target)); - - if (desc.kind == ArtifactKind::Text) + // If didn't produce a filename, use basename with .unknown extension + if (filename.getLength() == 0) { - dumpIntermediateText(data, size, _getTargetExtension(target)); - return; + filename = basename; + filename << ".unknown"; } - switch (target) - { -#if 0 - case CodeGenTarget::SlangIRAssembly: - { - dumpIntermediateText(compileRequest, data, size, ".slang-ir.asm"); - break; - } -#endif - case CodeGenTarget::DXIL: - case CodeGenTarget::DXBytecode: - case CodeGenTarget::SPIRV: - { - const char* ext = _getTargetExtension(target); - SLANG_ASSERT(ext); - - dumpIntermediateBinary(data, size, ext); - ComPtr<ISlangBlob> disassemblyBlob; - if (SLANG_SUCCEEDED(dissassembleWithDownstream(data, size, disassemblyBlob.writeRef()))) - { - StringBuilder buf; - buf << ext << ".asm"; - dumpIntermediateText(disassemblyBlob->getBufferPointer(), disassemblyBlob->getBufferSize(), buf.getBuffer()); - } - break; - } - - case CodeGenTarget::HostHostCallable: - case CodeGenTarget::ShaderHostCallable: - case CodeGenTarget::ShaderSharedLibrary: - case CodeGenTarget::HostExecutable: - { - dumpIntermediateBinary(data, size, _getTargetExtension(target)); - break; - } - default: break; - } + // Write to a file + ArtifactOutputUtil::writeToFile(desc, data, size, filename); } - void CodeGenContext::maybeDumpIntermediate( - char const* text) + void CodeGenContext::maybeDumpIntermediate(IArtifact* artifact) { if (!shouldDumpIntermediates()) return; - maybeDumpIntermediate(text, strlen(text)); + + _dumpIntermediateMaybeWithAssembly(artifact); } IRDumpOptions CodeGenContext::getIRDumpOptions() |
