summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-10-20 10:32:50 -0400
committerGitHub <noreply@github.com>2021-10-20 10:32:50 -0400
commitdeb638f446863ab38248a9568553a1eab47ca086 (patch)
tree5a37ac31dce2b15b5079f8f67b268d7ef652e939 /source
parent8406244e27c142ea56c7a934b09e0b1cdace6afd (diff)
Selecting downstream compiler on code gen transition (#1980)
* #include an absolute path didn't work - because paths were taken to always be relative. * Add support for LLVM for host callable. Added CodeGenTransitionMap. * Remove hack to enable host callable for LLVM. * Small improvements around transitions/downstream compiler. * Fix typo in method name. * Fix comment.
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-downstream-compiler.cpp28
-rw-r--r--source/compiler-core/slang-downstream-compiler.h4
-rw-r--r--source/core/slang-type-convert-util.cpp41
-rw-r--r--source/core/slang-type-convert-util.h21
-rw-r--r--source/slang/slang-compiler.cpp151
-rwxr-xr-xsource/slang/slang-compiler.h51
-rw-r--r--source/slang/slang-diagnostic-defs.h8
-rw-r--r--source/slang/slang.cpp98
8 files changed, 278 insertions, 124 deletions
diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp
index 9312554ae..daf31c9eb 100644
--- a/source/compiler-core/slang-downstream-compiler.cpp
+++ b/source/compiler-core/slang-downstream-compiler.cpp
@@ -185,20 +185,6 @@ SlangResult DownstreamCompiler::disassemble(SlangCompileTarget sourceBlobTarget,
return (info.sourceLanguageFlags & (SourceLanguageFlags(1) << int(sourceLanguage))) != 0;
}
-/* static */SlangCompileTarget DownstreamCompiler::getCompileTarget(SlangSourceLanguage sourceLanguage)
-{
- switch (sourceLanguage)
- {
- case SLANG_SOURCE_LANGUAGE_HLSL: return SLANG_HLSL;
- case SLANG_SOURCE_LANGUAGE_GLSL: return SLANG_GLSL;
- case SLANG_SOURCE_LANGUAGE_C: return SLANG_C_SOURCE;
- case SLANG_SOURCE_LANGUAGE_CPP: return SLANG_CPP_SOURCE;
- case SLANG_SOURCE_LANGUAGE_CUDA: return SLANG_CUDA_SOURCE;
-
- default: return SLANG_TARGET_UNKNOWN;
- }
-}
-
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamDiagnostics !!!!!!!!!!!!!!!!!!!!!!*/
Index DownstreamDiagnostics::getCountAtLeastSeverity(Diagnostic::Severity severity) const
@@ -719,20 +705,6 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
case SLANG_SOURCE_LANGUAGE_CPP:
case SLANG_SOURCE_LANGUAGE_C:
{
-
-#if 0
- // TODO(JS): We can't just enable this because we can currently only use slang-llvm, if we want to 'host-callable'
- // It *can't* handle pass through (the includes are not available with just the dll),
- // As it stands it doesn't support ext/obj/shared library output
-
- // If we have LLVM, lets use that as the default
- {
- DownstreamCompiler::Desc desc;
- desc.type = SLANG_PASS_THROUGH_LLVM;
- compiler = findCompiler(set, MatchType::Newest, desc);
- }
-#endif
-
// Find the compiler closest to the compiler this was compiled with
if (!compiler)
{
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index 1e6571e0f..58b7c5be0 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -360,9 +360,7 @@ public:
/// True if this compiler can compile the specified language
static bool canCompile(SlangPassThrough compiler, SlangSourceLanguage sourceLanguage);
- /// Given a source language return as the equivalent compile target
- static SlangCompileTarget getCompileTarget(SlangSourceLanguage sourceLanguage);
-
+
protected:
static Infos s_infos;
diff --git a/source/core/slang-type-convert-util.cpp b/source/core/slang-type-convert-util.cpp
new file mode 100644
index 000000000..fbf385319
--- /dev/null
+++ b/source/core/slang-type-convert-util.cpp
@@ -0,0 +1,41 @@
+
+#include "slang-type-convert-util.h"
+
+namespace Slang
+{
+
+/* static */SlangSourceLanguage TypeConvertUtil::getSourceLanguageFromTarget(SlangCompileTarget target)
+{
+ switch (target)
+ {
+ case SLANG_GLSL:
+ case SLANG_GLSL_VULKAN:
+ case SLANG_GLSL_VULKAN_ONE_DESC:
+ {
+ return SLANG_SOURCE_LANGUAGE_GLSL;
+ }
+ case SLANG_HLSL: return SLANG_SOURCE_LANGUAGE_HLSL;
+ case SLANG_C_SOURCE: return SLANG_SOURCE_LANGUAGE_C;
+ case SLANG_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP;
+ case SLANG_CUDA_SOURCE: return SLANG_SOURCE_LANGUAGE_CUDA;
+ default: break;
+ }
+ return SLANG_SOURCE_LANGUAGE_UNKNOWN;
+}
+
+/* static */SlangCompileTarget TypeConvertUtil::getCompileTargetFromSourceLanguage(SlangSourceLanguage lang)
+{
+ switch (lang)
+ {
+ case SLANG_SOURCE_LANGUAGE_GLSL: return SLANG_GLSL;
+ case SLANG_SOURCE_LANGUAGE_HLSL: return SLANG_HLSL;
+ case SLANG_SOURCE_LANGUAGE_C: return SLANG_C_SOURCE;
+ case SLANG_SOURCE_LANGUAGE_CPP: return SLANG_CPP_SOURCE;
+ case SLANG_SOURCE_LANGUAGE_CUDA: return SLANG_CUDA_SOURCE;
+ }
+
+ return SLANG_TARGET_UNKNOWN;
+}
+
+}
+
diff --git a/source/core/slang-type-convert-util.h b/source/core/slang-type-convert-util.h
new file mode 100644
index 000000000..00b47a154
--- /dev/null
+++ b/source/core/slang-type-convert-util.h
@@ -0,0 +1,21 @@
+#ifndef SLANG_CORE_TYPE_CONVERT_UTIL_H
+#define SLANG_CORE_TYPE_CONVERT_UTIL_H
+
+#include "../../slang.h"
+
+namespace Slang
+{
+
+/// Utility class for simple conversions between types
+struct TypeConvertUtil
+{
+ /// Convert a target into it's equivalent language if ones available. If not returns SOURCE_LANGUAGE_UNKNOWN
+ static SlangSourceLanguage getSourceLanguageFromTarget(SlangCompileTarget target);
+
+ /// Convert a language into the equivalent target. If not available returns SLANG_TARGET_UNKNOWN
+ static SlangCompileTarget getCompileTargetFromSourceLanguage(SlangSourceLanguage lang);
+};
+
+}
+
+#endif // SLANG_CORE_TYPE_TEXT_UTIL_H
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index a73289852..c1a768f02 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -7,6 +7,7 @@
#include "../core/slang-hex-dump-util.h"
#include "../core/slang-riff.h"
#include "../core/slang-type-text-util.h"
+#include "../core/slang-type-convert-util.h"
#include "slang-check.h"
#include "slang-compiler.h"
@@ -575,9 +576,7 @@ namespace Slang
// And if pass-through isn't set, we don't need
// access to the translation unit.
- //
- if(endToEndReq->m_passThrough == PassThroughMode::None) return false;
- return true;
+ return endToEndReq->m_passThrough != PassThroughMode::None;
}
/// If there is a pass-through compile going on, find the translation unit for the given entry point.
/// Assumes isPassThroughEnabled has already been called
@@ -962,6 +961,26 @@ namespace Slang
}
}
+ static CodeGenTarget _getDefaultSourceForTarget(CodeGenTarget target)
+ {
+ switch (target)
+ {
+ case CodeGenTarget::HostCallable:
+ case CodeGenTarget::SharedLibrary:
+ case CodeGenTarget::Executable:
+ {
+ return CodeGenTarget::CPPSource;
+ }
+ case CodeGenTarget::PTX: return CodeGenTarget::CUDASource;
+ case CodeGenTarget::DXBytecode: return CodeGenTarget::HLSL;
+ case CodeGenTarget::DXIL: return CodeGenTarget::HLSL;
+ case CodeGenTarget::SPIRV: return CodeGenTarget::GLSL;
+ default: break;
+ }
+ return CodeGenTarget::Unknown;
+ }
+
+
SlangResult emitWithDownstreamForEntryPoints(
ComponentType* program,
BackEndCompileRequest* slangRequest,
@@ -977,80 +996,37 @@ namespace Slang
auto session = slangRequest->getSession();
+
CodeGenTarget sourceTarget = CodeGenTarget::None;
SourceLanguage sourceLanguage = SourceLanguage::Unknown;
- PassThroughMode downstreamCompiler = endToEndReq ? endToEndReq->m_passThrough : PassThroughMode::None;
-
RefPtr<ExtensionTracker> extensionTracker = _newExtensionTracker(target);
+ PassThroughMode compilerType = endToEndReq ? endToEndReq->m_passThrough : PassThroughMode::None;
// If we are not in pass through, lookup the default compiler for the emitted source type
- if (downstreamCompiler == PassThroughMode::None)
+ if (compilerType == PassThroughMode::None)
{
- switch (target)
+ // Get the default source codegen type for a given target
+ sourceTarget = _getDefaultSourceForTarget(target);
+ compilerType = (PassThroughMode)session->getDownstreamCompilerForTransition((SlangCompileTarget)sourceTarget, (SlangCompileTarget)target);
+ // We should have a downstream compiler set at this point
+ if (compilerType == PassThroughMode::None)
{
- case CodeGenTarget::HostCallable:
- case CodeGenTarget::SharedLibrary:
- case CodeGenTarget::Executable:
- {
- sourceTarget = CodeGenTarget::CPPSource;
- sourceLanguage = SourceLanguage::CPP;
- break;
- }
- case CodeGenTarget::PTX:
- {
- sourceTarget = CodeGenTarget::CUDASource;
- sourceLanguage = SourceLanguage::CUDA;
- break;
- }
- case CodeGenTarget::DXBytecode:
- {
- sourceTarget = CodeGenTarget::HLSL;
- sourceLanguage = SourceLanguage::HLSL;
- downstreamCompiler = PassThroughMode::Fxc;
- break;
- }
- case CodeGenTarget::DXIL:
- {
- sourceTarget = CodeGenTarget::HLSL;
- sourceLanguage = SourceLanguage::HLSL;
- downstreamCompiler = PassThroughMode::Dxc;
- break;
- }
- case CodeGenTarget::SPIRV:
- {
- sourceTarget = CodeGenTarget::GLSL;
- sourceLanguage = SourceLanguage::GLSL;
- downstreamCompiler = PassThroughMode::Glslang;
- break;
- }
- default: break;
- }
+ auto sourceName = TypeTextUtil::getCompileTargetName(SlangCompileTarget(sourceTarget));
+ auto targetName = TypeTextUtil::getCompileTargetName(SlangCompileTarget(target));
- // Try looking up based on the language if one isn't set
- if (downstreamCompiler == PassThroughMode::None)
- {
- downstreamCompiler = PassThroughMode(session->getDefaultDownstreamCompiler(SlangSourceLanguage(sourceLanguage)));
- }
- }
- else
- {
- // If we are pass through, we may need to set extension tracker state.
- if (GLSLExtensionTracker* glslTracker = as<GLSLExtensionTracker>(extensionTracker))
- {
- trackGLSLTargetCaps(glslTracker, targetReq->getTargetCaps());
+ sink->diagnose(SourceLoc(), Diagnostics::compilerNotDefinedForTransition, sourceName, targetName);
+ return SLANG_FAIL;
}
}
-
- // We should have a downstream compiler set at this point
- SLANG_ASSERT(downstreamCompiler != PassThroughMode::None);
+
+ SLANG_ASSERT(compilerType != PassThroughMode::None);
// Get the required downstream compiler
- DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(downstreamCompiler, sink);
-
+ DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(compilerType, sink);
if (!compiler)
{
- auto compilerName = TypeTextUtil::getPassThroughAsHumanText((SlangPassThrough)downstreamCompiler);
+ auto compilerName = TypeTextUtil::getPassThroughAsHumanText((SlangPassThrough)compilerType);
sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName);
return SLANG_FAIL;
}
@@ -1061,13 +1037,11 @@ namespace Slang
typedef DownstreamCompiler::CompileOptions CompileOptions;
CompileOptions options;
- /* Let's set the compiler specific options
-
- We can only do this if the endToEndReq is set. */
+ // Set compiler specific args
{
auto linkage = targetReq->getLinkage();
- auto name = TypeTextUtil::getPassThroughName((SlangPassThrough)downstreamCompiler);
+ auto name = TypeTextUtil::getPassThroughName((SlangPassThrough)compilerType);
const Index nameIndex = linkage->m_downstreamArgs.findName(name);
if (nameIndex >= 0)
{
@@ -1079,15 +1053,30 @@ namespace Slang
}
}
-
/* 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 */
if (isPassThroughEnabled(endToEndReq))
{
+ // If we are pass through, we may need to set extension tracker state.
+ if (GLSLExtensionTracker* glslTracker = as<GLSLExtensionTracker>(extensionTracker))
+ {
+ trackGLSLTargetCaps(glslTracker, targetReq->getTargetCaps());
+ }
+
// TODO(DG): Review this assertion later
SLANG_ASSERT(entryPointIndices.getCount() == 1);
auto translationUnit = getPassThroughTranslationUnit(endToEndReq, entryPointIndices[0]);
+
+ // We are just passing thru, so it's whatever it originally was
+ sourceLanguage = translationUnit->sourceLanguage;
+
+ // TODO(JS): This seems like a bit of a hack
+ // That if a pass-through is being performed and the source language is Slang
+ // no downstream compiler knows how to deal with that, so probably means 'HLSL'
+ sourceLanguage = (sourceLanguage == SourceLanguage::Slang) ? SourceLanguage::HLSL : sourceLanguage;
+ sourceTarget = CodeGenTarget(TypeConvertUtil::getCompileTargetFromSourceLanguage((SlangSourceLanguage)sourceLanguage));
+
// If it's pass through we accumulate the preprocessor definitions.
for (auto& define : translationUnit->compileRequest->preprocessorDefinitions)
{
@@ -1130,18 +1119,6 @@ namespace Slang
}
}
- // We are just passing thru, so it's whatever it originally was
- sourceLanguage = translationUnit->sourceLanguage;
-
- // TODO(JS): This seems like a bit of a hack
- // That if a pass-through is being performed and the source language is Slang
- // no downstream compiler knows how to deal with that, so probably means 'HLSL'
- if (sourceLanguage == SourceLanguage::Slang)
- {
- sourceLanguage = SourceLanguage::HLSL;
- }
-
- sourceTarget = CodeGenTarget(DownstreamCompiler::getCompileTarget(SlangSourceLanguage(sourceLanguage)));
// If emitted source is required, emit and set the path
if (_useEmittedSource(compiler, translationUnit))
@@ -1167,6 +1144,8 @@ namespace Slang
{
SLANG_RETURN_ON_FAIL(emitEntryPointsSource(slangRequest, entryPointIndices, targetReq, sourceTarget, endToEndReq, extensionTracker, options.sourceContents));
maybeDumpIntermediate(slangRequest, options.sourceContents.getBuffer(), sourceTarget);
+
+ sourceLanguage = (SourceLanguage)TypeConvertUtil::getSourceLanguageFromTarget((SlangCompileTarget)sourceTarget);
}
// If we have an extension tracker, we may need to set options such as SPIR-V version
@@ -1212,9 +1191,9 @@ namespace Slang
// Disable exceptions and security checks
options.flags &= ~(CompileOptions::Flag::EnableExceptionHandling | CompileOptions::Flag::EnableSecurityChecks);
- if (downstreamCompiler == PassThroughMode::Fxc ||
- downstreamCompiler == PassThroughMode::Dxc ||
- downstreamCompiler == PassThroughMode::Glslang)
+ if (compilerType == PassThroughMode::Fxc ||
+ compilerType == PassThroughMode::Dxc ||
+ compilerType == PassThroughMode::Glslang)
{
if (entryPointIndices.getCount() != 1)
{
@@ -1233,7 +1212,7 @@ namespace Slang
// Set the entry point name
options.entryPointName = getText(entryPoint->getName());
- if (downstreamCompiler == PassThroughMode::Dxc)
+ if (compilerType == PassThroughMode::Dxc)
{
// We will enable the flag to generate proper code for 16 - bit types
// by default, as long as the user is requesting a sufficiently
@@ -1260,15 +1239,15 @@ namespace Slang
// Set the matrix layout
options.matrixLayout = targetReq->getDefaultMatrixLayoutMode();
}
- else if (downstreamCompiler == PassThroughMode::Fxc)
+ else if (compilerType == PassThroughMode::Fxc)
{
// Set the profile
options.profileName = GetHLSLProfileName(profile);
}
}
- // For host callable we want downstream compile to produce a shared library
- if (target == CodeGenTarget::HostCallable)
+ // If we aren't using LLVM 'host callable', we want downstream compile to produce a shared library
+ if (compilerType != PassThroughMode::LLVM && target == CodeGenTarget::HostCallable)
{
target = CodeGenTarget::SharedLibrary;
}
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 46f16f0d5..9677c4fbe 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -2363,6 +2363,45 @@ namespace Slang
static const BaseTypeInfo s_info[Index(BaseType::CountOf)];
};
+ class CodeGenTransitionMap
+ {
+ public:
+ struct Pair
+ {
+ typedef Pair ThisType;
+ SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const { return source == rhs.source && target == rhs.target; }
+ SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
+ SLANG_FORCE_INLINE HashCode getHashCode() const { return combineHash(HashCode(source), HashCode(target)); }
+
+ CodeGenTarget source;
+ CodeGenTarget target;
+ };
+
+ void removeTransition(CodeGenTarget source, CodeGenTarget target)
+ {
+ m_map.Remove(Pair{ source, target });
+ }
+ void addTransition(CodeGenTarget source, CodeGenTarget target, PassThroughMode compiler)
+ {
+ SLANG_ASSERT(source != target);
+ m_map.Add(Pair{ source, target }, compiler);
+ }
+ bool hasTransition(CodeGenTarget source, CodeGenTarget target) const
+ {
+ return m_map.ContainsKey(Pair{ source, target });
+ }
+ PassThroughMode getTransition(CodeGenTarget source, CodeGenTarget target) const
+ {
+ const Pair pair{ source, target };
+ auto value = m_map.TryGetValue(pair);
+ return value ? *value : PassThroughMode::None;
+ }
+
+ protected:
+ Dictionary<Pair, PassThroughMode> m_map;
+ };
+
class Session : public RefObject, public slang::IGlobalSession
{
public:
@@ -2397,9 +2436,12 @@ namespace Slang
SLANG_NO_THROW SlangCapabilityID SLANG_MCALL findCapability(char const* name) override;
- /// Get the default compiler for a language
- DownstreamCompiler* getDefaultDownstreamCompiler(SourceLanguage sourceLanguage);
+ SLANG_NO_THROW void SLANG_MCALL setDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler) override;
+ SLANG_NO_THROW SlangPassThrough SLANG_MCALL getDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target) override;
+ /// Get the downstream compiler for a transition
+ DownstreamCompiler* getDownstreamCompiler(CodeGenTarget source, CodeGenTarget target);
+
Scope* baseLanguageScope = nullptr;
Scope* coreLanguageScope = nullptr;
Scope* hlslLanguageScope = nullptr;
@@ -2477,6 +2519,8 @@ namespace Slang
private:
+ void _initCodeGenTransitionMap();
+
SlangResult _readBuiltinModule(ISlangFileSystem* fileSystem, Scope* scope, String moduleName);
SlangResult _loadRequest(EndToEndCompileRequest* request, const void* data, size_t size);
@@ -2487,6 +2531,9 @@ namespace Slang
String m_downstreamCompilerPaths[int(PassThroughMode::CountOf)]; ///< Paths for each pass through
String m_languagePreludes[int(SourceLanguage::CountOf)]; ///< Prelude for each source language
PassThroughMode m_defaultDownstreamCompilers[int(SourceLanguage::CountOf)];
+
+ // Describes a conversion from one code gen target (source) to another (target)
+ CodeGenTransitionMap m_codeGenTransitionMap;
};
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index b1f1bbaef..2add5792b 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -549,10 +549,12 @@ DIAGNOSTIC(52000, Error, multiLevelBreakUnsupported, "control flow appears to re
DIAGNOSTIC(52001, Warning, dxilNotFound, "dxil shared library not found, so 'dxc' output cannot be signed! Shader code will not be runnable in non-development environments.")
-DIAGNOSTIC(52002, Error, passThroughCompilerNotFound, "Could not find a suitable pass-through compiler for '$0'.")
+DIAGNOSTIC(52002, Error, passThroughCompilerNotFound, "could not find a suitable pass-through compiler for '$0'.")
-DIAGNOSTIC(52004, Error, unableToWriteFile, "Unable to write file '$0'")
-DIAGNOSTIC(52005, Error, unableToReadFile, "Unable to read file '$0'")
+DIAGNOSTIC(52004, Error, unableToWriteFile, "unable to write file '$0'")
+DIAGNOSTIC(52005, Error, unableToReadFile, "unable to read file '$0'")
+
+DIAGNOSTIC(52006, Error, compilerNotDefinedForTransition, "compiler not defined for transition '$0' to '$1'.")
//
// 8xxxx - Issues specific to a particular library/technology/platform/etc.
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 78f7c7c51..ccc1404f1 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -5,6 +5,7 @@
#include "../core/slang-shared-library.h"
#include "../core/slang-archive-file-system.h"
#include "../core/slang-type-text-util.h"
+#include "../core/slang-type-convert-util.h"
#include "slang-check.h"
#include "slang-parameter-binding.h"
@@ -119,6 +120,8 @@ void Session::init()
{
SLANG_ASSERT(BaseTypeInfo::check());
+ _initCodeGenTransitionMap();
+
::memset(m_downstreamCompilerLocators, 0, sizeof(m_downstreamCompilerLocators));
DownstreamCompilerUtil::setDefaultLocators(m_downstreamCompilerLocators);
m_downstreamCompilerSet = new DownstreamCompilerSet;
@@ -191,6 +194,46 @@ void Session::init()
m_languagePreludes[Index(SourceLanguage::HLSL)] = get_slang_hlsl_prelude();
}
+void Session::_initCodeGenTransitionMap()
+{
+ // TODO(JS): Might want to do something about these in the future...
+
+ //PassThroughMode getDownstreamCompilerRequiredForTarget(CodeGenTarget target);
+ //SourceLanguage getDefaultSourceLanguageForDownstreamCompiler(PassThroughMode compiler);
+
+ // Set up the default ways to do compilations between code gen targets
+ auto& map = m_codeGenTransitionMap;
+
+ // TODO(JS): There currently isn't a 'downstream compiler' for direct spirv output. If we did
+ // it would presumably a transition from SlangIR to SPIRV.
+
+ // For C and C++ we default to use the 'genericCCpp' compiler
+ {
+ const CodeGenTarget sources[] = { CodeGenTarget::CSource, CodeGenTarget::CPPSource };
+ for (auto source : sources)
+ {
+ // We *don't* add a default for host callable, as we will determine what is suitable depending on what
+ // is available. We prefer LLVM if that's available. If it's not we can use generic C/C++ compiler
+
+ map.addTransition(source, CodeGenTarget::SharedLibrary, PassThroughMode::GenericCCpp);
+ map.addTransition(source, CodeGenTarget::Executable, PassThroughMode::GenericCCpp);
+ map.addTransition(source, CodeGenTarget::ObjectCode, PassThroughMode::GenericCCpp);
+ }
+ }
+
+
+ // Add all the straightforward transitions
+ map.addTransition(CodeGenTarget::CUDASource, CodeGenTarget::PTX, PassThroughMode::NVRTC);
+ map.addTransition(CodeGenTarget::HLSL, CodeGenTarget::DXBytecode, PassThroughMode::Fxc);
+ map.addTransition(CodeGenTarget::HLSL, CodeGenTarget::DXIL, PassThroughMode::Dxc);
+ map.addTransition(CodeGenTarget::GLSL, CodeGenTarget::SPIRV, PassThroughMode::Glslang);
+
+ // To assembly
+ map.addTransition(CodeGenTarget::SPIRV, CodeGenTarget::SPIRVAssembly, PassThroughMode::Glslang);
+ map.addTransition(CodeGenTarget::DXIL, CodeGenTarget::DXILAssembly, PassThroughMode::Dxc);
+ map.addTransition(CodeGenTarget::DXBytecode, CodeGenTarget::DXBytecodeAssembly, PassThroughMode::Fxc);
+}
+
void Session::addBuiltins(
char const* sourcePath,
char const* sourceString)
@@ -599,9 +642,60 @@ SlangPassThrough SLANG_MCALL Session::getDefaultDownstreamCompiler(SlangSourceLa
return SlangPassThrough(m_defaultDownstreamCompilers[int(sourceLanguage)]);
}
-DownstreamCompiler* Session::getDefaultDownstreamCompiler(SourceLanguage sourceLanguage)
+void Session::setDownstreamCompilerForTransition(SlangCompileTarget source, SlangCompileTarget target, SlangPassThrough compiler)
+{
+ if (compiler == SLANG_PASS_THROUGH_NONE)
+ {
+ // Removing the transition means a default can be used
+ m_codeGenTransitionMap.removeTransition(CodeGenTarget(source), CodeGenTarget(target));
+ }
+ else
+ {
+ m_codeGenTransitionMap.addTransition(CodeGenTarget(source), CodeGenTarget(target), PassThroughMode(compiler));
+ }
+}
+
+SlangPassThrough Session::getDownstreamCompilerForTransition(SlangCompileTarget inSource, SlangCompileTarget inTarget)
+{
+ const CodeGenTarget source = CodeGenTarget(inSource);
+ const CodeGenTarget target = CodeGenTarget(inTarget);
+
+ if (m_codeGenTransitionMap.hasTransition(source, target))
+ {
+ return (SlangPassThrough)m_codeGenTransitionMap.getTransition(source, target);
+ }
+
+ // Special case host-callable
+ if (target == CodeGenTarget::HostCallable)
+ {
+ if (source == CodeGenTarget::CSource || source == CodeGenTarget::CPPSource)
+ {
+ // We prefer LLVM if it's available
+ DownstreamCompiler* llvm = getOrLoadDownstreamCompiler(PassThroughMode::LLVM, nullptr);
+ if (llvm)
+ {
+ return SLANG_PASS_THROUGH_LLVM;
+ }
+ }
+ }
+
+ // Use the legacy 'sourceLanguage' default mechanism.
+ // This says nothing about the target type, so it is *assumed* the target type is possible
+ // If not it will fail when trying to compile to an unknown target
+ const SourceLanguage sourceLanguage = (SourceLanguage)TypeConvertUtil::getSourceLanguageFromTarget(inSource);
+ if (sourceLanguage != SourceLanguage::Unknown)
+ {
+ return getDefaultDownstreamCompiler(SlangSourceLanguage(sourceLanguage));
+ }
+
+ // Unknwon
+ return SLANG_PASS_THROUGH_NONE;
+}
+
+DownstreamCompiler* Session::getDownstreamCompiler(CodeGenTarget source, CodeGenTarget target)
{
- return getOrLoadDownstreamCompiler(m_defaultDownstreamCompilers[int(sourceLanguage)], nullptr);
+ PassThroughMode compilerType = (PassThroughMode)getDownstreamCompilerForTransition(SlangCompileTarget(source), SlangCompileTarget(target));
+ return getOrLoadDownstreamCompiler(compilerType, nullptr);
}
Profile getEffectiveProfile(EntryPoint* entryPoint, TargetRequest* target)