summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj2
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj.filters6
-rw-r--r--build/visual-studio/run-generators/run-generators.vcxproj1
-rw-r--r--build/visual-studio/run-generators/run-generators.vcxproj.filters3
-rw-r--r--prelude/slang-cpp-prelude.h31
-rw-r--r--prelude/slang-cpp-scalar-intrinsics.h186
-rw-r--r--prelude/slang-cpp-types.h2
-rw-r--r--prelude/slang-llvm.h393
-rw-r--r--slang.h1
-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
-rw-r--r--tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected2
-rw-r--r--tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang2
-rw-r--r--tools/slang-test/slang-test-main.cpp46
-rw-r--r--tools/slang-test/test-context.h3
21 files changed, 805 insertions, 112 deletions
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj b/build/visual-studio/compiler-core/compiler-core.vcxproj
index 339bc73d1..86dec62fc 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj
@@ -186,6 +186,7 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-json-value.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-lexer-diagnostic-defs.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-lexer.h" />
+ <ClInclude Include="..\..\..\source\compiler-core\slang-llvm-compiler.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-misc-diagnostic-defs.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-name-convention-util.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-name.h" />
@@ -211,6 +212,7 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-json-parser.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-json-value.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-lexer.cpp" />
+ <ClCompile Include="..\..\..\source\compiler-core\slang-llvm-compiler.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-name-convention-util.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-name.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-nvrtc-compiler.cpp" />
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
index da0ca5d63..d68b6e630 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
@@ -57,6 +57,9 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-lexer.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\compiler-core\slang-llvm-compiler.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\compiler-core\slang-misc-diagnostic-defs.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -128,6 +131,9 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-lexer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\compiler-core\slang-llvm-compiler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\compiler-core\slang-name-convention-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/build/visual-studio/run-generators/run-generators.vcxproj b/build/visual-studio/run-generators/run-generators.vcxproj
index 2819cc616..98f121f9f 100644
--- a/build/visual-studio/run-generators/run-generators.vcxproj
+++ b/build/visual-studio/run-generators/run-generators.vcxproj
@@ -156,6 +156,7 @@
<ItemGroup>
<ClInclude Include="..\..\..\prelude\slang-cpp-scalar-intrinsics.h" />
<ClInclude Include="..\..\..\prelude\slang-cpp-types.h" />
+ <ClInclude Include="..\..\..\prelude\slang-llvm.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\source\core\slang-string.cpp" />
diff --git a/build/visual-studio/run-generators/run-generators.vcxproj.filters b/build/visual-studio/run-generators/run-generators.vcxproj.filters
index 17a7477ed..c535b0a02 100644
--- a/build/visual-studio/run-generators/run-generators.vcxproj.filters
+++ b/build/visual-studio/run-generators/run-generators.vcxproj.filters
@@ -15,6 +15,9 @@
<ClInclude Include="..\..\..\prelude\slang-cpp-types.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\prelude\slang-llvm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\source\core\slang-string.cpp">
diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h
index ffd18cf32..76ff16590 100644
--- a/prelude/slang-cpp-prelude.h
+++ b/prelude/slang-cpp-prelude.h
@@ -5,17 +5,22 @@
// to use the version in the std namespace.
// https://stackoverflow.com/questions/39130040/cmath-hides-isnan-in-math-h-in-c14-c11
-#if SLANG_GCC_FAMILY && __GNUC__ < 6
-# include <cmath>
-# define SLANG_PRELUDE_STD std::
-#else
-# include <math.h>
-# define SLANG_PRELUDE_STD
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
+#ifdef SLANG_LLVM
+# include "slang-llvm.h"
+#else // SLANG_LLVM
+# if SLANG_GCC_FAMILY && __GNUC__ < 6
+# include <cmath>
+# define SLANG_PRELUDE_STD std::
+# else
+# include <math.h>
+# define SLANG_PRELUDE_STD
+# endif
+
+# include <assert.h>
+# include <stdlib.h>
+# include <string.h>
+# include <stdint.h>
+#endif // SLANG_LLVM
#if defined(_MSC_VER)
# define SLANG_PRELUDE_SHARED_LIB_EXPORT __declspec(dllexport)
@@ -26,8 +31,12 @@
#ifdef __cplusplus
# define SLANG_PRELUDE_EXTERN_C extern "C"
+# define SLANG_PRELUDE_EXTERN_C_START extern "C" {
+# define SLANG_PRELUDE_EXTERN_C_END }
#else
# define SLANG_PRELUDE_EXTERN_C
+# define SLANG_PRELUDE_EXTERN_C_START
+# define SLANG_PRELUDE_EXTERN_C_END
#endif
#define SLANG_PRELUDE_EXPORT SLANG_PRELUDE_EXTERN_C SLANG_PRELUDE_SHARED_LIB_EXPORT
diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h
index 7ee62dbc6..60f1dd278 100644
--- a/prelude/slang-cpp-scalar-intrinsics.h
+++ b/prelude/slang-cpp-scalar-intrinsics.h
@@ -1,8 +1,8 @@
#ifndef SLANG_PRELUDE_SCALAR_INTRINSICS_H
#define SLANG_PRELUDE_SCALAR_INTRINSICS_H
-#if SLANG_PROCESSOR_X86_64 && SLANG_VC
-// If we have visual studio and 64 bit processor, we can assume we have popcnt, and can include x86 intrinsics
+#if !defined(SLANG_LLVM) && SLANG_PROCESSOR_X86_64 && SLANG_VC
+// If we have visual studio and 64 bit processor, we can assume we have popcnt, and can include x86 intrinsics
# include <intrin.h>
#endif
@@ -35,15 +35,55 @@ union Union64
};
// Helpers
-SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians)
-{
- // Put 0 to 2pi cycles to cycle around 0 to 1
- float a = radians * (1.0f / float(SLANG_PRELUDE_PI * 2));
- // Get truncated fraction, as value in 0 - 1 range
- a = a - ::floorf(a);
- // Convert back to 0 - 2pi range
- return (a * float(SLANG_PRELUDE_PI * 2));
-}
+SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians);
+
+#ifdef SLANG_LLVM
+
+SLANG_PRELUDE_EXTERN_C_START
+
+// Unary
+float F32_ceil(float f);
+float F32_floor(float f);
+float F32_round(float f);
+float F32_sin(float f);
+float F32_cos(float f);
+float F32_tan(float f);
+float F32_asin(float f);
+float F32_acos(float f);
+float F32_atan(float f);
+float F32_sinh(float f);
+float F32_cosh(float f);
+float F32_tanh(float f);
+float F32_log2(float f);
+float F32_log(float f);
+float F32_log10(float f);
+float F32_exp2(float f);
+float F32_exp(float f);
+float F32_abs(float f);
+float F32_trunc(float f);
+float F32_sqrt(float f);
+
+bool F32_isnan(float f);
+bool F32_isfinite(float f);
+bool F32_isinf(float f);
+
+// Binary
+SLANG_FORCE_INLINE float F32_min(float a, float b) { return a < b ? a : b; }
+SLANG_FORCE_INLINE float F32_max(float a, float b) { return a > b ? a : b; }
+float F32_pow(float a, float b);
+float F32_fmod(float a, float b);
+float F32_remainder(float a, float b);
+float F32_atan2(float a, float b);
+
+float F32_frexp(float x, float* e);
+float F32_modf(float x, float* ip);
+
+// Ternary
+SLANG_FORCE_INLINE float F32_fma(float a, float b, float c) { return a * b + c; }
+
+SLANG_PRELUDE_EXTERN_C_END
+
+#else
// Unary
SLANG_FORCE_INLINE float F32_ceil(float f) { return ::ceilf(f); }
@@ -66,9 +106,6 @@ SLANG_FORCE_INLINE float F32_exp(float f) { return ::expf(f); }
SLANG_FORCE_INLINE float F32_abs(float f) { return ::fabsf(f); }
SLANG_FORCE_INLINE float F32_trunc(float f) { return ::truncf(f); }
SLANG_FORCE_INLINE float F32_sqrt(float f) { return ::sqrtf(f); }
-SLANG_FORCE_INLINE float F32_rsqrt(float f) { return 1.0f / F32_sqrt(f); }
-SLANG_FORCE_INLINE float F32_sign(float f) { return ( f == 0.0f) ? f : (( f < 0.0f) ? -1.0f : 1.0f); }
-SLANG_FORCE_INLINE float F32_frac(float f) { return f - F32_floor(f); }
SLANG_FORCE_INLINE bool F32_isnan(float f) { return SLANG_PRELUDE_STD isnan(f); }
SLANG_FORCE_INLINE bool F32_isfinite(float f) { return SLANG_PRELUDE_STD isfinite(f); }
@@ -94,24 +131,81 @@ SLANG_FORCE_INLINE float F32_modf(float x, float* ip)
return ::modff(x, ip);
}
-SLANG_FORCE_INLINE uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; }
-SLANG_FORCE_INLINE int32_t F32_asint(float f) { Union32 u; u.f = f; return u.i; }
-
// Ternary
SLANG_FORCE_INLINE float F32_fma(float a, float b, float c) { return ::fmaf(a, b, c); }
-// ----------------------------- F64 -----------------------------------------
+#endif
-SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians)
+SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians)
{
// Put 0 to 2pi cycles to cycle around 0 to 1
- double a = radians * (1.0f / (SLANG_PRELUDE_PI * 2));
+ float a = radians * (1.0f / float(SLANG_PRELUDE_PI * 2));
// Get truncated fraction, as value in 0 - 1 range
- a = a - ::floor(a);
+ a = a - F32_floor(a);
// Convert back to 0 - 2pi range
- return (a * (SLANG_PRELUDE_PI * 2));
+ return (a * float(SLANG_PRELUDE_PI * 2));
}
+SLANG_FORCE_INLINE float F32_rsqrt(float f) { return 1.0f / F32_sqrt(f); }
+SLANG_FORCE_INLINE float F32_sign(float f) { return ( f == 0.0f) ? f : (( f < 0.0f) ? -1.0f : 1.0f); }
+SLANG_FORCE_INLINE float F32_frac(float f) { return f - F32_floor(f); }
+
+SLANG_FORCE_INLINE uint32_t F32_asuint(float f) { Union32 u; u.f = f; return u.u; }
+SLANG_FORCE_INLINE int32_t F32_asint(float f) { Union32 u; u.f = f; return u.i; }
+
+// ----------------------------- F64 -----------------------------------------
+
+SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians);
+
+#ifdef SLANG_LLVM
+
+SLANG_PRELUDE_EXTERN_C_START
+
+// Unary
+double F64_ceil(double f);
+double F64_floor(double f);
+double F64_round(double f);
+double F64_sin(double f);
+double F64_cos(double f);
+double F64_tan(double f);
+double F64_asin(double f);
+double F64_acos(double f);
+double F64_atan(double f);
+double F64_sinh(double f);
+double F64_cosh(double f);
+double F64_tanh(double f);
+double F64_log2(double f);
+double F64_log(double f);
+double F64_log10(float f);
+double F64_exp2(double f);
+double F64_exp(double f);
+double F64_abs(double f);
+double F64_trunc(double f);
+double F64_sqrt(double f);
+
+bool F64_isnan(double f);
+bool F64_isfinite(double f);
+bool F64_isinf(double f);
+
+// Binary
+SLANG_FORCE_INLINE double F64_min(double a, double b) { return a < b ? a : b; }
+SLANG_FORCE_INLINE double F64_max(double a, double b) { return a > b ? a : b; }
+double F64_pow(double a, double b);
+double F64_fmod(double a, double b);
+double F64_remainder(double a, double b);
+double F64_atan2(double a, double b);
+
+double F64_frexp(double x, double* e);
+
+double F64_modf(double x, double* ip);
+
+// Ternary
+SLANG_FORCE_INLINE double F64_fma(double a, double b, double c) { return a * b + c; }
+
+SLANG_PRELUDE_EXTERN_C_END
+
+#else // SLANG_LLVM
+
// Unary
SLANG_FORCE_INLINE double F64_ceil(double f) { return ::ceil(f); }
SLANG_FORCE_INLINE double F64_floor(double f) { return ::floor(f); }
@@ -133,9 +227,7 @@ SLANG_FORCE_INLINE double F64_exp(double f) { return ::exp(f); }
SLANG_FORCE_INLINE double F64_abs(double f) { return ::fabs(f); }
SLANG_FORCE_INLINE double F64_trunc(double f) { return ::trunc(f); }
SLANG_FORCE_INLINE double F64_sqrt(double f) { return ::sqrt(f); }
-SLANG_FORCE_INLINE double F64_rsqrt(double f) { return 1.0 / F64_sqrt(f); }
-SLANG_FORCE_INLINE double F64_sign(double f) { return (f == 0.0) ? f : ((f < 0.0) ? -1.0 : 1.0); }
-SLANG_FORCE_INLINE double F64_frac(double f) { return f - F64_floor(f); }
+
SLANG_FORCE_INLINE bool F64_isnan(double f) { return SLANG_PRELUDE_STD isnan(f); }
SLANG_FORCE_INLINE bool F64_isfinite(double f) { return SLANG_PRELUDE_STD isfinite(f); }
@@ -162,6 +254,15 @@ SLANG_FORCE_INLINE double F64_modf(double x, double* ip)
return ::modf(x, ip);
}
+// Ternary
+SLANG_FORCE_INLINE double F64_fma(double a, double b, double c) { return ::fma(a, b, c); }
+
+#endif // SLANG_LLVM
+
+SLANG_FORCE_INLINE double F64_rsqrt(double f) { return 1.0 / F64_sqrt(f); }
+SLANG_FORCE_INLINE double F64_sign(double f) { return (f == 0.0) ? f : ((f < 0.0) ? -1.0 : 1.0); }
+SLANG_FORCE_INLINE double F64_frac(double f) { return f - F64_floor(f); }
+
SLANG_FORCE_INLINE void F64_asuint(double d, uint32_t* low, uint32_t* hi)
{
Union64 u;
@@ -178,8 +279,15 @@ SLANG_FORCE_INLINE void F64_asint(double d, int32_t* low, int32_t* hi)
*hi = int32_t(u.u >> 32);
}
-// Ternary
-SLANG_FORCE_INLINE double F64_fma(double a, double b, double c) { return ::fma(a, b, c); }
+SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians)
+{
+ // Put 0 to 2pi cycles to cycle around 0 to 1
+ double a = radians * (1.0f / (SLANG_PRELUDE_PI * 2));
+ // Get truncated fraction, as value in 0 - 1 range
+ a = a - F64_floor(a);
+ // Convert back to 0 - 2pi range
+ return (a * (SLANG_PRELUDE_PI * 2));
+}
// ----------------------------- I32 -----------------------------------------
@@ -217,7 +325,7 @@ SLANG_FORCE_INLINE double U32_asdouble(uint32_t low, uint32_t hi)
SLANG_FORCE_INLINE uint32_t U32_countbits(uint32_t v)
{
-#if SLANG_GCC_FAMILY
+#if SLANG_GCC_FAMILY && !defined(SLANG_LLVM)
return __builtin_popcount(v);
#elif SLANG_PROCESSOR_X86_64 && SLANG_VC
return __popcnt(v);
@@ -244,7 +352,7 @@ SLANG_FORCE_INLINE uint64_t U64_max(uint64_t a, uint64_t b) { return a > b ? a :
// 32 bits can always hold the result, and will be implicitly promoted.
SLANG_FORCE_INLINE uint32_t U64_countbits(uint64_t v)
{
-#if SLANG_GCC_FAMILY
+#if SLANG_GCC_FAMILY && !defined(SLANG_LLVM)
return uint32_t(__builtin_popcountl(v));
#elif SLANG_PROCESSOR_X86_64 && SLANG_VC
return uint32_t(__popcnt64(v));
@@ -268,18 +376,26 @@ SLANG_FORCE_INLINE int64_t I64_max(int64_t a, int64_t b) { return a > b ? a : b;
// ----------------------------- Interlocked ---------------------------------
-#ifdef _WIN32
-#include <intrin.h>
-#endif
+
+#if SLANG_LLVM
+
+#else // SLANG_LLVM
+
+# ifdef _WIN32
+# include <intrin.h>
+# endif
void InterlockedAdd(uint32_t* dest, uint32_t value, uint32_t* oldValue)
{
-#ifdef _WIN32
+# ifdef _WIN32
*oldValue = _InterlockedExchangeAdd((long*)dest, (long)value);
-#else
+# else
*oldValue = __sync_fetch_and_add(dest, value);
-#endif
+# endif
}
+
+#endif // SLANG_LLVM
+
#ifdef SLANG_PRELUDE_NAMESPACE
}
#endif
diff --git a/prelude/slang-cpp-types.h b/prelude/slang-cpp-types.h
index 99e8f5097..64db2efb3 100644
--- a/prelude/slang-cpp-types.h
+++ b/prelude/slang-cpp-types.h
@@ -1,6 +1,6 @@
#ifndef SLANG_PRELUDE_CPP_TYPES_H
#define SLANG_PRELUDE_CPP_TYPES_H
-#include <stdint.h>
+
#ifndef SLANG_PRELUDE_ASSERT
# ifdef _DEBUG
# define SLANG_PRELUDE_ASSERT(VALUE) assert(VALUE)
diff --git a/prelude/slang-llvm.h b/prelude/slang-llvm.h
new file mode 100644
index 000000000..22966ead0
--- /dev/null
+++ b/prelude/slang-llvm.h
@@ -0,0 +1,393 @@
+#ifndef SLANG_LLVM_H
+#define SLANG_LLVM_H
+
+#ifndef SLANG_PRELUDE_ASSERT
+# ifdef DEBUG
+extern "C" void assertFailure(const char* msg);
+# define SLANG_PRELUDE_EXPECT(VALUE, MSG) if(VALUE) {} else assertFailure("assertion failed: '" MSG "'")
+# define SLANG_PRELUDE_ASSERT(VALUE) SLANG_PRELUDE_EXPECT(VALUE, #VALUE)
+# else // DEBUG
+
+# define SLANG_PRELUDE_ASSERT(x)
+# endif // DEBUG
+#endif
+
+/*
+Taken from stddef.h
+*/
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __SIZE_TYPE__ rsize_t;
+
+//typedef __WCHAR_TYPE__ wchar_t;
+
+#if defined(__need_NULL)
+#undef NULL
+#ifdef __cplusplus
+# if !defined(__MINGW32__) && !defined(_MSC_VER)
+# define NULL __null
+# else
+# define NULL 0
+# endif
+#else
+# define NULL ((void*)0)
+#endif
+#ifdef __cplusplus
+#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
+namespace std { typedef decltype(nullptr) nullptr_t; }
+using ::std::nullptr_t;
+#endif
+#endif
+#undef __need_NULL
+#endif /* defined(__need_NULL) */
+
+
+/*
+The following are taken verbatim from stdint.h from Clang in LLVM. Only 8/16/32/64 types are needed.
+*/
+
+// LLVM/Clang types such that we can use LLVM/Clang without headers for C++ output from Slang
+
+#ifdef __INT64_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+typedef __INT64_TYPE__ int64_t;
+# endif /* __int8_t_defined */
+typedef __UINT64_TYPE__ uint64_t;
+# define __int_least64_t int64_t
+# define __uint_least64_t uint64_t
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+typedef __int_least64_t int_least64_t;
+typedef __uint_least64_t uint_least64_t;
+typedef __int_least64_t int_fast64_t;
+typedef __uint_least64_t uint_fast64_t;
+#endif /* __int_least64_t */
+
+#ifdef __INT32_TYPE__
+
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+typedef __INT32_TYPE__ int32_t;
+# endif /* __int8_t_defined */
+
+# ifndef __uint32_t_defined /* more glibc compatibility */
+# define __uint32_t_defined
+typedef __UINT32_TYPE__ uint32_t;
+# endif /* __uint32_t_defined */
+
+# define __int_least32_t int32_t
+# define __uint_least32_t uint32_t
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+typedef __int_least32_t int_least32_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __int_least32_t int_fast32_t;
+typedef __uint_least32_t uint_fast32_t;
+#endif /* __int_least32_t */
+
+#ifdef __INT16_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+typedef __INT16_TYPE__ int16_t;
+#endif /* __int8_t_defined */
+typedef __UINT16_TYPE__ uint16_t;
+# define __int_least16_t int16_t
+# define __uint_least16_t uint16_t
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+typedef __int_least16_t int_least16_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __int_least16_t int_fast16_t;
+typedef __uint_least16_t uint_fast16_t;
+#endif /* __int_least16_t */
+
+#ifdef __INT8_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int8_t*/
+typedef __INT8_TYPE__ int8_t;
+#endif /* __int8_t_defined */
+typedef __UINT8_TYPE__ uint8_t;
+# define __int_least8_t int8_t
+# define __uint_least8_t uint8_t
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+typedef __int_least8_t int_least8_t;
+typedef __uint_least8_t uint_least8_t;
+typedef __int_least8_t int_fast8_t;
+typedef __uint_least8_t uint_fast8_t;
+#endif /* __int_least8_t */
+
+/* prevent glibc sys/types.h from defining conflicting types */
+#ifndef __int8_t_defined
+# define __int8_t_defined
+#endif /* __int8_t_defined */
+
+/* C99 7.18.1.4 Integer types capable of holding object pointers.
+ */
+#define __stdint_join3(a,b,c) a ## b ## c
+
+#ifndef _INTPTR_T
+#ifndef __intptr_t_defined
+typedef __INTPTR_TYPE__ intptr_t;
+#define __intptr_t_defined
+#define _INTPTR_T
+#endif
+#endif
+
+#ifndef _UINTPTR_T
+typedef __UINTPTR_TYPE__ uintptr_t;
+#define _UINTPTR_T
+#endif
+
+/* C99 7.18.1.5 Greatest-width integer types.
+ */
+typedef __INTMAX_TYPE__ intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
+
+/* C99 7.18.4 Macros for minimum-width integer constants.
+ *
+ * The standard requires that integer constant macros be defined for all the
+ * minimum-width types defined above. As 8-, 16-, 32-, and 64-bit minimum-width
+ * types are required, the corresponding integer constant macros are defined
+ * here. This implementation also defines minimum-width types for every other
+ * integer width that the target implements, so corresponding macros are
+ * defined below, too.
+ *
+ * These macros are defined using the same successive-shrinking approach as
+ * the type definitions above. It is likewise important that macros are defined
+ * in order of decending width.
+ *
+ * Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#define __int_c_join(a, b) a ## b
+#define __int_c(v, suffix) __int_c_join(v, suffix)
+#define __uint_c(v, suffix) __int_c_join(v##U, suffix)
+
+#ifdef __INT64_TYPE__
+# ifdef __INT64_C_SUFFIX__
+# define __int64_c_suffix __INT64_C_SUFFIX__
+# else
+# undef __int64_c_suffix
+# endif /* __INT64_C_SUFFIX__ */
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+# ifdef __int64_c_suffix
+# define INT64_C(v) __int_c(v, __int64_c_suffix)
+# define UINT64_C(v) __uint_c(v, __int64_c_suffix)
+# else
+# define INT64_C(v) v
+# define UINT64_C(v) v ## U
+# endif /* __int64_c_suffix */
+#endif /* __int_least64_t */
+
+
+#ifdef __INT32_TYPE__
+# ifdef __INT32_C_SUFFIX__
+# define __int32_c_suffix __INT32_C_SUFFIX__
+#else
+# undef __int32_c_suffix
+# endif /* __INT32_C_SUFFIX__ */
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+# ifdef __int32_c_suffix
+# define INT32_C(v) __int_c(v, __int32_c_suffix)
+# define UINT32_C(v) __uint_c(v, __int32_c_suffix)
+# else
+# define INT32_C(v) v
+# define UINT32_C(v) v ## U
+# endif /* __int32_c_suffix */
+#endif /* __int_least32_t */
+
+#ifdef __INT16_TYPE__
+# ifdef __INT16_C_SUFFIX__
+# define __int16_c_suffix __INT16_C_SUFFIX__
+#else
+# undef __int16_c_suffix
+# endif /* __INT16_C_SUFFIX__ */
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+# ifdef __int16_c_suffix
+# define INT16_C(v) __int_c(v, __int16_c_suffix)
+# define UINT16_C(v) __uint_c(v, __int16_c_suffix)
+# else
+# define INT16_C(v) v
+# define UINT16_C(v) v ## U
+# endif /* __int16_c_suffix */
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+# ifdef __INT8_C_SUFFIX__
+# define __int8_c_suffix __INT8_C_SUFFIX__
+#else
+# undef __int8_c_suffix
+# endif /* __INT8_C_SUFFIX__ */
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+# ifdef __int8_c_suffix
+# define INT8_C(v) __int_c(v, __int8_c_suffix)
+# define UINT8_C(v) __uint_c(v, __int8_c_suffix)
+# else
+# define INT8_C(v) v
+# define UINT8_C(v) v ## U
+# endif /* __int8_c_suffix */
+#endif /* __int_least8_t */
+
+/* C99 7.18.2.1 Limits of exact-width integer types.
+ * C99 7.18.2.2 Limits of minimum-width integer types.
+ * C99 7.18.2.3 Limits of fastest minimum-width integer types.
+ *
+ * The presence of limit macros are completely optional in C99. This
+ * implementation defines limits for all of the types (exact- and
+ * minimum-width) that it defines above, using the limits of the minimum-width
+ * type for any types that do not have exact-width representations.
+ *
+ * As in the type definitions, this section takes an approach of
+ * successive-shrinking to determine which limits to use for the standard (8,
+ * 16, 32, 64) bit widths when they don't have exact representations. It is
+ * therefore important that the definitions be kept in order of decending
+ * widths.
+ *
+ * Note that C++ should not check __STDC_LIMIT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#ifdef __INT64_TYPE__
+# define INT64_MAX INT64_C( 9223372036854775807)
+# define INT64_MIN (-INT64_C( 9223372036854775807)-1)
+# define UINT64_MAX UINT64_C(18446744073709551615)
+# define __INT_LEAST64_MIN INT64_MIN
+# define __INT_LEAST64_MAX INT64_MAX
+# define __UINT_LEAST64_MAX UINT64_MAX
+#endif /* __INT64_TYPE__ */
+
+#ifdef __INT_LEAST64_MIN
+# define INT_LEAST64_MIN __INT_LEAST64_MIN
+# define INT_LEAST64_MAX __INT_LEAST64_MAX
+# define UINT_LEAST64_MAX __UINT_LEAST64_MAX
+# define INT_FAST64_MIN __INT_LEAST64_MIN
+# define INT_FAST64_MAX __INT_LEAST64_MAX
+# define UINT_FAST64_MAX __UINT_LEAST64_MAX
+#endif /* __INT_LEAST64_MIN */
+
+#ifdef __INT32_TYPE__
+# define INT32_MAX INT32_C(2147483647)
+# define INT32_MIN (-INT32_C(2147483647)-1)
+# define UINT32_MAX UINT32_C(4294967295)
+# define __INT_LEAST32_MIN INT32_MIN
+# define __INT_LEAST32_MAX INT32_MAX
+# define __UINT_LEAST32_MAX UINT32_MAX
+#endif /* __INT32_TYPE__ */
+
+#ifdef __INT_LEAST32_MIN
+# define INT_LEAST32_MIN __INT_LEAST32_MIN
+# define INT_LEAST32_MAX __INT_LEAST32_MAX
+# define UINT_LEAST32_MAX __UINT_LEAST32_MAX
+# define INT_FAST32_MIN __INT_LEAST32_MIN
+# define INT_FAST32_MAX __INT_LEAST32_MAX
+# define UINT_FAST32_MAX __UINT_LEAST32_MAX
+#endif /* __INT_LEAST32_MIN */
+
+#ifdef __INT16_TYPE__
+#define INT16_MAX INT16_C(32767)
+#define INT16_MIN (-INT16_C(32767)-1)
+#define UINT16_MAX UINT16_C(65535)
+# define __INT_LEAST16_MIN INT16_MIN
+# define __INT_LEAST16_MAX INT16_MAX
+# define __UINT_LEAST16_MAX UINT16_MAX
+#endif /* __INT16_TYPE__ */
+
+#ifdef __INT_LEAST16_MIN
+# define INT_LEAST16_MIN __INT_LEAST16_MIN
+# define INT_LEAST16_MAX __INT_LEAST16_MAX
+# define UINT_LEAST16_MAX __UINT_LEAST16_MAX
+# define INT_FAST16_MIN __INT_LEAST16_MIN
+# define INT_FAST16_MAX __INT_LEAST16_MAX
+# define UINT_FAST16_MAX __UINT_LEAST16_MAX
+#endif /* __INT_LEAST16_MIN */
+
+
+#ifdef __INT8_TYPE__
+# define INT8_MAX INT8_C(127)
+# define INT8_MIN (-INT8_C(127)-1)
+# define UINT8_MAX UINT8_C(255)
+# define __INT_LEAST8_MIN INT8_MIN
+# define __INT_LEAST8_MAX INT8_MAX
+# define __UINT_LEAST8_MAX UINT8_MAX
+#endif /* __INT8_TYPE__ */
+
+#ifdef __INT_LEAST8_MIN
+# define INT_LEAST8_MIN __INT_LEAST8_MIN
+# define INT_LEAST8_MAX __INT_LEAST8_MAX
+# define UINT_LEAST8_MAX __UINT_LEAST8_MAX
+# define INT_FAST8_MIN __INT_LEAST8_MIN
+# define INT_FAST8_MAX __INT_LEAST8_MAX
+# define UINT_FAST8_MAX __UINT_LEAST8_MAX
+#endif /* __INT_LEAST8_MIN */
+
+/* Some utility macros */
+#define __INTN_MIN(n) __stdint_join3( INT, n, _MIN)
+#define __INTN_MAX(n) __stdint_join3( INT, n, _MAX)
+#define __UINTN_MAX(n) __stdint_join3(UINT, n, _MAX)
+#define __INTN_C(n, v) __stdint_join3( INT, n, _C(v))
+#define __UINTN_C(n, v) __stdint_join3(UINT, n, _C(v))
+
+/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
+/* C99 7.18.3 Limits of other integer types. */
+
+#define INTPTR_MIN (-__INTPTR_MAX__-1)
+#define INTPTR_MAX __INTPTR_MAX__
+#define UINTPTR_MAX __UINTPTR_MAX__
+#define PTRDIFF_MIN (-__PTRDIFF_MAX__-1)
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define SIZE_MAX __SIZE_MAX__
+
+/* ISO9899:2011 7.20 (C11 Annex K): Define RSIZE_MAX if __STDC_WANT_LIB_EXT1__
+ * is enabled. */
+#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
+#define RSIZE_MAX (SIZE_MAX >> 1)
+#endif
+
+/* C99 7.18.2.5 Limits of greatest-width integer types. */
+#define INTMAX_MIN (-__INTMAX_MAX__-1)
+#define INTMAX_MAX __INTMAX_MAX__
+#define UINTMAX_MAX __UINTMAX_MAX__
+
+/* C99 7.18.3 Limits of other integer types. */
+#define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__)
+#define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__)
+#ifdef __WINT_UNSIGNED__
+# define WINT_MIN __UINTN_C(__WINT_WIDTH__, 0)
+# define WINT_MAX __UINTN_MAX(__WINT_WIDTH__)
+#else
+# define WINT_MIN __INTN_MIN(__WINT_WIDTH__)
+# define WINT_MAX __INTN_MAX(__WINT_WIDTH__)
+#endif
+
+#ifndef WCHAR_MAX
+# define WCHAR_MAX __WCHAR_MAX__
+#endif
+#ifndef WCHAR_MIN
+# if __WCHAR_MAX__ == __INTN_MAX(__WCHAR_WIDTH__)
+# define WCHAR_MIN __INTN_MIN(__WCHAR_WIDTH__)
+# else
+# define WCHAR_MIN __UINTN_C(__WCHAR_WIDTH__, 0)
+# endif
+#endif
+
+/* 7.18.4.2 Macros for greatest-width integer constants. */
+#define INTMAX_C(v) __int_c(v, __INTMAX_C_SUFFIX__)
+#define UINTMAX_C(v) __int_c(v, __UINTMAX_C_SUFFIX__)
+
+
+#endif // SLANG_LLVM_H
+
+
diff --git a/slang.h b/slang.h
index 5433b4f37..38acc3997 100644
--- a/slang.h
+++ b/slang.h
@@ -557,6 +557,7 @@ extern "C"
SLANG_PASS_THROUGH_GCC, ///< GCC C/C++ compiler
SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the source type
SLANG_PASS_THROUGH_NVRTC, ///< NVRTC Cuda compiler
+ SLANG_PASS_THROUGH_LLVM, ///< LLVM 'compiler' - includes LLVM and Clang
SLANG_PASS_THROUGH_COUNT_OF,
};
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);
diff --git a/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected b/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected
index 73328c480..599e497f5 100644
--- a/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected
+++ b/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected
@@ -1,6 +1,6 @@
result code = 1
standard error = {
-(1): error 100000: downstream tool name not known, allowed names are [ fxc, dxc, glslang, clang, visualstudio, gcc, genericcpp, nvrtc, downstream, linker ]
+(1): error 100000: downstream tool name not known, allowed names are [ fxc, dxc, glslang, clang, visualstudio, gcc, genericcpp, nvrtc, llvm, downstream, linker ]
tests/diagnostics/command-line/x-arg-tool-unknown.slang -entry main -stage compute -o myKernel.dxbc -o myKernel.dxbc -Xthingy
^
}
diff --git a/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang b/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang
index c5fd93ca4..77e7c2050 100644
--- a/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang
+++ b/tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang
@@ -1,4 +1,4 @@
-//TEST:COMPILE: -entry computeMain -stage compute -target dll tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang
+//TEST:COMPILE: -entry computeMain -stage compute -target callable tests/hlsl-intrinsic/sampler-feedback/compute-sampler-feedback.slang
// Not available on non PS shader
// dx.op.writeSamplerFeedback WriteSamplerFeedback
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index f477faf57..18ac05477 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -3430,46 +3430,40 @@ SlangResult innerMain(int argc, char** argv)
// An un-categorized test will always belong to the `full` category
categorySet.defaultCategory = fullTestCategory;
- TestCategory* fxcCategory = nullptr;
- TestCategory* dxcCategory = nullptr;
- TestCategory* glslangCategory = nullptr;
- TestCategory* nvrtcCategory = nullptr;
+ // All following values are initialized to '0', so null.
+ TestCategory* passThroughCategories[SLANG_PASS_THROUGH_COUNT_OF] = { nullptr };
// Work out what backends/pass-thrus are available
{
SlangSession* session = context.getSession();
+ StdWriters::getOut().print("Supported backends:");
+
for (int i = 0; i < SLANG_PASS_THROUGH_COUNT_OF; ++i)
{
- SlangPassThrough passThru = SlangPassThrough(i);
+ const SlangPassThrough passThru = SlangPassThrough(i);
+ if (passThru == SLANG_PASS_THROUGH_NONE)
+ {
+ continue;
+ }
if (SLANG_SUCCEEDED(spSessionCheckPassThroughSupport(session, passThru)))
{
context.availableBackendFlags |= PassThroughFlags(1) << int(i);
+
+ StringBuilder buf;
+
+ auto name = TypeTextUtil::getPassThroughName(passThru);
+
+ buf << " " << name;
+
+ SLANG_ASSERT(passThroughCategories[i] == nullptr);
+ passThroughCategories[i] = categorySet.add(buf.getBuffer() + 1, fullTestCategory);
+
+ StdWriters::getOut().write(buf.getBuffer(), buf.getLength());
}
}
- StdWriters::getOut().print("Supported backends:");
- if (context.availableBackendFlags & PassThroughFlag::Fxc)
- {
- StdWriters::getOut().print(" fxc");
- fxcCategory = categorySet.add("fxc", fullTestCategory);
- }
- if (context.availableBackendFlags & PassThroughFlag::Glslang)
- {
- StdWriters::getOut().print(" glslang");
- glslangCategory = categorySet.add("glslang", fullTestCategory);
- }
- if (context.availableBackendFlags & PassThroughFlag::Dxc)
- {
- StdWriters::getOut().print(" dxc");
- dxcCategory = categorySet.add("dxc", fullTestCategory);
- }
- if (context.availableBackendFlags & PassThroughFlag::NVRTC)
- {
- StdWriters::getOut().print(" nvrtc");
- nvrtcCategory = categorySet.add("nvrtc", fullTestCategory);
- }
StdWriters::getOut().print("\n");
}
diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h
index a4b92790b..67707028d 100644
--- a/tools/slang-test/test-context.h
+++ b/tools/slang-test/test-context.h
@@ -28,7 +28,8 @@ struct PassThroughFlag
GCC = 1 << int(SLANG_PASS_THROUGH_GCC),
Clang = 1 << int(SLANG_PASS_THROUGH_CLANG),
Generic_C_CPP = 1 << int(SLANG_PASS_THROUGH_GENERIC_C_CPP),
- NVRTC = 1 << int(SLANG_PASS_THROUGH_NVRTC)
+ NVRTC = 1 << int(SLANG_PASS_THROUGH_NVRTC),
+ LLVM = 1 << int(SLANG_PASS_THROUGH_LLVM),
};
};