diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-09-10 16:31:26 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-10 13:31:26 -0700 |
| commit | 27ce5eb0de9f792f3e433bcb239c07d79371cf45 (patch) | |
| tree | bb85155ceafd280a3931432141fc1cc1dae20959 /source | |
| parent | 28adf8917e53953dbfebd746410a427a55eed814 (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.cpp | 93 | ||||
| -rw-r--r-- | source/compiler-core/slang-downstream-compiler.h | 30 | ||||
| -rw-r--r-- | source/compiler-core/slang-llvm-compiler.cpp | 54 | ||||
| -rw-r--r-- | source/compiler-core/slang-llvm-compiler.h | 18 | ||||
| -rw-r--r-- | source/core/slang-type-text-util.cpp | 24 | ||||
| -rw-r--r-- | source/slang/slang-check.cpp | 8 | ||||
| -rw-r--r-- | source/slang/slang-compiler.cpp | 9 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 3 |
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); |
