summaryrefslogtreecommitdiffstats
path: root/source/slang
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
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')
-rw-r--r--source/slang/slang-artifact-output-util.cpp237
-rw-r--r--source/slang/slang-artifact-output-util.h46
-rw-r--r--source/slang/slang-compiler.cpp594
-rwxr-xr-xsource/slang/slang-compiler.h83
-rw-r--r--source/slang/slang-diagnostic-defs.h1
-rw-r--r--source/slang/slang-emit.cpp42
-rw-r--r--source/slang/slang-ir-link.h10
-rw-r--r--source/slang/slang-ir-metadata.cpp5
-rw-r--r--source/slang/slang-ir-metadata.h2
-rw-r--r--source/slang/slang-module-library.h2
-rw-r--r--source/slang/slang.cpp49
11 files changed, 404 insertions, 667 deletions
diff --git a/source/slang/slang-artifact-output-util.cpp b/source/slang/slang-artifact-output-util.cpp
new file mode 100644
index 000000000..2694fcb10
--- /dev/null
+++ b/source/slang/slang-artifact-output-util.cpp
@@ -0,0 +1,237 @@
+#include "slang-artifact-output-util.h"
+
+#include "../core/slang-platform.h"
+
+#include "../core/slang-io.h"
+#include "../core/slang-string-util.h"
+#include "../core/slang-hex-dump-util.h"
+
+#include "../core/slang-type-text-util.h"
+
+// Artifact
+#include "../compiler-core/slang-artifact-desc-util.h"
+#include "../compiler-core/slang-artifact-util.h"
+
+#include "slang-compiler.h"
+
+namespace Slang
+{
+
+// Given a desc returns a codegen target if it can be used for disassembly
+// Returns Unknown if cannot be used for generating disassembly
+//
+// NOTE! This returns the code gen target for the input binary, *not* the dissassembly output
+static CodeGenTarget _getDisassemblyCodeGenTarget(const ArtifactDesc& desc)
+{
+ switch (desc.payload)
+ {
+ case ArtifactPayload::DXIL: return CodeGenTarget::DXIL;
+ case ArtifactPayload::DXBC: return CodeGenTarget::DXBytecode;
+ case ArtifactPayload::SPIRV: return CodeGenTarget::SPIRV;
+ default: break;
+ }
+ return CodeGenTarget::Unknown;
+}
+
+/* static */SlangResult ArtifactOutputUtil::dissassembleWithDownstream(Session* session, IArtifact* artifact, DiagnosticSink* sink, IArtifact** outArtifact)
+{
+ auto desc = artifact->getDesc();
+
+ // 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.
+
+ const CodeGenTarget target = _getDisassemblyCodeGenTarget(desc);
+ if (target == CodeGenTarget::Unknown)
+ {
+ return SLANG_FAIL;
+ }
+
+ auto downstreamCompiler = getDownstreamCompilerRequiredForTarget(target);
+
+ // Get the required downstream compiler
+ DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(downstreamCompiler, sink);
+
+ if (!compiler)
+ {
+ if (sink)
+ {
+ auto compilerName = TypeTextUtil::getPassThroughAsHumanText((SlangPassThrough)downstreamCompiler);
+ sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName);
+ }
+ return SLANG_FAIL;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+
+ const auto data = blob->getBufferPointer();
+ const auto dataSizeInBytes = blob->getBufferSize();
+
+ ComPtr<ISlangBlob> dissassemblyBlob;
+ SLANG_RETURN_ON_FAIL(compiler->disassemble(SlangCompileTarget(target), data, dataSizeInBytes, dissassemblyBlob.writeRef()));
+
+ ArtifactDesc disassemblyDesc(desc);
+ disassemblyDesc.kind = ArtifactKind::Assembly;
+
+ auto disassemblyArtifact = ArtifactUtil::createArtifact(disassemblyDesc);
+ disassemblyArtifact->addRepresentationUnknown(dissassemblyBlob);
+
+ *outArtifact = disassemblyArtifact.detach();
+ return SLANG_OK;
+}
+
+SlangResult ArtifactOutputUtil::maybeDisassemble(Session* session, IArtifact* artifact, DiagnosticSink* sink, ComPtr<IArtifact>& outArtifact)
+{
+ const auto desc = artifact->getDesc();
+ if (ArtifactDescUtil::isText(artifact->getDesc()))
+ {
+ // Nothing to convert
+ return SLANG_OK;
+ }
+
+ if (_getDisassemblyCodeGenTarget(desc) != CodeGenTarget::Unknown)
+ {
+ // Get the blob
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+
+ ComPtr<IArtifact> disassemblyArtifact;
+
+ if (SLANG_SUCCEEDED(dissassembleWithDownstream(session, artifact, sink, disassemblyArtifact.writeRef())))
+ {
+ // Check it is now text
+ SLANG_ASSERT(ArtifactDescUtil::isText(disassemblyArtifact->getDesc()));
+
+ outArtifact.swap(disassemblyArtifact);
+ return SLANG_OK;
+ }
+ }
+
+ return SLANG_OK;
+}
+
+/* static */SlangResult ArtifactOutputUtil::write(const ArtifactDesc& desc, ISlangBlob* blob, ISlangWriter* writer)
+{
+ // If is text, we can just output
+ if (ArtifactDescUtil::isText(desc))
+ {
+ return writer->write((const char*)blob->getBufferPointer(), blob->getBufferSize());
+ }
+ else
+ {
+ if (writer->isConsole())
+ {
+ // Else just dump as text
+ return 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);
+ return writer->write((const char*)blob->getBufferPointer(), blob->getBufferSize());
+ }
+ }
+}
+
+/* static */SlangResult ArtifactOutputUtil::write(IArtifact* artifact, ISlangWriter* writer)
+{
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+ return write(artifact->getDesc(), blob, writer);
+}
+
+static SlangResult _requireBlob(IArtifact* artifact, DiagnosticSink* sink, ComPtr<ISlangBlob>& outBlob)
+{
+ const auto res = artifact->loadBlob(ArtifactKeep::No, outBlob.writeRef());
+ if (SLANG_FAILED(res))
+ {
+ sink->diagnose(SourceLoc(), Diagnostics::cannotAccessAsBlob);
+ return res;
+ }
+ return SLANG_OK;
+}
+
+/* static */SlangResult ArtifactOutputUtil::write(IArtifact* artifact, DiagnosticSink* sink, const UnownedStringSlice& writerName, ISlangWriter* writer)
+{
+ if (sink == nullptr)
+ {
+ return write(artifact, writer);
+ }
+
+ // Make sure we can access as a blob
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(_requireBlob(artifact, sink, blob));
+
+ const auto res = write(artifact->getDesc(), blob, writer);
+ if (SLANG_FAILED(res))
+ {
+ sink->diagnose(SourceLoc(), Diagnostics::cannotWriteOutputFile, writerName);
+ }
+ return res;
+}
+
+/* static */SlangResult ArtifactOutputUtil::maybeConvertAndWrite(Session* session, IArtifact* artifact, DiagnosticSink* sink, const UnownedStringSlice& writerName, ISlangWriter* writer)
+{
+ // If the output is console we will try and turn into disassembly
+ if (writer->isConsole())
+ {
+ ComPtr<IArtifact> disassemblyArtifact;
+ maybeDisassemble(session, artifact, sink, disassemblyArtifact);
+
+ if (disassemblyArtifact)
+ {
+ return write(disassemblyArtifact, sink, writerName, writer);
+ }
+ }
+
+ return write(artifact, sink, writerName, writer);
+}
+
+/* static */SlangResult ArtifactOutputUtil::writeToFile(const ArtifactDesc& desc, const void* data, size_t size, const String& path)
+{
+ if (ArtifactDescUtil::isText(desc))
+ {
+ return File::writeNativeText(path, data, size);
+ }
+ else
+ {
+ return File::writeAllBytes(path, data, size);
+ }
+}
+
+/* static */SlangResult ArtifactOutputUtil::writeToFile(const ArtifactDesc& desc, ISlangBlob* blob, const String& path)
+{
+ SLANG_RETURN_ON_FAIL(writeToFile(desc, blob->getBufferPointer(), blob->getBufferSize(), path));
+ return SLANG_OK;
+}
+
+/* static */SlangResult ArtifactOutputUtil::writeToFile(IArtifact* artifact, const String& path)
+{
+ // Get the blob
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+ return writeToFile(artifact->getDesc(), blob, path);
+}
+
+/* static */SlangResult ArtifactOutputUtil::writeToFile(IArtifact* artifact, DiagnosticSink* sink, const String& path)
+{
+ if (!sink)
+ {
+ return writeToFile(artifact, path);
+ }
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(_requireBlob(artifact, sink, blob));
+
+ const auto res = writeToFile(artifact, path);
+ if (SLANG_FAILED(res) && sink)
+ {
+ sink->diagnose(SourceLoc(), Diagnostics::cannotWriteOutputFile, path);
+ }
+
+ return res;
+}
+
+}
diff --git a/source/slang/slang-artifact-output-util.h b/source/slang/slang-artifact-output-util.h
new file mode 100644
index 000000000..948b3ce7a
--- /dev/null
+++ b/source/slang/slang-artifact-output-util.h
@@ -0,0 +1,46 @@
+#ifndef SLANG_ARTIFACT_OUTPUT_UTIL_H
+#define SLANG_ARTIFACT_OUTPUT_UTIL_H
+
+#include "../core/slang-basic.h"
+
+#include "../compiler-core/slang-artifact.h"
+#include "../compiler-core/slang-diagnostic-sink.h"
+
+#include "../../slang-com-ptr.h"
+
+namespace Slang
+{
+
+class Session;
+
+struct ArtifactOutputUtil
+{
+ /// Attempts to disassembly artifact into outArtifact.
+ /// Errors are output to sink if set. If not desired pass nullptr
+ static SlangResult dissassembleWithDownstream(Session* session, IArtifact* artifact, DiagnosticSink* sink, IArtifact** outArtifact);
+
+ /// Disassembles if that is plausible
+ /// Errors are output to sink if set. If not desired pass nullptr
+ static SlangResult maybeDisassemble(Session* session, IArtifact* artifact, DiagnosticSink* sink, ComPtr<IArtifact>& outArtifact);
+
+ /// Writes output to writer, will convert into disassembly if that is possible and appropriate (if outputting to console for example).
+ /// Errors are output to sink if set. If not desired pass nullptr
+ static SlangResult maybeConvertAndWrite(Session* session, IArtifact* artifact, DiagnosticSink* sink, const UnownedStringSlice& writerName, ISlangWriter* writer);
+
+ /// Write (without any diagnostics)
+ static SlangResult write(IArtifact* artifact, ISlangWriter* writer);
+ static SlangResult write(const ArtifactDesc& desc, ISlangBlob* blob, ISlangWriter* writer);
+
+ /// Writes the artifact with diagnostics
+ static SlangResult write(IArtifact* artifact, DiagnosticSink* sink, const UnownedStringSlice& writerName, ISlangWriter* writer);
+
+ /// Write to the specified path
+ static SlangResult writeToFile(const ArtifactDesc& desc, const void* data, size_t size, const String& path);
+ static SlangResult writeToFile(const ArtifactDesc& desc, ISlangBlob* blob, const String& path);
+ static SlangResult writeToFile(IArtifact* artifact, const String& path);
+ static SlangResult writeToFile(IArtifact* artifact, DiagnosticSink* sink, const String& path);
+};
+
+}
+
+#endif
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()
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 9f75d94d3..6b79b2679 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -144,47 +144,6 @@ namespace Slang
class Module;
class TranslationUnitRequest;
-#if 0
- // Result of compiling an entry point.
- // Should only ever be string, binary or shared library
- class CompileResult
- {
- public:
- CompileResult() = default;
- explicit CompileResult(String const& str, RefPtr<PostEmitMetadata> metadata)
- : format(ResultFormat::Text)
- , outputString(str)
- , postEmitMetadata(metadata) {}
-
- explicit CompileResult(ISlangBlob* inBlob)
- : format(ResultFormat::Binary)
- , blob(inBlob) {}
-
- explicit CompileResult(DownstreamCompileResult* inDownstreamResult, RefPtr<PostEmitMetadata> metadata)
- : format(ResultFormat::Binary)
- , downstreamResult(inDownstreamResult)
- , postEmitMetadata(metadata) {}
-
- explicit CompileResult(const UnownedStringSlice& slice )
- : format(ResultFormat::Text)
- , outputString(slice) {}
-
- SlangResult getBlob(ComPtr<ISlangBlob>& outBlob) const;
- SlangResult getSharedLibrary(ComPtr<ISlangSharedLibrary>& outSharedLibrary);
-
- SlangResult isParameterLocationUsed(SlangParameterCategory category, UInt spaceIndex, UInt registerIndex, bool& outUsed);
-
- ResultFormat format = ResultFormat::None;
- String outputString; ///< Only set if result type is ResultFormat::Text
-
- mutable ComPtr<ISlangBlob> blob;
-
- RefPtr<DownstreamCompileResult> downstreamResult;
-
- RefPtr<PostEmitMetadata> postEmitMetadata;
- };
-#endif
-
/// Information collected about global or entry-point shader parameters
struct ShaderParamInfo
{
@@ -2414,46 +2373,21 @@ namespace Slang
SlangResult emitEntryPoints(ComPtr<IArtifact>& outArtifact);
- SlangResult dissassembleWithDownstream(
- const void* data,
- size_t dataSizeInBytes,
- ISlangBlob** outBlob);
-
- SlangResult dissassembleWithDownstream(
- DownstreamCompileResult* downstreamResult,
- ISlangBlob** outBlob);
+ void maybeDumpIntermediate(IArtifact* artifact);
protected:
CodeGenTarget m_targetFormat = CodeGenTarget::Unknown;
ExtensionTracker* m_extensionTracker = nullptr;
- void maybeDumpIntermediate(IArtifact* artifact);
+ /// Will output assembly as well as the artifact if appropriate for the artifact type for assembly output
+ /// and conversion is possible
+ void _dumpIntermediateMaybeWithAssembly(IArtifact* artifact);
- // Helper to dump intermediate output when debugging
- void maybeDumpIntermediate(
+ void _dumpIntermediate(IArtifact* artifact);
+ void _dumpIntermediate(
+ const ArtifactDesc& desc,
void const* data,
size_t size);
- void maybeDumpIntermediate(
- char const* text);
-
- void maybeDumpIntermediate(
- DownstreamCompileResult* compileResult);
-
- void dumpIntermediate(
- void const* data,
- size_t size,
- char const* ext,
- bool isBinary);
-
- void dumpIntermediateText(
- void const* data,
- size_t size,
- char const* ext);
-
- void dumpIntermediateBinary(
- void const* data,
- size_t size,
- char const* ext);
/* Emits entry point source taking into account if a pass-through or not. Uses 'targetFormat' to determine
the target (not targetReq) */
@@ -2687,6 +2621,7 @@ namespace Slang
return m_specializedEntryPoints[index];
}
+ void writeArtifactToStandardOutput(IArtifact* artifact, DiagnosticSink* sink);
void generateOutput();
@@ -2865,7 +2800,7 @@ namespace Slang
{
return m_downstreamCompileTime;
}
-
+
/// Get the downstream compiler for a transition
DownstreamCompiler* getDownstreamCompiler(CodeGenTarget source, CodeGenTarget target);
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index cbbb284cb..6acd27e40 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -129,6 +129,7 @@ DIAGNOSTIC( 94, Error, unableToReadRiff, "unable to read as 'riff'/not a 'rif
DIAGNOSTIC( 95, Error, unknownLibraryKind, "unknown library kind '$0'")
DIAGNOSTIC( 96, Error, kindNotLinkable, "not a known linkable kind '$0'")
DIAGNOSTIC( 97, Error, libraryDoesNotExist, "library '$0' does not exist")
+DIAGNOSTIC( 98, Error, cannotAccessAsBlob, "cannot access as a blob")
//
// 001xx - Downstream Compilers
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 43f9da3df..2a1b78833 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -71,6 +71,7 @@
#include "../compiler-core/slang-artifact-desc-util.h"
#include "../compiler-core/slang-artifact-util.h"
#include "../compiler-core/slang-artifact-impl.h"
+#include "../compiler-core/slang-artifact-associated-impl.h"
#include <assert.h>
@@ -836,11 +837,10 @@ Result linkAndOptimizeIR(
#endif
validateIRModuleIfEnabled(codeGenContext, irModule);
- auto metadata = Artifact::create(ArtifactDesc::make(ArtifactKind::Instance, ArtifactPayload::PostEmitMetadata, artifactDesc.style));
- auto postEmitMetaRep = new PostEmitMetadataArtifactRepresentation;
- metadata->addRepresentation(postEmitMetaRep);
+ auto metadata = new PostEmitMetadata;
+ outLinkedIR.metadata = metadata;
- collectMetadata(irModule, postEmitMetaRep->m_metadata);
+ collectMetadata(irModule, *metadata);
outLinkedIR.metadata = metadata;
@@ -857,8 +857,6 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
auto target = getTargetFormat();
auto targetRequest = getTargetReq();
- auto artifactContainer = ArtifactUtil::createResultsContainer();
-
auto lineDirectiveMode = targetRequest->getLineDirectiveMode();
// To try to make the default behavior reasonable, we will
// always use C-style line directives (to give the user
@@ -930,7 +928,7 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
SLANG_RETURN_ON_FAIL(sourceEmitter->init());
-
+ ComPtr<IPostEmitMetadata> metadata;
{
LinkingAndOptimizationOptions linkingAndOptimizationOptions;
@@ -955,11 +953,8 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
auto irModule = linkedIR.module;
- if (linkedIR.metadata)
- {
- artifactContainer->addChild(linkedIR.metadata);
- }
-
+ metadata = linkedIR.metadata;
+
// After all of the required optimization and legalization
// passes have been performed, we can emit target code from
// the IR module.
@@ -1029,12 +1024,15 @@ SlangResult CodeGenContext::emitEntryPointsSourceFromIR(ComPtr<IArtifact>& outAr
// Write out the result
- auto targetArtifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
- targetArtifact->addRepresentationUnknown(StringBlob::moveCreate(finalResult));
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
+ artifact->addRepresentationUnknown(StringBlob::moveCreate(finalResult));
- artifactContainer->addChild(targetArtifact);
+ if (metadata)
+ {
+ artifact->addAssociated(metadata);
+ }
- outArtifact = artifactContainer;
+ outArtifact.swap(artifact);
return SLANG_OK;
}
@@ -1048,8 +1046,6 @@ SlangResult emitSPIRVForEntryPointsDirectly(
CodeGenContext* codeGenContext,
ComPtr<IArtifact>& outArtifact)
{
- auto artifactContainer = ArtifactUtil::createResultsContainer();
-
// Outside because we want to keep IR in scope whilst we are processing emits
LinkedIR linkedIR;
LinkingAndOptimizationOptions linkingAndOptimizationOptions;
@@ -1064,17 +1060,15 @@ SlangResult emitSPIRVForEntryPointsDirectly(
List<uint8_t> spirv;
emitSPIRVFromIR(codeGenContext, irModule, irEntryPoints, spirv);
- auto targetArtifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(codeGenContext->getTargetFormat()));
- targetArtifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));
-
- artifactContainer->addChild(targetArtifact);
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(codeGenContext->getTargetFormat()));
+ artifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));
if (linkedIR.metadata)
{
- artifactContainer->addChild(linkedIR.metadata);
+ artifact->addAssociated(linkedIR.metadata);
}
- outArtifact = artifactContainer;
+ outArtifact.swap(artifact);
return SLANG_OK;
}
diff --git a/source/slang/slang-ir-link.h b/source/slang/slang-ir-link.h
index dcfb642da..5fac8dde2 100644
--- a/source/slang/slang-ir-link.h
+++ b/source/slang/slang-ir-link.h
@@ -3,16 +3,18 @@
#include "slang-compiler.h"
+#include "../compiler-core/slang-artifact-associated.h"
+
namespace Slang
{
struct IRVarLayout;
struct LinkedIR
{
- RefPtr<IRModule> module;
- IRVarLayout* globalScopeVarLayout;
- List<IRFunc*> entryPoints;
- ComPtr<IArtifact> metadata;
+ RefPtr<IRModule> module;
+ IRVarLayout* globalScopeVarLayout;
+ List<IRFunc*> entryPoints;
+ ComPtr<IPostEmitMetadata> metadata;
};
diff --git a/source/slang/slang-ir-metadata.cpp b/source/slang/slang-ir-metadata.cpp
index 396c40837..7d4694ec5 100644
--- a/source/slang/slang-ir-metadata.cpp
+++ b/source/slang/slang-ir-metadata.cpp
@@ -4,7 +4,7 @@
#include "slang-ir.h"
#include "slang-ir-insts.h"
-#include "../compiler-core/slang-artifact-representation-impl.h"
+#include "../compiler-core/slang-artifact-associated-impl.h"
namespace Slang
{
@@ -69,11 +69,10 @@ void collectMetadata(const IRModule* irModule, PostEmitMetadata& outMetadata)
auto registerIndex = offsetAttr->getOffset();
auto size = sizeAttr->getSize();
auto count = size.isFinite() ? size.getFiniteValue() : 0;
- _insertBinding(outMetadata.usedBindings, kind, spaceIndex, registerIndex, count);
+ _insertBinding(outMetadata.m_usedBindings, kind, spaceIndex, registerIndex, count);
}
}
}
}
-
}
diff --git a/source/slang/slang-ir-metadata.h b/source/slang/slang-ir-metadata.h
index b7fcd1e2b..e72e10a94 100644
--- a/source/slang/slang-ir-metadata.h
+++ b/source/slang/slang-ir-metadata.h
@@ -4,7 +4,7 @@
namespace Slang
{
-struct PostEmitMetadata;
+class PostEmitMetadata;
struct IRModule;
void collectMetadata(const IRModule* irModule, PostEmitMetadata& outMetadata);
diff --git a/source/slang/slang-module-library.h b/source/slang/slang-module-library.h
index dd74193a4..698e4e014 100644
--- a/source/slang/slang-module-library.h
+++ b/source/slang/slang-module-library.h
@@ -26,7 +26,7 @@ public:
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// IArtifactRepresentation
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) SLANG_OVERRIDE { SLANG_UNUSED(blob); return SLANG_E_NOT_IMPLEMENTED; }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE { SLANG_UNUSED(typeGuid); SLANG_UNUSED(outCastable); return SLANG_E_NOT_IMPLEMENTED; }
virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; }
List<FrontEndCompileRequest::ExtraEntryPointInfo> m_entryPoints;
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 6515dc35d..4f135d144 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -11,6 +11,7 @@
#include "../compiler-core/slang-artifact-impl.h"
#include "../compiler-core/slang-artifact-desc-util.h"
#include "../compiler-core/slang-artifact-util.h"
+#include "../compiler-core/slang-artifact-associated-impl.h"
#include "slang-module-library.h"
@@ -3153,19 +3154,13 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode(
DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer);
- IArtifact* entryPointResult = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
+ IArtifact* artifact = targetProgram->getOrCreateEntryPointResult(entryPointIndex, &sink);
sink.getBlobIfNeeded(outDiagnostics);
- if(entryPointResult == nullptr)
- return SLANG_FAIL;
-
- IArtifact* significantBlob = ArtifactUtil::findSignificant(entryPointResult);
- if (!significantBlob)
- {
+ if(artifact == nullptr)
return SLANG_FAIL;
- }
- return significantBlob->loadBlob(ArtifactKeep::Yes, outCode);
+ return artifact->loadBlob(ArtifactKeep::Yes, outCode);
}
SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointHostCallable(
@@ -4838,11 +4833,8 @@ SlangResult EndToEndCompileRequest::getEntryPointCodeBlob(int entryPointIndex, i
if (!outBlob) return SLANG_E_INVALID_ARG;
ComPtr<IArtifact> artifact;
SLANG_RETURN_ON_FAIL(_getEntryPointResult(this, entryPointIndex, targetIndex, artifact));
- if (auto significant = ArtifactUtil::findSignificant(artifact))
- {
- SLANG_RETURN_ON_FAIL(significant->loadBlob(ArtifactKeep::Yes, outBlob));
- return SLANG_OK;
- }
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::Yes, outBlob));
+
return SLANG_E_NOT_AVAILABLE;
}
@@ -4851,11 +4843,7 @@ SlangResult EndToEndCompileRequest::getEntryPointHostCallable(int entryPointInde
if (!outSharedLibrary) return SLANG_E_INVALID_ARG;
ComPtr<IArtifact> artifact;
SLANG_RETURN_ON_FAIL(_getEntryPointResult(this, entryPointIndex, targetIndex, artifact));
- if (auto significant = ArtifactUtil::findSignificant(artifact))
- {
- SLANG_RETURN_ON_FAIL(significant->loadSharedLibrary(ArtifactKeep::Yes, outSharedLibrary));
- return SLANG_OK;
- }
+ SLANG_RETURN_ON_FAIL(artifact->loadSharedLibrary(ArtifactKeep::Yes, outSharedLibrary));
return SLANG_E_NOT_AVAILABLE;
}
@@ -4866,13 +4854,8 @@ SlangResult EndToEndCompileRequest::getTargetCodeBlob(int targetIndex, ISlangBlo
ComPtr<IArtifact> artifact;
SLANG_RETURN_ON_FAIL(_getWholeProgramResult(this, targetIndex, artifact));
-
- if (auto significant = ArtifactUtil::findSignificant(artifact))
- {
- SLANG_RETURN_ON_FAIL(significant->loadBlob(ArtifactKeep::Yes, outBlob));
- return SLANG_OK;
- }
- return SLANG_E_NOT_AVAILABLE;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(ArtifactKeep::Yes, outBlob));
+ return SLANG_OK;
}
SlangResult EndToEndCompileRequest::getTargetHostCallable(int targetIndex,ISlangSharedLibrary** outSharedLibrary)
@@ -5030,22 +5013,14 @@ SlangResult EndToEndCompileRequest::isParameterLocationUsed(Int entryPointIndex,
if (SLANG_FAILED(_getEntryPointResult(this, static_cast<int>(entryPointIndex), static_cast<int>(targetIndex), artifact)))
return SLANG_E_INVALID_ARG;
- // We need to find the meta data
- IArtifact* metadataArtifact = artifact->findArtifactByDerivedDesc(IArtifact::FindStyle::SelfOrChildren,
- ArtifactDesc::make(ArtifactKind::Base, ArtifactPayload::PostEmitMetadata, ArtifactStyle::Base));
- if (!metadataArtifact)
- {
- return SLANG_E_NOT_AVAILABLE;
- }
-
// Find a rep
- auto metadataRep = findRepresentation<IPostEmitMetadataArtifactRepresentation>(metadataArtifact);
- if (!metadataRep)
+ auto metadata = findAssociated<IPostEmitMetadata>(artifact);
+ if (!metadata)
return SLANG_E_NOT_AVAILABLE;
// TODO: optimize this with a binary search through a sorted list
- for (const auto& range : metadataRep->getBindingRanges())
+ for (const auto& range : metadata->getBindingRanges())
{
if (range.containsBinding((slang::ParameterCategory)category, spaceIndex, registerIndex))
{