summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-compiler.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-16 16:12:45 -0400
committerGitHub <noreply@github.com>2022-08-16 13:12:45 -0700
commit42de00db3ffe07599fff6d47d0d7228181ee3082 (patch)
tree84367b359cd2701212214379d4d604488c4fac91 /source/slang/slang-compiler.cpp
parentac71724c03392b429e44641a3641b2bcf7cc55fc (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.cpp594
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()