summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-09-10 16:31:26 -0400
committerGitHub <noreply@github.com>2021-09-10 13:31:26 -0700
commit27ce5eb0de9f792f3e433bcb239c07d79371cf45 (patch)
treebb85155ceafd280a3931432141fc1cc1dae20959 /source
parent28adf8917e53953dbfebd746410a427a55eed814 (diff)
First Slang LLVM integration (#1934)
* #include an absolute path didn't work - because paths were taken to always be relative. * First integration with 'slang-llvm'. * Fix project. * Fix test output. * First pass assert support. * Add inline impls for min and max. * Add abs inline abs impl for llvm. * Make abs not use ternary op * Fix typo in slang-llvm.h * Sundary fixes to make remaining tests using llvm backend pass.
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-downstream-compiler.cpp93
-rw-r--r--source/compiler-core/slang-downstream-compiler.h30
-rw-r--r--source/compiler-core/slang-llvm-compiler.cpp54
-rw-r--r--source/compiler-core/slang-llvm-compiler.h18
-rw-r--r--source/core/slang-type-text-util.cpp24
-rw-r--r--source/slang/slang-check.cpp8
-rw-r--r--source/slang/slang-compiler.cpp9
-rwxr-xr-xsource/slang/slang-compiler.h3
8 files changed, 203 insertions, 36 deletions
diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp
index 936c9402a..2a172eb3a 100644
--- a/source/compiler-core/slang-downstream-compiler.cpp
+++ b/source/compiler-core/slang-downstream-compiler.cpp
@@ -22,6 +22,7 @@
#include "slang-fxc-compiler.h"
#include "slang-dxc-compiler.h"
#include "slang-glslang-compiler.h"
+#include "slang-llvm-compiler.h"
namespace Slang
{
@@ -37,6 +38,7 @@ static DownstreamCompiler::Infos _calcInfos()
infos.infos[int(SLANG_PASS_THROUGH_CLANG)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
infos.infos[int(SLANG_PASS_THROUGH_VISUAL_STUDIO)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
infos.infos[int(SLANG_PASS_THROUGH_GCC)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
+ infos.infos[int(SLANG_PASS_THROUGH_LLVM)] = Info(SourceLanguageFlag::CPP | SourceLanguageFlag::C);
infos.infos[int(SLANG_PASS_THROUGH_NVRTC)] = Info(SourceLanguageFlag::CUDA);
@@ -199,6 +201,16 @@ SlangResult DownstreamCompiler::disassemble(SlangCompileTarget sourceBlobTarget,
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamDiagnostics !!!!!!!!!!!!!!!!!!!!!!*/
+Index DownstreamDiagnostics::getCountAtLeastSeverity(Diagnostic::Severity severity) const
+{
+ Index count = 0;
+ for (const auto& msg : diagnostics)
+ {
+ count += Index(Index(msg.severity) >= Index(severity));
+ }
+ return count;
+}
+
Index DownstreamDiagnostics::getCountBySeverity(Diagnostic::Severity severity) const
{
Index count = 0;
@@ -660,21 +672,43 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
return compiler;
}
- // If we are gcc, we can try clang and vice versa
- if (desc.type == SLANG_PASS_THROUGH_GCC || desc.type == SLANG_PASS_THROUGH_CLANG)
{
- DownstreamCompiler::Desc compatible = desc;
- compatible.type = (compatible.type == SLANG_PASS_THROUGH_CLANG) ? SLANG_PASS_THROUGH_GCC : SLANG_PASS_THROUGH_CLANG;
+ // These compilers should be usable interchangably. The order is important, as the first one that matches will
+ // be used, so LLVM is used before CLANG or GCC if appropriate
+ const SlangPassThrough compatiblePassThroughs[] =
+ {
+ SLANG_PASS_THROUGH_LLVM,
+ SLANG_PASS_THROUGH_CLANG,
+ SLANG_PASS_THROUGH_GCC,
+ };
- compiler = findCompiler(compilers, MatchType::MinGreaterEqual, compatible);
- if (compiler)
+ bool isCompatible = false;
+ for (auto passThrough : compatiblePassThroughs)
{
- return compiler;
+ if (desc.type == passThrough)
+ {
+ isCompatible = true;
+ break;
+ }
}
- compiler = findCompiler(compilers, MatchType::MinAbsolute, compatible);
- if (compiler)
+
+ if (isCompatible)
{
- return compiler;
+ for (auto passThrough : compatiblePassThroughs)
+ {
+ if (passThrough != desc.type)
+ {
+ DownstreamCompiler::Desc compatible;
+
+ compatible.type = passThrough;
+ // Find the latest version.
+ compiler = findCompiler(compilers, MatchType::Newest, compatible);
+ if (compiler)
+ {
+ return compiler;
+ }
+ }
+ }
}
}
@@ -702,7 +736,25 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
case SLANG_SOURCE_LANGUAGE_CPP:
case SLANG_SOURCE_LANGUAGE_C:
{
- compiler = findClosestCompiler(set, getCompiledWithDesc());
+
+#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)
+ {
+ compiler = findClosestCompiler(set, getCompiledWithDesc());
+ }
break;
}
case SLANG_SOURCE_LANGUAGE_CUDA:
@@ -735,6 +787,7 @@ const DownstreamCompiler::Desc& DownstreamCompilerUtil::getCompiledWithDesc()
outFuncs[int(SLANG_PASS_THROUGH_DXC)] = &DXCDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_FXC)] = &FXCDownstreamCompilerUtil::locateCompilers;
outFuncs[int(SLANG_PASS_THROUGH_GLSLANG)] = &GlslangDownstreamCompilerUtil::locateCompilers;
+ outFuncs[int(SLANG_PASS_THROUGH_LLVM)] = &LLVMDownstreamCompilerUtil::locateCompilers;
}
static String _getParentPath(const String& path)
@@ -892,6 +945,21 @@ void DownstreamCompilerSet::getCompilers(List<DownstreamCompiler*>& outCompilers
outCompilers.addRange((DownstreamCompiler*const*)m_compilers.begin(), m_compilers.getCount());
}
+bool DownstreamCompilerSet::hasSharedLibrary(ISlangSharedLibrary* lib)
+{
+ const Index foundIndex = m_sharedLibraries.findFirstIndex([lib](ISlangSharedLibrary* inLib) -> bool { return lib == inLib; });
+ return(foundIndex >= 0);
+}
+
+void DownstreamCompilerSet::addSharedLibrary(ISlangSharedLibrary* lib)
+{
+ SLANG_ASSERT(lib);
+ if (!hasSharedLibrary(lib))
+ {
+ m_sharedLibraries.add(ComPtr<ISlangSharedLibrary>(lib));
+ }
+}
+
bool DownstreamCompilerSet::hasCompiler(SlangPassThrough compilerType) const
{
for (DownstreamCompiler* compiler : m_compilers)
@@ -905,7 +973,6 @@ bool DownstreamCompilerSet::hasCompiler(SlangPassThrough compilerType) const
return false;
}
-
void DownstreamCompilerSet::remove(SlangPassThrough compilerType)
{
for (Index i = 0; i < m_compilers.getCount(); ++i)
@@ -932,6 +999,4 @@ void DownstreamCompilerSet::addCompiler(DownstreamCompiler* compiler)
}
}
-
-
}
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index 861960f10..ed932a5c9 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -82,6 +82,9 @@ struct DownstreamDiagnostics
/// Reset to an initial empty state
void reset() { diagnostics.clear(); rawDiagnostics = String(); result = SLANG_OK; }
+ /// Count the number of diagnostics which have 'severity' or greater
+ Index getCountAtLeastSeverity(Diagnostic::Severity severity) const;
+
/// Get the number of diagnostics by severity
Index getCountBySeverity(Diagnostic::Severity severity) const;
/// True if there are any diagnostics of severity
@@ -108,7 +111,7 @@ struct DownstreamDiagnostics
String rawDiagnostics;
- SlangResult result;
+ SlangResult result = SLANG_OK;
List<Diagnostic> diagnostics;
};
@@ -203,9 +206,9 @@ public:
/// Ctor
explicit Desc(SlangPassThrough inType = SLANG_PASS_THROUGH_NONE, Int inMajorVersion = 0, Int inMinorVersion = 0):type(inType), majorVersion(inMajorVersion), minorVersion(inMinorVersion) {}
- SlangPassThrough type; ///< The type of the compiler
- Int majorVersion; ///< Major version (interpretation is type specific)
- Int minorVersion; ///< Minor version
+ SlangPassThrough type; ///< The type of the compiler
+ Int majorVersion; ///< Major version (interpretation is type specific)
+ Int minorVersion; ///< Minor version (interpretation is type specific)
};
enum class OptimizationLevel
@@ -462,14 +465,33 @@ public:
void clear() { m_compilers.clear(); }
+ bool hasSharedLibrary(ISlangSharedLibrary* lib);
+ void addSharedLibrary(ISlangSharedLibrary* lib);
+
+ ~DownstreamCompilerSet()
+ {
+ // A compiler may be implemented in a shared library, so release all first.
+ m_compilers.clearAndDeallocate();
+ for (auto& defaultCompiler : m_defaultCompilers)
+ {
+ defaultCompiler.setNull();
+ }
+
+ // Release any shared libraries
+ m_sharedLibraries.clearAndDeallocate();
+ }
+
protected:
Index _findIndex(const DownstreamCompiler::Desc& desc) const;
+
RefPtr<DownstreamCompiler> m_defaultCompilers[int(SLANG_SOURCE_LANGUAGE_COUNT_OF)];
// This could be a dictionary/map - but doing a linear search is going to be fine and it makes
// somethings easier.
List<RefPtr<DownstreamCompiler>> m_compilers;
+
+ List<ComPtr<ISlangSharedLibrary>> m_sharedLibraries;
};
typedef SlangResult (*DownstreamCompilerLocatorFunc)(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
diff --git a/source/compiler-core/slang-llvm-compiler.cpp b/source/compiler-core/slang-llvm-compiler.cpp
new file mode 100644
index 000000000..9b301ffab
--- /dev/null
+++ b/source/compiler-core/slang-llvm-compiler.cpp
@@ -0,0 +1,54 @@
+// slang-llvm-compiler.cpp
+#include "slang-llvm-compiler.h"
+
+#include "../core/slang-common.h"
+#include "../../slang-com-helper.h"
+
+#include "../core/slang-blob.h"
+
+#include "../core/slang-string-util.h"
+#include "../core/slang-string-slice-pool.h"
+
+#include "../core/slang-io.h"
+#include "../core/slang-shared-library.h"
+#include "../core/slang-semantic-version.h"
+#include "../core/slang-char-util.h"
+
+#include "slang-include-system.h"
+#include "slang-source-loc.h"
+
+#include "../core/slang-shared-library.h"
+
+namespace Slang
+{
+
+/* static */SlangResult LLVMDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set)
+{
+ ComPtr<ISlangSharedLibrary> library;
+
+ SLANG_RETURN_ON_FAIL(DownstreamCompilerUtil::loadSharedLibrary(path, loader, nullptr, "slang-llvm", library));
+
+ SLANG_ASSERT(library);
+ if (!library)
+ {
+ return SLANG_FAIL;
+ }
+
+ typedef SlangResult(*CreateDownstreamCompilerFunc)(RefPtr<DownstreamCompiler>& out);
+
+ auto fn = (CreateDownstreamCompilerFunc)library->findFuncByName("createLLVMDownstreamCompiler");
+ if (!fn)
+ {
+ return SLANG_FAIL;
+ }
+
+ RefPtr<DownstreamCompiler> downstreamCompiler;
+
+ SLANG_RETURN_ON_FAIL(fn(downstreamCompiler));
+
+ set->addSharedLibrary(library);
+ set->addCompiler(downstreamCompiler);
+ return SLANG_OK;
+}
+
+}
diff --git a/source/compiler-core/slang-llvm-compiler.h b/source/compiler-core/slang-llvm-compiler.h
new file mode 100644
index 000000000..4044aef0f
--- /dev/null
+++ b/source/compiler-core/slang-llvm-compiler.h
@@ -0,0 +1,18 @@
+#ifndef SLANG_LLVM_COMPILER_UTIL_H
+#define SLANG_LLVM_COMPILER_UTIL_H
+
+#include "slang-downstream-compiler.h"
+
+#include "../core/slang-platform.h"
+
+namespace Slang
+{
+
+struct LLVMDownstreamCompilerUtil
+{
+ static SlangResult locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set);
+};
+
+}
+
+#endif
diff --git a/source/core/slang-type-text-util.cpp b/source/core/slang-type-text-util.cpp
index 89cd4504b..c67b6ec6e 100644
--- a/source/core/slang-type-text-util.cpp
+++ b/source/core/slang-type-text-util.cpp
@@ -27,7 +27,8 @@ namespace Slang
x(clang, CLANG) \
x(gcc, GCC) \
x(genericcpp, GENERIC_C_CPP) \
- x(nvrtc, NVRTC)
+ x(nvrtc, NVRTC) \
+ x(llvm, LLVM)
namespace { // anonymous
@@ -136,7 +137,8 @@ static const ArchiveTypeInfo s_archiveTypeInfos[] =
x(NVRTC, "NVRTC") \
x(FXC, "fxc") \
x(DXC, "dxc") \
- x(GLSLANG, "glslang")
+ x(GLSLANG, "glslang") \
+ x(LLVM, "LLVM/Clang")
/* static */UnownedStringSlice TypeTextUtil::getPassThroughAsHumanText(SlangPassThrough type)
{
@@ -192,15 +194,15 @@ static const ArchiveTypeInfo s_archiveTypeInfos[] =
SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_NAME_TO_TYPE)
- // Other options
- if (slice == "c" || slice == "cpp")
- {
- return SLANG_PASS_THROUGH_GENERIC_C_CPP;
- }
- else if (slice == "vs")
- {
- return SLANG_PASS_THROUGH_VISUAL_STUDIO;
- }
+ // Other options
+ if (slice == "c" || slice == "cpp")
+ {
+ return SLANG_PASS_THROUGH_GENERIC_C_CPP;
+ }
+ else if (slice == "vs")
+ {
+ return SLANG_PASS_THROUGH_VISUAL_STUDIO;
+ }
return SLANG_PASS_THROUGH_NONE;
}
diff --git a/source/slang/slang-check.cpp b/source/slang/slang-check.cpp
index 55306a0da..74e30cf8d 100644
--- a/source/slang/slang-check.cpp
+++ b/source/slang/slang-check.cpp
@@ -12,12 +12,7 @@
namespace Slang
{
namespace { // anonymous
- struct FunctionInfo
- {
- const char* name;
- PassThroughMode compilerType;
- };
-
+
class SinkSharedLibraryLoader : public RefObject, public ISlangSharedLibraryLoader
{
public:
@@ -101,6 +96,7 @@ namespace Slang
getOrLoadDownstreamCompiler(PassThroughMode::Clang, sink);
getOrLoadDownstreamCompiler(PassThroughMode::Gcc, sink);
getOrLoadDownstreamCompiler(PassThroughMode::VisualStudio, sink);
+ getOrLoadDownstreamCompiler(PassThroughMode::LLVM, sink);
}
// Mark that we have tried to load it
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 513f9623d..9f10876a0 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -480,6 +480,7 @@ namespace Slang
{
return SourceLanguage::GLSL;
}
+ case PassThroughMode::LLVM:
case PassThroughMode::Clang:
case PassThroughMode::VisualStudio:
case PassThroughMode::Gcc:
@@ -493,6 +494,7 @@ namespace Slang
{
return SourceLanguage::CUDA;
}
+
default: break;
}
SLANG_ASSERT(!"Unknown compiler");
@@ -1791,6 +1793,13 @@ namespace Slang
ComPtr<ISlangBlob> blob;
if (SLANG_FAILED(result.getBlob(blob)))
{
+ if (targetReq->getTarget() == CodeGenTarget::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;
+ }
+
SLANG_UNEXPECTED("No blob to emit");
return;
}
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 4ed30ed28..a7903dd5a 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -979,7 +979,8 @@ namespace Slang
VisualStudio = SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio compiler
Gcc = SLANG_PASS_THROUGH_GCC, ///< Gcc compiler
GenericCCpp = SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C/C++ compiler
- NVRTC = SLANG_PASS_THROUGH_NVRTC,
+ NVRTC = SLANG_PASS_THROUGH_NVRTC, ///< NVRTC CUDA compiler
+ LLVM = SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler'
CountOf = SLANG_PASS_THROUGH_COUNT_OF,
};
void printDiagnosticArg(StringBuilder& sb, PassThroughMode val);