summaryrefslogtreecommitdiffstats
path: root/source/slang/slang.cpp
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/slang/slang.cpp
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/slang/slang.cpp')
-rw-r--r--source/slang/slang.cpp98
1 files changed, 96 insertions, 2 deletions
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)