summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-compiler.cpp122
-rwxr-xr-xsource/slang/slang-compiler.h3
-rw-r--r--source/slang/slang-emit-spirv.cpp24
-rw-r--r--source/slang/slang-emit.cpp32
-rw-r--r--source/slang/slang-ir-inline.cpp29
-rw-r--r--source/slang/slang-ir-inline.h3
-rw-r--r--source/slang/slang-spirv-opt.cpp66
-rw-r--r--source/slang/slang-spirv-opt.h10
8 files changed, 111 insertions, 178 deletions
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 9b14fd2f7..997466d49 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -953,6 +953,71 @@ namespace Slang
return false;
}
+ SlangResult passthroughDownstreamDiagnostics(DiagnosticSink* sink, IDownstreamCompiler* compiler, IArtifact* artifact)
+ {
+ auto diagnostics = findAssociatedRepresentation<IArtifactDiagnostics>(artifact);
+
+ if (!diagnostics)
+ return SLANG_OK;
+
+ if (diagnostics->getCount())
+ {
+ StringBuilder compilerText;
+ DownstreamCompilerUtil::appendAsText(compiler->getDesc(), compilerText);
+
+ StringBuilder builder;
+
+ auto const diagnosticCount = diagnostics->getCount();
+ for (Index i = 0; i < diagnosticCount; ++i)
+ {
+ const auto& diagnostic = *diagnostics->getAt(i);
+
+ builder.clear();
+
+ const Severity severity = _getDiagnosticSeverity(diagnostic.severity);
+
+ if (diagnostic.filePath.count == 0 && diagnostic.location.line == 0 && severity == Severity::Note)
+ {
+ // If theres no filePath line number and it's info, output severity and text alone
+ builder << getSeverityName(severity) << " : ";
+ }
+ else
+ {
+ if (diagnostic.filePath.count)
+ {
+ builder << asStringSlice(diagnostic.filePath);
+ }
+
+ if (diagnostic.location.line)
+ {
+ builder << "(" << diagnostic.location.line << ")";
+ }
+
+ builder << ": ";
+
+ if (diagnostic.stage == ArtifactDiagnostic::Stage::Link)
+ {
+ builder << "link ";
+ }
+
+ builder << getSeverityName(severity);
+ builder << " " << asStringSlice(diagnostic.code) << ": ";
+ }
+
+ builder << asStringSlice(diagnostic.text);
+ reportExternalCompileError(compilerText.getBuffer(), severity, SLANG_OK, builder.getUnownedSlice(), sink);
+ }
+ }
+
+ // If any errors are emitted, then we are done
+ if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error))
+ {
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+ }
+
SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(ComPtr<IArtifact>& outArtifact)
{
outArtifact.setNull();
@@ -1421,62 +1486,7 @@ namespace Slang
(std::chrono::high_resolution_clock::now() - downstreamStartTime).count() * 0.000000001;
getSession()->addDownstreamCompileTime(downstreamElapsedTime);
- auto diagnostics = findAssociatedRepresentation<IArtifactDiagnostics>(artifact);
-
- if (diagnostics->getCount())
- {
- StringBuilder compilerText;
- DownstreamCompilerUtil::appendAsText(compiler->getDesc(), compilerText);
-
- StringBuilder builder;
-
- auto const diagnosticCount = diagnostics->getCount();
- for (Index i = 0; i < diagnosticCount; ++i)
- {
- const auto& diagnostic = *diagnostics->getAt(i);
-
- builder.clear();
-
- const Severity severity = _getDiagnosticSeverity(diagnostic.severity);
-
- if (diagnostic.filePath.count == 0 && diagnostic.location.line == 0 && severity == Severity::Note)
- {
- // If theres no filePath line number and it's info, output severity and text alone
- builder << getSeverityName(severity) << " : ";
- }
- else
- {
- if (diagnostic.filePath.count)
- {
- builder << asStringSlice(diagnostic.filePath);
- }
-
- if (diagnostic.location.line)
- {
- builder << "(" << diagnostic.location.line <<")";
- }
-
- builder << ": ";
-
- if (diagnostic.stage == ArtifactDiagnostic::Stage::Link)
- {
- builder << "link ";
- }
-
- builder << getSeverityName(severity);
- builder << " " << asStringSlice(diagnostic.code) << ": ";
- }
-
- builder << asStringSlice(diagnostic.text);
- reportExternalCompileError(compilerText.getBuffer(), severity, SLANG_OK, builder.getUnownedSlice(), sink);
- }
- }
-
- // If any errors are emitted, then we are done
- if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error))
- {
- return SLANG_FAIL;
- }
+ SLANG_RETURN_ON_FAIL(passthroughDownstreamDiagnostics(getSink(), compiler, artifact));
// Copy over all of the information associated with the source into the output
if (sourceArtifact)
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index c5bd3348c..c3f2d8e70 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1197,6 +1197,7 @@ namespace Slang
GenericCCpp = SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C/C++ compiler
NVRTC = SLANG_PASS_THROUGH_NVRTC, ///< NVRTC CUDA compiler
LLVM = SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler'
+ SpirvOpt = SLANG_PASS_THROUGH_SPIRV_OPT, ///< pass thorugh spirv to spirv-opt
CountOf = SLANG_PASS_THROUGH_COUNT_OF,
};
void printDiagnosticArg(StringBuilder& sb, PassThroughMode val);
@@ -3153,6 +3154,8 @@ namespace Slang
DiagnosticSink* sink,
const LoadedModuleDictionary* additionalLoadedModules);
+ SlangResult passthroughDownstreamDiagnostics(DiagnosticSink* sink, IDownstreamCompiler* compiler, IArtifact* artifact);
+
//
// The following functions are utilties to convert between
// matching "external" (public API) and "internal" (implementation)
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 6d71f1a2c..16a88b8af 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -4815,18 +4815,22 @@ SlangResult emitSPIRVFromIR(
(uint8_t const*) context.m_words.getBuffer(),
context.m_words.getCount() * Index(sizeof(context.m_words[0])));
- const auto validationResult = debugValidateSPIRV(spirvOut);
- // If validation isn't available, don't say it failed, it's just a debug
- // feature so we can skip
- if(SLANG_FAILED(validationResult) && validationResult != SLANG_E_NOT_AVAILABLE)
+ StringBuilder runSpirvValEnvVar;
+ PlatformUtil::getEnvironmentVariable(UnownedStringSlice("SLANG_RUN_SPIRV_VALIDATION"), runSpirvValEnvVar);
+ if (runSpirvValEnvVar.getUnownedSlice() == "1")
{
- codeGenContext->getSink()->diagnoseWithoutSourceView(
- SourceLoc{},
- Diagnostics::spirvValidationFailed
- );
- return validationResult;
+ const auto validationResult = debugValidateSPIRV(spirvOut);
+ // If validation isn't available, don't say it failed, it's just a debug
+ // feature so we can skip
+ if (SLANG_FAILED(validationResult) && validationResult != SLANG_E_NOT_AVAILABLE)
+ {
+ codeGenContext->getSink()->diagnoseWithoutSourceView(
+ SourceLoc{},
+ Diagnostics::spirvValidationFailed
+ );
+ return validationResult;
+ }
}
-
return SLANG_OK;
}
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 86136a010..57ca736e3 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -73,7 +73,6 @@
#include "slang-legalize-types.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
-#include "slang-spirv-opt.h"
#include "slang-syntax.h"
#include "slang-type-layout.h"
#include "slang-visitor.h"
@@ -931,8 +930,7 @@ Result linkAndOptimizeIR(
if (isKhronosTarget(targetRequest) && targetRequest->shouldEmitSPIRVDirectly())
{
- //performIntrinsicFunctionFunctionInlining(irModule);
- performSpirvInlining(irModule);
+ performIntrinsicFunctionFunctionInlining(irModule);
eliminateDeadCode(irModule);
}
eliminateMultiLevelBreak(irModule);
@@ -1289,10 +1287,36 @@ SlangResult emitSPIRVForEntryPointsDirectly(
spirv = _Move(outSpirv);
}
#endif
-
auto artifact = ArtifactUtil::createArtifactForCompileTarget(asExternal(codeGenContext->getTargetFormat()));
artifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));
+ IDownstreamCompiler* compiler = codeGenContext->getSession()->getOrLoadDownstreamCompiler(
+ PassThroughMode::SpirvOpt, codeGenContext->getSink());
+ if (compiler)
+ {
+ ComPtr<IArtifact> optimizedArtifact;
+ DownstreamCompileOptions downstreamOptions;
+ downstreamOptions.sourceArtifacts = makeSlice(artifact.readRef(), 1);
+ downstreamOptions.targetType = SLANG_SPIRV;
+ downstreamOptions.sourceLanguage = SLANG_SOURCE_LANGUAGE_SPIRV;
+ auto linkage = codeGenContext->getLinkage();
+ switch (linkage->optimizationLevel)
+ {
+ case OptimizationLevel::None: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::None; break;
+ case OptimizationLevel::Default: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::Default; break;
+ case OptimizationLevel::High: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::High; break;
+ case OptimizationLevel::Maximal: downstreamOptions.optimizationLevel = DownstreamCompileOptions::OptimizationLevel::Maximal; break;
+ default: SLANG_ASSERT(!"Unhandled optimization level"); break;
+ }
+
+ if (SLANG_SUCCEEDED(compiler->compile(downstreamOptions, optimizedArtifact.writeRef())))
+ {
+ artifact = _Move(optimizedArtifact);
+ }
+
+ SLANG_RETURN_ON_FAIL(passthroughDownstreamDiagnostics(codeGenContext->getSink(), compiler, artifact));
+ }
+
ArtifactUtil::addAssociated(artifact, linkedIR.metadata);
outArtifact.swap(artifact);
diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp
index 3b01d7dde..01dfdc42d 100644
--- a/source/slang/slang-ir-inline.cpp
+++ b/source/slang/slang-ir-inline.cpp
@@ -1019,33 +1019,4 @@ bool inlineCall(IRCall* call)
return pass.considerCallSite(call);
}
-
-struct SpirvInliningPass : InliningPassBase
-{
- typedef InliningPassBase Super;
-
- SpirvInliningPass(IRModule* module)
- : Super(module)
- {}
-
- bool shouldInline(CallSiteInfo const& info)
- {
- if (!info.callee->findDecoration<IREntryPointDecoration>())
- return true;
- return false;
- }
-};
-
-void performSpirvInlining(IRModule* module)
-{
- SLANG_PROFILE;
- while (true)
- {
- SpirvInliningPass pass(module);
- if (pass.considerAllCallSites())
- continue;
- break;
- }
-}
-
} // namespace Slang
diff --git a/source/slang/slang-ir-inline.h b/source/slang/slang-ir-inline.h
index 5e888ad07..539bb26c0 100644
--- a/source/slang/slang-ir-inline.h
+++ b/source/slang/slang-ir-inline.h
@@ -34,9 +34,6 @@ namespace Slang
/// Inline simple intrinsic functions whose definition is a single asm block.
void performIntrinsicFunctionFunctionInlining(IRModule* module);
- /// Inline all functions for SPIRV emit.
- void performSpirvInlining(IRModule* module);
-
/// Inline a specific call.
bool inlineCall(IRCall* call);
}
diff --git a/source/slang/slang-spirv-opt.cpp b/source/slang/slang-spirv-opt.cpp
deleted file mode 100644
index 786358324..000000000
--- a/source/slang/slang-spirv-opt.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "slang-spirv-opt.h"
-#include "slang-spirv-val.h"
-
-namespace Slang
-{
-
-struct RemoveFileRAII
-{
- String fileName;
-
- RemoveFileRAII(String inFileName)
- :fileName(inFileName)
- {}
-
- ~RemoveFileRAII()
- {
- File::remove(fileName);
- }
-};
-
-SlangResult optimizeSPIRV(const List<uint8_t>& spirv, String& outErr, List<uint8_t>& outSpv)
-{
- // Set up our process
- CommandLine commandLine;
- commandLine.m_executableLocation.setName("spirv-opt");
- commandLine.addArg("--eliminate-dead-functions");
- commandLine.addArg("--eliminate-local-single-block");
- commandLine.addArg("--eliminate-local-single-store");
- commandLine.addArg("--eliminate-dead-code-aggressive");
-
- commandLine.addArg("-o");
- String outFileName;
- File::generateTemporary(UnownedStringSlice("out_spv"), outFileName);
- RemoveFileRAII removeFile(outFileName);
-
- commandLine.addArg(outFileName);
-
- RefPtr<Process> p;
-
- // If we failed to even start the process, then spirv-opt isn't available
- SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, p));
- const auto in = p->getStream(StdStreamType::In);
- const auto out = p->getStream(StdStreamType::Out);
- const auto err = p->getStream(StdStreamType::ErrorOut);
-
- List<Byte> outErrData;
- SLANG_RETURN_ON_FAIL(StreamUtil::readAndWrite(in, spirv.getArrayView(), out, outSpv, err, outErrData));
-
- outSpv.clear();
- File::readAllBytes(outFileName, outSpv);
-
- SLANG_RETURN_ON_FAIL(p->waitForTermination(3600000));
-
- outErr = String(
- reinterpret_cast<const char*>(outErrData.begin()),
- reinterpret_cast<const char*>(outErrData.end())
- );
-
- const auto ret = p->getReturnValue();
- if (ret != 0)
- return SLANG_FAIL;
-
- return debugValidateSPIRV(outSpv);
-}
-
-}
diff --git a/source/slang/slang-spirv-opt.h b/source/slang/slang-spirv-opt.h
deleted file mode 100644
index c7dfde157..000000000
--- a/source/slang/slang-spirv-opt.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#include <cstdint>
-#include "slang-compiler.h"
-
-namespace Slang
-{
-SlangResult optimizeSPIRV(const List<uint8_t>& spirv, String& outErr, List<uint8_t>& outSpv);
-}
-