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 | |
| 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')
| -rw-r--r-- | source/slang/slang-artifact-output-util.cpp | 237 | ||||
| -rw-r--r-- | source/slang/slang-artifact-output-util.h | 46 | ||||
| -rw-r--r-- | source/slang/slang-compiler.cpp | 594 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 83 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 42 | ||||
| -rw-r--r-- | source/slang/slang-ir-link.h | 10 | ||||
| -rw-r--r-- | source/slang/slang-ir-metadata.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-metadata.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-module-library.h | 2 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 49 |
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)) { |
