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 | |
| 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.
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 + + @@ -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), }; }; |
