From f9b5f18fb5306e3dc1f9bef8106f98b5f9cb468f Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 18 Jun 2020 11:36:58 -0400 Subject: * Fix warnings from prelude * Make compilation work on gcc by disabling -Wclass-mem-access --- prelude/slang-cpp-scalar-intrinsics.h | 14 +++++++++----- premake5.lua | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h index c814365c6..c7d654170 100644 --- a/prelude/slang-cpp-scalar-intrinsics.h +++ b/prelude/slang-cpp-scalar-intrinsics.h @@ -84,7 +84,7 @@ SLANG_FORCE_INLINE float F32_frexp(float x, float& e) { int ei; float m = ::frexpf(x, &ei); - e = ei; + e = float(ei); return m; } SLANG_FORCE_INLINE float F32_modf(float x, float& ip) @@ -151,9 +151,10 @@ SLANG_FORCE_INLINE double F64_frexp(double x, double& e) { int ei; double m = ::frexp(x, &ei); - e = ei; + e = float(ei); return m; } + SLANG_FORCE_INLINE double F64_modf(double x, double& ip) { return ::modf(x, &ip); @@ -236,14 +237,17 @@ SLANG_FORCE_INLINE uint64_t U64_abs(uint64_t f) { return f; } SLANG_FORCE_INLINE uint64_t U64_min(uint64_t a, uint64_t b) { return a < b ? a : b; } SLANG_FORCE_INLINE uint64_t U64_max(uint64_t a, uint64_t b) { return a > b ? a : b; } +// TODO(JS): We don't define countbits for 64bit in stdlib currently. +// It's not clear from documentation if it should return 32 or 64 bits, if it exists. +// 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 - return __builtin_popcountl(v); + return uint32_t(__builtin_popcountl(v)); #elif SLANG_PROCESSOR_X86_64 && SLANG_VC - return __popcnt64(v); + return uint32_t(__popcnt64(v)); #else - uint64_t c = 0; + uint32_t c = 0; while (v) { c++; diff --git a/premake5.lua b/premake5.lua index 93d310ee0..2b3385b1c 100644 --- a/premake5.lua +++ b/premake5.lua @@ -201,7 +201,7 @@ workspace "slang" architecture "ARM" filter { "toolset:clang or gcc*" } - buildoptions { "-Wno-unused-parameter", "-Wno-type-limits", "-Wno-sign-compare", "-Wno-unused-variable", "-Wno-reorder", "-Wno-switch", "-Wno-return-type", "-Wno-unused-local-typedefs", "-Wno-parentheses", "-std=c++11", "-fvisibility=hidden" , "-Wno-ignored-optimization-argument", "-Wno-unknown-warning-option"} + buildoptions { "-Wno-unused-parameter", "-Wno-type-limits", "-Wno-sign-compare", "-Wno-unused-variable", "-Wno-reorder", "-Wno-switch", "-Wno-return-type", "-Wno-unused-local-typedefs", "-Wno-parentheses", "-std=c++11", "-fvisibility=hidden" , "-Wno-ignored-optimization-argument", "-Wno-unknown-warning-option", "-Wno-class-memaccess"} filter { "toolset:gcc*"} buildoptions { "-Wno-unused-but-set-variable", "-Wno-implicit-fallthrough" } -- cgit v1.2.3 From 48da3ed09c84cd53f24b1f3628402f0bbc92e540 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 18 Jun 2020 12:44:51 -0400 Subject: #include Use SLANG_PRELUDE_STD macro to prefix functions that may need to be specified in std:: namespace. --- prelude/slang-cpp-prelude.h | 2 +- prelude/slang-cpp-scalar-intrinsics.h | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h index 2e680f824..4a07674d1 100644 --- a/prelude/slang-cpp-prelude.h +++ b/prelude/slang-cpp-prelude.h @@ -3,7 +3,7 @@ #include "../slang.h" -#include +#include #include #include diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h index c7d654170..f6c35e393 100644 --- a/prelude/slang-cpp-scalar-intrinsics.h +++ b/prelude/slang-cpp-scalar-intrinsics.h @@ -8,6 +8,12 @@ # include #endif +// Because the signiture of isnan, isfinite, and is isinf changed in C++, we use the macro +// to use the version in the std namespace. +// https://stackoverflow.com/questions/39130040/cmath-hides-isnan-in-math-h-in-c14-c11 + +#define SLANG_PRELUDE_STD std:: + #ifdef SLANG_PRELUDE_NAMESPACE namespace SLANG_PRELUDE_NAMESPACE { #endif @@ -68,9 +74,9 @@ 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 isnan(f); } -SLANG_FORCE_INLINE bool F32_isfinite(float f) { return isfinite(f); } -SLANG_FORCE_INLINE bool F32_isinf(float f) { return isinf(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); } +SLANG_FORCE_INLINE bool F32_isinf(float f) { return SLANG_PRELUDE_STD isinf(f); } // Binary SLANG_FORCE_INLINE float F32_min(float a, float b) { return ::fminf(a, b); } @@ -135,9 +141,9 @@ 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 isnan(f); } -SLANG_FORCE_INLINE bool F64_isfinite(double f) { return isfinite(f); } -SLANG_FORCE_INLINE bool F64_isinf(double f) { return isinf(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); } +SLANG_FORCE_INLINE bool F64_isinf(double f) { return SLANG_PRELUDE_STD isinf(f); } // Binary SLANG_FORCE_INLINE double F64_min(double a, double b) { return ::fmin(a, b); } -- cgit v1.2.3 From e2d21026d115dc61296b47dcc990534f1844bc7f Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 18 Jun 2020 14:46:14 -0400 Subject: Try using cmath or math.h depending on compiler to avoid issues around isinf etc. --- prelude/slang-cpp-prelude.h | 13 ++++++++++++- prelude/slang-cpp-scalar-intrinsics.h | 6 ------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h index 4a07674d1..d476676ed 100644 --- a/prelude/slang-cpp-prelude.h +++ b/prelude/slang-cpp-prelude.h @@ -3,7 +3,18 @@ #include "../slang.h" -#include +// Because the signiture of isnan, isfinite, and is isinf changed in C++, we use the macro +// 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 +# define SLANG_PRELUDE_STD std:: +#else +# include +# define SLANG_PRELUDE_STD +#endif + #include #include diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h index f6c35e393..07945f1e0 100644 --- a/prelude/slang-cpp-scalar-intrinsics.h +++ b/prelude/slang-cpp-scalar-intrinsics.h @@ -8,12 +8,6 @@ # include #endif -// Because the signiture of isnan, isfinite, and is isinf changed in C++, we use the macro -// to use the version in the std namespace. -// https://stackoverflow.com/questions/39130040/cmath-hides-isnan-in-math-h-in-c14-c11 - -#define SLANG_PRELUDE_STD std:: - #ifdef SLANG_PRELUDE_NAMESPACE namespace SLANG_PRELUDE_NAMESPACE { #endif -- cgit v1.2.3 From 110d15b61ac5d76da001d412eaa4be07f3cd8f4d Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 19 Jun 2020 11:19:51 -0700 Subject: Dynamic dispatch for static member functions of associatedtypes. (#1404) --- source/slang/slang-emit-c-like.cpp | 13 ++---- source/slang/slang-emit-cpp.cpp | 21 +++++++-- tests/compute/dynamic-dispatch-2.slang | 53 ++++++++++++++++++++++ .../compute/dynamic-dispatch-2.slang.expected.txt | 4 ++ 4 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 tests/compute/dynamic-dispatch-2.slang create mode 100644 tests/compute/dynamic-dispatch-2.slang.expected.txt diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 6c004c84c..3438fd3f4 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -237,18 +237,15 @@ List CLikeSourceEmitter::getSortedWitnessTableEntries(IRWi for (UInt i = 0; i < interfaceType->getOperandCount(); i++) { auto reqKey = cast(interfaceType->getOperand(i)); - bool matchingEntryFound = false; IRWitnessTableEntry* entry = nullptr; if (witnessTableEntryDictionary.TryGetValue(reqKey, entry)) { - if (entry->requirementKey.get() == reqKey) - { - matchingEntryFound = true; - sortedWitnessTableEntries.add(entry); - break; - } + sortedWitnessTableEntries.add(entry); + } + else + { + SLANG_UNREACHABLE("interface requirement key not found in witness table."); } - SLANG_ASSERT(matchingEntryFound); } return sortedWitnessTableEntries; } diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index accb290fa..4a59f4cf9 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -1711,6 +1711,15 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions() m_writer->emit("&KernelContext::"); m_writer->emit(_getWitnessTableWrapperFuncName(funcVal)); } + else if (auto witnessTableVal = as(entry->getSatisfyingVal())) + { + if (!isFirstEntry) + m_writer->emit(",\n"); + else + isFirstEntry = false; + m_writer->emit("&"); + m_writer->emit(getName(witnessTableVal)); + } else { // TODO: handle other witness table entry types. @@ -1745,16 +1754,11 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition( emitSimpleType(interfaceType); m_writer->emit("\n{\n"); m_writer->indent(); - bool isFirstEntry = true; for (Index i = 0; i < sortedWitnessTableEntries.getCount(); i++) { auto entry = sortedWitnessTableEntries[i]; if (auto funcVal = as(entry->satisfyingVal.get())) { - if (!isFirstEntry) - m_writer->emit(",\n"); - else - isFirstEntry = false; emitType(funcVal->getResultType()); m_writer->emit(" (KernelContext::*"); m_writer->emit(getName(entry->requirementKey.get())); @@ -1777,6 +1781,13 @@ void CPPSourceEmitter::_maybeEmitWitnessTableTypeDefinition( } m_writer->emit(");\n"); } + else if (auto witnessTableVal = as(entry->getSatisfyingVal())) + { + emitType(as(witnessTableVal->getOperand(0))); + m_writer->emit("* "); + m_writer->emit(getName(entry->requirementKey.get())); + m_writer->emit(";\n"); + } else { // TODO: handle other witness table entry types. diff --git a/tests/compute/dynamic-dispatch-2.slang b/tests/compute/dynamic-dispatch-2.slang new file mode 100644 index 000000000..ade8aeb84 --- /dev/null +++ b/tests/compute/dynamic-dispatch-2.slang @@ -0,0 +1,53 @@ +//TEST(compute):COMPARE_COMPUTE:-cpu -xslang -allow-dynamic-code + +// Test dynamic dispatch code gen for static member functions +// of associated type. + +interface IAssoc +{ + int get(); + static int getBase(); +} +interface IInterface +{ + associatedtype Assoc : IAssoc; + int Compute(int inVal); + Assoc getAssoc(); +}; + +int GenericCompute(T obj, int inVal) +{ + return obj.Compute(inVal) + T.Assoc.getBase(); +} + +struct Impl : IInterface +{ + struct Assoc : IAssoc + { + int val; + int get() { return val; } + static int getBase() { return -1; } + }; + int base; + int Compute(int inVal) { return base + inVal * inVal; } + Assoc getAssoc() { Assoc rs; rs.val = 1; return rs; } +}; + +int test(int inVal) +{ + Impl obj; + obj.base = 1; + return GenericCompute(obj, inVal); +} + +//TEST_INPUT:ubuffer(data=[0 1 2 3], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer : register(u0); + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + int inVal = outputBuffer[tid]; + int outVal = test(inVal); + outputBuffer[tid] = outVal; +} diff --git a/tests/compute/dynamic-dispatch-2.slang.expected.txt b/tests/compute/dynamic-dispatch-2.slang.expected.txt new file mode 100644 index 000000000..c9fa0697e --- /dev/null +++ b/tests/compute/dynamic-dispatch-2.slang.expected.txt @@ -0,0 +1,4 @@ +0 +1 +4 +9 -- cgit v1.2.3