summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-compiler.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-16 03:39:41 -0400
committerGitHub <noreply@github.com>2022-08-16 00:39:41 -0700
commitac71724c03392b429e44641a3641b2bcf7cc55fc (patch)
tree8f7ffa61329dd24bc9be551e293840b6b94aab36 /source/slang/slang-compiler.cpp
parent786f48d32340c36a06865a333ff9066033b5b2bc (diff)
Remove CompileResult to use IArtifact (#2357)
* #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.
Diffstat (limited to 'source/slang/slang-compiler.cpp')
-rw-r--r--source/slang/slang-compiler.cpp513
1 files changed, 254 insertions, 259 deletions
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 80015440a..e49b67af2 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -18,6 +18,7 @@
#include "../compiler-core/slang-artifact-desc-util.h"
#include "../compiler-core/slang-artifact-representation-impl.h"
#include "../compiler-core/slang-artifact-impl.h"
+#include "../compiler-core/slang-artifact-util.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
@@ -55,52 +56,7 @@
namespace Slang
{
- // A temporary class that adapts `ISlangSharedLibrary_Dep1` to ISlangSharedLibrary
- class SharedLibraryDep1Adapter : public ComBaseObject, public ISlangSharedLibrary
- {
- public:
- SLANG_COM_BASE_IUNKNOWN_ALL
-
- // ICastable
- virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
-
- // ISlangSharedLibrary
- virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE { return m_contained->findSymbolAddressByName(name); }
-
- SharedLibraryDep1Adapter(ISlangSharedLibrary_Dep1* dep1):
- m_contained(dep1)
- {
- }
-
- protected:
- void* getInterface(const Guid& guid)
- {
- if (guid == ISlangUnknown::getTypeGuid() ||
- guid == ICastable::getTypeGuid() ||
- guid == ISlangSharedLibrary::getTypeGuid())
- {
- return static_cast<ISlangSharedLibrary*>(this);
- }
- return nullptr;
- }
- void* getObject(const Guid& guid)
- {
- SLANG_UNUSED(guid);
- return nullptr;
- }
-
- ComPtr<ISlangSharedLibrary_Dep1> m_contained;
- };
-
- void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid)
- {
- if (auto intf = getInterface(guid))
- {
- return intf;
- }
- return getObject(guid);
- }
// !!!!!!!!!!!!!!!!!!!!!! free functions for DiagnosicSink !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -123,6 +79,7 @@ namespace Slang
// !!!!!!!!!!!!!!!!!!!!!!!!!!!! CompileResult !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#if 0
SlangResult CompileResult::getSharedLibrary(ComPtr<ISlangSharedLibrary>& outSharedLibrary)
{
if (downstreamResult)
@@ -188,27 +145,8 @@ namespace Slang
return SLANG_OK;
}
- SlangResult CompileResult::isParameterLocationUsed(SlangParameterCategory category, UInt spaceIndex, UInt registerIndex, bool& outUsed)
- {
- if (!postEmitMetadata)
- return SLANG_E_NOT_AVAILABLE;
-
- if (!ShaderBindingRange::isUsageTracked((slang::ParameterCategory)category))
- return SLANG_E_NOT_AVAILABLE;
- // TODO: optimize this with a binary search through a sorted list
- for (const auto& range : postEmitMetadata->usedBindings)
- {
- if (range.containsBinding((slang::ParameterCategory)category, spaceIndex, registerIndex))
- {
- outUsed = true;
- return SLANG_OK;
- }
- }
-
- outUsed = false;
- return SLANG_OK;
- }
+#endif
//
// FrontEndEntryPointRequest
@@ -729,13 +667,20 @@ namespace Slang
}
}
- SlangResult CodeGenContext::emitEntryPointsSource(
- String& outSource,
- RefPtr<PostEmitMetadata>& outMetadata)
+#if SLANG_VC
+// TODO(JS): This is a workaround
+// In debug VS builds there is a warning on line about it being unreachable.
+// for (auto entryPointIndex : getEntryPointIndices())
+// It's not clear how that could possibly be unreachable
+# pragma warning(push)
+# pragma warning(disable:4702)
+#endif
+ SlangResult CodeGenContext::emitEntryPointsSource(ComPtr<IArtifact>& outArtifact)
{
- outSource = String();
+ outArtifact.setNull();
- if(auto endToEndReq = isPassThroughEnabled())
+ auto endToEndReq = isPassThroughEnabled();
+ if(endToEndReq)
{
for (auto entryPointIndex : getEntryPointIndices())
{
@@ -776,16 +721,22 @@ namespace Slang
}
}
- outSource = codeBuilder.ProduceString();
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(getTargetFormat()));
+ artifact->addRepresentationUnknown(StringBlob::moveCreate(codeBuilder));
+
+ outArtifact.swap(artifact);
+ return SLANG_OK;
}
return SLANG_OK;
}
else
{
- return emitEntryPointsSourceFromIR(
- outSource, outMetadata);
+ return emitEntryPointsSourceFromIR(outArtifact);
}
}
+#if SLANG_VC
+# pragma warning(pop)
+#endif
String GetHLSLProfileName(Profile profile)
{
@@ -1052,11 +1003,9 @@ namespace Slang
return desc.style == ArtifactStyle::Host;
}
- SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(
- RefPtr<DownstreamCompileResult>& outResult,
- RefPtr<PostEmitMetadata>& outMetadata)
+ SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(ComPtr<IArtifact>& outArtifact)
{
- outResult.setNull();
+ outArtifact.setNull();
auto sink = getSink();
auto session = getSession();
@@ -1123,6 +1072,8 @@ namespace Slang
}
}
+ ComPtr<IArtifact> sourceContainerArtifact;
+
/* 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
for that to work most easily we want to use the original file, if there is one */
@@ -1189,7 +1140,10 @@ namespace Slang
options.sourceContentsPath = calcSourcePathForEntryPoints();
CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker);
- SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(options.sourceContents, outMetadata));
+
+ SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceContainerArtifact));
+
+ sourceCodeGenContext.maybeDumpIntermediate(sourceContainerArtifact);
}
else
{
@@ -1206,12 +1160,32 @@ namespace Slang
else
{
CodeGenContext sourceCodeGenContext(this, sourceTarget, extensionTracker);
- SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(options.sourceContents, outMetadata));
- sourceCodeGenContext.maybeDumpIntermediate(options.sourceContents.getBuffer());
+
+ SLANG_RETURN_ON_FAIL(sourceCodeGenContext.emitEntryPointsSource(sourceContainerArtifact));
+ sourceCodeGenContext.maybeDumpIntermediate(sourceContainerArtifact);
sourceLanguage = (SourceLanguage)TypeConvertUtil::getSourceLanguageFromTarget((SlangCompileTarget)sourceTarget);
}
+ ComPtr<IArtifact> metadata;
+ if (sourceContainerArtifact)
+ {
+ 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));
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(sourceArtifact->loadBlob(ArtifactKeep::No, blob.writeRef()));
+
+ options.sourceContents = StringUtil::getString(blob);
+ }
+
// Add any preprocessor definitions associated with the linkage
{
// TODO(JS): This is somewhat arguable - should defines passed to Slang really be
@@ -1539,7 +1513,22 @@ namespace Slang
return SLANG_FAIL;
}
- outResult = downstreamCompileResult;
+ auto artifactContainer = ArtifactUtil::createResultsContainer();
+
+ if (metadata)
+ {
+ artifactContainer->addChild(metadata);
+ }
+
+ // Create the artifact that encapsulates the result
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
+
+ // Wrap the downstream compile result
+ auto objRep = new ObjectArtifactRepresentation(DownstreamCompileResult::getTypeGuid(), downstreamCompileResult);
+ artifact->addRepresentation(objRep);
+
+ // Set the artifact
+ outArtifact.swap(artifact);
return SLANG_OK;
}
@@ -1588,8 +1577,7 @@ namespace Slang
SlangResult emitSPIRVForEntryPointsDirectly(
CodeGenContext* codeGenContext,
- List<uint8_t>& spirvOut,
- RefPtr<PostEmitMetadata>& outMetadata);
+ ComPtr<IArtifact>& outArtifact);
static CodeGenTarget _getIntermediateTarget(CodeGenTarget target)
{
@@ -1603,9 +1591,7 @@ namespace Slang
}
/// Function to simplify the logic around emitting, and dissassembling
- SlangResult CodeGenContext::_emitEntryPoints(
- RefPtr<DownstreamCompileResult>& outDownstreamResult,
- RefPtr<PostEmitMetadata>& outMetadata)
+ SlangResult CodeGenContext::_emitEntryPoints(ComPtr<IArtifact>& outArtifact)
{
auto target = getTargetFormat();
switch (target)
@@ -1618,25 +1604,37 @@ namespace Slang
const CodeGenTarget intermediateTarget = _getIntermediateTarget(target);
CodeGenContext intermediateContext(this, intermediateTarget);
- RefPtr<DownstreamCompileResult> code;
- SLANG_RETURN_ON_FAIL(intermediateContext._emitEntryPoints(code, outMetadata));
- intermediateContext.maybeDumpIntermediate(code);
+ ComPtr<IArtifact> intermediateArtifact;
+
+ 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(code, disassemblyBlob.writeRef()));
+ SLANG_RETURN_ON_FAIL(intermediateContext.dissassembleWithDownstream(binaryBlob->getBufferPointer(), binaryBlob->getBufferSize(), disassemblyBlob.writeRef()));
+
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(target));
+ artifact->addRepresentationUnknown(disassemblyBlob);
+
+ outArtifact.swap(artifact);
- outDownstreamResult = new BlobDownstreamCompileResult(DownstreamDiagnostics(), disassemblyBlob);
return SLANG_OK;
}
case CodeGenTarget::SPIRV:
if (getTargetReq()->shouldEmitSPIRVDirectly())
{
- List<uint8_t> spirv;
- SLANG_RETURN_ON_FAIL(emitSPIRVForEntryPointsDirectly(this, spirv, outMetadata));
- auto spirvBlob = ListBlob::moveCreate(spirv);
- outDownstreamResult = new BlobDownstreamCompileResult(DownstreamDiagnostics(), spirvBlob);
+ SLANG_RETURN_ON_FAIL(emitSPIRVForEntryPointsDirectly(this, outArtifact));
return SLANG_OK;
}
/* fall through to: */
@@ -1647,7 +1645,7 @@ namespace Slang
case CodeGenTarget::ShaderSharedLibrary:
case CodeGenTarget::HostExecutable:
case CodeGenTarget::HostHostCallable:
- SLANG_RETURN_ON_FAIL(emitWithDownstreamForEntryPoints(outDownstreamResult, outMetadata));
+ SLANG_RETURN_ON_FAIL(emitWithDownstreamForEntryPoints(outArtifact));
return SLANG_OK;
default: break;
@@ -1657,10 +1655,8 @@ namespace Slang
}
// Do emit logic for a zero or more entry points
- CompileResult CodeGenContext::emitEntryPoints()
+ SlangResult CodeGenContext::emitEntryPoints(ComPtr<IArtifact>& outArtifact)
{
- CompileResult result;
-
auto target = getTargetFormat();
switch (target)
@@ -1677,14 +1673,10 @@ namespace Slang
case CodeGenTarget::ShaderSharedLibrary:
case CodeGenTarget::HostExecutable:
{
- RefPtr<DownstreamCompileResult> downstreamResult;
- RefPtr<PostEmitMetadata> metadata;
+ SLANG_RETURN_ON_FAIL(_emitEntryPoints(outArtifact));
- if (SLANG_SUCCEEDED(_emitEntryPoints(downstreamResult, metadata)))
- {
- maybeDumpIntermediate(downstreamResult);
- result = CompileResult(downstreamResult, metadata);
- }
+ maybeDumpIntermediate(outArtifact);
+ return SLANG_OK;
}
break;
case CodeGenTarget::GLSL:
@@ -1695,35 +1687,31 @@ namespace Slang
case CodeGenTarget::CSource:
{
RefPtr<ExtensionTracker> extensionTracker = _newExtensionTracker(target);
- RefPtr<PostEmitMetadata> metadata;
-
+
CodeGenContext subContext(this, target, extensionTracker);
- String code;
- if (SLANG_FAILED(subContext.emitEntryPointsSource(code, metadata)))
- {
- return result;
- }
+ ComPtr<IArtifact> sourceArtifact;
+
+ SLANG_RETURN_ON_FAIL(subContext.emitEntryPointsSource(sourceArtifact));
- subContext.maybeDumpIntermediate(code.getBuffer());
- result = CompileResult(code, metadata);
+ subContext.maybeDumpIntermediate(sourceArtifact);
+ outArtifact = sourceArtifact;
+ return SLANG_OK;
}
break;
case CodeGenTarget::None:
// The user requested no output
- break;
+ return SLANG_OK;
// Note(tfoley): We currently hit this case when compiling the stdlib
case CodeGenTarget::Unknown:
- break;
+ return SLANG_OK;
default:
SLANG_UNEXPECTED("unhandled code generation target");
break;
}
-
- return result;
}
enum class OutputFileKind
@@ -1792,42 +1780,31 @@ namespace Slang
static void writeCompileResultToFile(
CodeGenContext* context,
String const& outputPath,
- CompileResult const& result)
+ IArtifact* inArtifact)
{
- switch (result.format)
+ // The artifact can contain multiple things, we want to find something like 'source' or binary like
+ IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact);
+ if (!artifact)
{
- case ResultFormat::Text:
- {
- auto text = result.outputString;
- writeOutputFile(context,
- outputPath,
- text.begin(),
- text.end() - text.begin(),
- OutputFileKind::Text);
- }
- break;
-
- case ResultFormat::Binary:
- {
- ComPtr<ISlangBlob> blob;
- if (SLANG_FAILED(result.getBlob(blob)))
- {
- SLANG_UNEXPECTED("No blob to emit");
- return;
- }
- writeOutputFile(context,
- outputPath,
- blob->getBufferPointer(),
- blob->getBufferSize(),
- OutputFileKind::Binary);
- }
- break;
+ return;
+ }
- default:
- SLANG_UNEXPECTED("unhandled output format");
- break;
+ 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(
@@ -1840,99 +1817,65 @@ namespace Slang
static void writeCompileResultToStandardOutput(
CodeGenContext* codeGenContext,
EndToEndCompileRequest* endToEndReq,
- CompileResult const& result)
+ IArtifact* inArtifact)
{
- auto targetReq = codeGenContext->getTargetReq();
ISlangWriter* writer = endToEndReq->getWriter(WriterChannel::StdOutput);
- switch (result.format)
+ // The artifact can contain multiple things, we want to find something like 'source' or binary like
+ IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact);
+ if (!artifact)
{
- case ResultFormat::Text:
- writeOutputToConsole(writer, result.outputString);
- break;
-
- case ResultFormat::Binary:
- {
- ComPtr<ISlangBlob> blob;
- if (SLANG_FAILED(result.getBlob(blob)))
- {
- if (ArtifactDescUtil::makeDescFromCompileTarget(asExternal(targetReq->getTarget())).kind == ArtifactKind::HostCallable)
- {
- // Some HostCallable are not directly representable as a 'binary'.
- // So here, we just ignore if that appears the case, and don't output an unexpected error.
- return;
- }
+ return;
+ }
- SLANG_UNEXPECTED("No blob to emit");
- return;
- }
+ ComPtr<ISlangBlob> blob;
+ if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef())))
+ {
+ // Unable to get blob
+ return;
+ }
- const void* blobData = blob->getBufferPointer();
- size_t blobSize = blob->getBufferSize();
+ // If is text, we can just output
+ if (ArtifactDescUtil::isText(artifact->getDesc()))
+ {
+ writer->write((const char*)blob->getBufferPointer(), blob->getBufferSize());
+ return;
+ }
- if (writer->isConsole())
+ if (writer->isConsole())
+ {
+ switch (artifact->getDesc().payload)
+ {
+ case ArtifactPayload::SPIRV:
+ case ArtifactPayload::DXIL:
+ case ArtifactPayload::DXBC:
{
- // Writing to console, so we need to generate text output.
+ ComPtr<ISlangBlob> disassemblyBlob;
- switch (targetReq->getTarget())
+ if (SLANG_SUCCEEDED(codeGenContext->dissassembleWithDownstream(blob->getBufferPointer(), blob->getBufferSize(), disassemblyBlob.writeRef())))
{
- case CodeGenTarget::SPIRVAssembly:
- case CodeGenTarget::DXBytecodeAssembly:
- case CodeGenTarget::DXILAssembly:
- {
- const UnownedStringSlice disassembly = StringUtil::getSlice(blob);
- writeOutputToConsole(writer, disassembly);
- }
- break;
- case CodeGenTarget::SPIRV:
- case CodeGenTarget::DXIL:
- case CodeGenTarget::DXBytecode:
- {
- ComPtr<ISlangBlob> disassemblyBlob;
-
- if (SLANG_SUCCEEDED(codeGenContext->dissassembleWithDownstream(blobData, blobSize, disassemblyBlob.writeRef())))
- {
- const UnownedStringSlice disassembly = StringUtil::getSlice(disassemblyBlob);
- writeOutputToConsole(writer, disassembly);
- }
- }
- break;
- case CodeGenTarget::PTX:
- // For now we just dump PTX out as hex
-
- case CodeGenTarget::HostHostCallable:
- case CodeGenTarget::ShaderHostCallable:
- case CodeGenTarget::ShaderSharedLibrary:
- case CodeGenTarget::HostExecutable:
- HexDumpUtil::dumpWithMarkers((const uint8_t*)blobData, blobSize, 24, writer);
- break;
-
-
- default:
- SLANG_UNEXPECTED("unhandled output format");
- return;
- }
+ const UnownedStringSlice disassembly = StringUtil::getSlice(disassemblyBlob);
+ writeOutputToConsole(writer, disassembly);
+ }
+ return;
}
- else
- {
- // Redirecting stdout to a file, so do the usual thing
- writer->setMode(SLANG_WRITER_MODE_BINARY);
-
- writeOutputFile(
- codeGenContext,
- writer,
- "stdout",
- blobData,
- blobSize);
}
- }
- break;
- default:
- SLANG_UNEXPECTED("unhandled output format");
- break;
+ // 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());
+ }
}
void EndToEndCompileRequest::writeWholeProgramResult(
@@ -1941,10 +1884,10 @@ namespace Slang
auto program = getSpecializedGlobalAndEntryPointsComponentType();
auto targetProgram = program->getTargetProgram(targetReq);
- auto& result = targetProgram->getExistingWholeProgramResult();
+ IArtifact* artifact = targetProgram->getExistingWholeProgramResult();
// Skip the case with no output
- if (result.format == ResultFormat::None)
+ if (artifact == nullptr)
return;
CodeGenContext::EntryPointIndices entryPointIndices;
@@ -1964,12 +1907,12 @@ namespace Slang
String outputPath = targetInfo->wholeTargetOutputPath;
if (outputPath != "")
{
- writeCompileResultToFile(&codeGenContext, outputPath, result);
+ writeCompileResultToFile(&codeGenContext, outputPath, artifact);
return;
}
}
- writeCompileResultToStandardOutput(&codeGenContext, this, result);
+ writeCompileResultToStandardOutput(&codeGenContext, this, artifact);
}
void EndToEndCompileRequest::writeEntryPointResult(
@@ -1979,10 +1922,10 @@ namespace Slang
auto program = getSpecializedGlobalAndEntryPointsComponentType();
auto targetProgram = program->getTargetProgram(targetReq);
- auto& result = targetProgram->getExistingEntryPointResult(entryPointIndex);
+ IArtifact* artifact = targetProgram->getExistingEntryPointResult(entryPointIndex);
// Skip the case with no output
- if (result.format == ResultFormat::None)
+ if (artifact == nullptr)
return;
CodeGenContext::EntryPointIndices entryPointIndices;
@@ -2003,15 +1946,15 @@ namespace Slang
String outputPath;
if(targetInfo->entryPointOutputPaths.TryGetValue(entryPointIndex, outputPath))
{
- writeCompileResultToFile(&codeGenContext, outputPath, result);
+ writeCompileResultToFile(&codeGenContext, outputPath, artifact);
return;
}
}
- writeCompileResultToStandardOutput(&codeGenContext, this, result);
+ writeCompileResultToStandardOutput(&codeGenContext, this, artifact);
}
- CompileResult& TargetProgram::_createWholeProgramResult(
+ IArtifact* TargetProgram::_createWholeProgramResult(
DiagnosticSink* sink,
EndToEndCompileRequest* endToEndReq)
{
@@ -2026,17 +1969,18 @@ namespace Slang
for (Index i = 0; i < entryPointIndices.getCount(); i++)
entryPointIndices[i] = i;
- auto& result = m_wholeProgramResult;
-
CodeGenContext::Shared sharedCodeGenContext(this, entryPointIndices, sink, endToEndReq);
CodeGenContext codeGenContext(&sharedCodeGenContext);
- result = codeGenContext.emitEntryPoints();
-
- return result;
+ if (SLANG_FAILED(codeGenContext.emitEntryPoints(m_wholeProgramResult)))
+ {
+ return nullptr;
+ }
+
+ return m_wholeProgramResult;
}
- CompileResult& TargetProgram::_createEntryPointResult(
+ IArtifact* TargetProgram::_createEntryPointResult(
Int entryPointIndex,
DiagnosticSink* sink,
EndToEndCompileRequest* endToEndReq)
@@ -2050,26 +1994,25 @@ namespace Slang
// this problem.
//
if(entryPointIndex >= m_entryPointResults.getCount())
- m_entryPointResults.setCount(entryPointIndex+1);
-
- auto& result = m_entryPointResults[entryPointIndex];
+ m_entryPointResults.setCount(entryPointIndex + 1);
+
CodeGenContext::EntryPointIndices entryPointIndices;
entryPointIndices.add(entryPointIndex);
CodeGenContext::Shared sharedCodeGenContext(this, entryPointIndices, sink, endToEndReq);
CodeGenContext codeGenContext(&sharedCodeGenContext);
- result = codeGenContext.emitEntryPoints();
- return result;
+ codeGenContext.emitEntryPoints(m_entryPointResults[entryPointIndex]);
+
+ return m_entryPointResults[entryPointIndex];
}
- CompileResult& TargetProgram::getOrCreateWholeProgramResult(
+ IArtifact* TargetProgram::getOrCreateWholeProgramResult(
DiagnosticSink* sink)
{
- auto& result = m_wholeProgramResult;
- if (result.format != ResultFormat::None)
- return result;
+ if (m_wholeProgramResult)
+ return m_wholeProgramResult;
// If we haven't yet computed a layout for this target
// program, we need to make sure that is done before
@@ -2077,22 +2020,21 @@ namespace Slang
//
if (!getOrCreateIRModuleForLayout(sink))
{
- return result;
+ return nullptr;
}
return _createWholeProgramResult(sink);
}
- CompileResult& TargetProgram::getOrCreateEntryPointResult(
+ IArtifact* TargetProgram::getOrCreateEntryPointResult(
Int entryPointIndex,
DiagnosticSink* sink)
{
if(entryPointIndex >= m_entryPointResults.getCount())
- m_entryPointResults.setCount(entryPointIndex+1);
+ m_entryPointResults.setCount(entryPointIndex + 1);
- auto& result = m_entryPointResults[entryPointIndex];
- if( result.format != ResultFormat::None )
- return result;
+ if(IArtifact* artifact = m_entryPointResults[entryPointIndex])
+ return artifact;
// If we haven't yet computed a layout for this target
// program, we need to make sure that is done before
@@ -2100,7 +2042,7 @@ namespace Slang
//
if( !getOrCreateIRModuleForLayout(sink) )
{
- return result;
+ return nullptr;
}
return _createEntryPointResult(
@@ -2492,6 +2434,59 @@ namespace Slang
return nullptr;
}
+ void CodeGenContext::maybeDumpIntermediate(IArtifact* inArtifact)
+ {
+ if (!shouldDumpIntermediates())
+ return;
+
+ IArtifact* artifact = ArtifactUtil::findSignificant(inArtifact);
+ if (!artifact)
+ {
+ return;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ if (SLANG_FAILED(artifact->loadBlob(ArtifactKeep::No, blob.writeRef())))
+ {
+ return;
+ }
+
+ const auto desc = artifact->getDesc();
+ String ext = ArtifactDescUtil::getDefaultExtension(desc);
+
+
+ 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;
+
+ if (SLANG_SUCCEEDED(dissassembleWithDownstream(blob->getBufferPointer(), blob->getBufferSize(), disassemblyBlob.writeRef())))
+ {
+ ArtifactDesc assemblyDesc(desc);
+ assemblyDesc.kind = ArtifactKind::Assembly;
+
+ ext = ArtifactDescUtil::getDefaultExtension(assemblyDesc);
+
+ dumpIntermediateText(disassemblyBlob->getBufferPointer(), disassemblyBlob->getBufferSize(), ext.getBuffer());
+ return;
+ }
+ }
+ default: break;
+ }
+
+ dumpIntermediateBinary(blob->getBufferPointer(), blob->getBufferSize(), ext.getBuffer());
+ }
+ }
+
void CodeGenContext::maybeDumpIntermediate(
void const* data,
size_t size)