diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 7fc6de5ac0ade..4220df3ab6626 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1218,9 +1218,14 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, getToolChain().AddCudaIncludeArgs(Args, CmdArgs); if (JA.isOffloading(Action::OFK_SYCL) || - Args.hasArg(options::OPT_fsycl_device_only)) + Args.hasArg(options::OPT_fsycl_device_only)) { toolchains::SYCLToolChain::AddSYCLIncludeArgs(D, Args, CmdArgs); + if (getToolChain().getTriple().isSPIR()) { + toolchains::SYCLToolChain::AddDevicelibIncludeArgs(CmdArgs); + } + } + // If we are offloading to a target via OpenMP we need to include the // openmp_wrappers folder which contains alternative system headers. if (JA.isDeviceOffloading(Action::OFK_OpenMP) && diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp index 5d1909643cc39..476aa4a3db767 100644 --- a/clang/lib/Driver/ToolChains/SYCL.cpp +++ b/clang/lib/Driver/ToolChains/SYCL.cpp @@ -543,6 +543,12 @@ void SYCLToolChain::AddSYCLIncludeArgs(const clang::driver::Driver &Driver, CC1Args.push_back(DriverArgs.MakeArgString(P)); } +void SYCLToolChain::AddDevicelibIncludeArgs(ArgStringList &CC1Args) { + // Assume that clang system include path is added elsewhere + CC1Args.push_back("-include"); + CC1Args.push_back("devicelib/__devicelib_assert.h"); +} + void SYCLToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args); diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h index 975c9127c89f8..336036faaa07b 100644 --- a/clang/lib/Driver/ToolChains/SYCL.h +++ b/clang/lib/Driver/ToolChains/SYCL.h @@ -145,6 +145,7 @@ class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain { static void AddSYCLIncludeArgs(const clang::driver::Driver &Driver, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args); + static void AddDevicelibIncludeArgs(llvm::opt::ArgStringList &CC1Args); void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; void AddClangCXXStdlibIncludeArgs( diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 28d43cb7ed35a..0b8e5c69b2ba2 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -147,6 +147,12 @@ set(openmp_wrapper_files openmp_wrappers/new ) +set(devicelib_wrapper_files + devicelib/__devicelib_assert.h + devicelib/__devicelib.h + devicelib/spirv_vars.h +) + set(output_dir ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/include) set(out_files) set(generated_files) @@ -175,7 +181,7 @@ endfunction(clang_generate_header) # Copy header files from the source directory to the build directory -foreach( f ${files} ${cuda_wrapper_files} ${ppc_wrapper_files} ${openmp_wrapper_files}) +foreach( f ${files} ${cuda_wrapper_files} ${ppc_wrapper_files} ${openmp_wrapper_files} ${devicelib_wrapper_files}) copy_header_to_output_dir(${CMAKE_CURRENT_SOURCE_DIR} ${f}) endforeach( f ) @@ -218,6 +224,11 @@ install( DESTINATION ${header_install_dir}/openmp_wrappers COMPONENT clang-resource-headers) +install( + FILES ${devicelib_wrapper_files} + DESTINATION ${header_install_dir}/devicelib + COMPONENT clang-resource-headers) + if (NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-clang-resource-headers DEPENDS clang-resource-headers diff --git a/clang/lib/Headers/devicelib/__devicelib.h b/clang/lib/Headers/devicelib/__devicelib.h new file mode 100644 index 0000000000000..854935e074ab5 --- /dev/null +++ b/clang/lib/Headers/devicelib/__devicelib.h @@ -0,0 +1,51 @@ +//==------------ devicelib.h - macros for devicelib wrappers ---------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __DEVICELIB_H__ +#define __DEVICELIB_H__ + +#ifndef _WIN32 +#include // for GLIBC macro +#endif + +// Devicelib wraps a system C or C++ library +#ifdef __GLIBC__ +#define __DEVICELIB_GLIBC__ 1 +#elif defined(_WIN32) +#define __DEVICELIB_MSLIBC__ 1 +#endif + +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else // __cplusplus +#define EXTERN_C +#endif // __cplusplus + +#ifdef CL_SYCL_LANGUAGE_VERSION +#ifndef SYCL_EXTERNAL +#define SYCL_EXTERNAL +#endif // SYCL_EXTERNAL + +#ifdef __SYCL_DEVICE_ONLY__ +#define DEVICE_EXTERNAL SYCL_EXTERNAL __attribute__((weak)) +#else // __SYCL_DEVICE_ONLY__ +#define DEVICE_EXTERNAL static +#undef EXTERN_C +#define EXTERN_C +#endif // __SYCL_DEVICE_ONLY__ +#else // CL_SYCL_LANGUAGE_VERSION +#define DEVICE_EXTERNAL +#endif // CL_SYCL_LANGUAGE_VERSION + +#define DEVICE_EXTERN_C DEVICE_EXTERNAL EXTERN_C + +#ifdef __SYCL_DEVICE_ONLY__ +#define __DEVICELIB_DEVICE_ONLY__ 1 +#endif + +#endif // __DEVICELIB_H__ diff --git a/clang/lib/Headers/devicelib/__devicelib_assert.h b/clang/lib/Headers/devicelib/__devicelib_assert.h new file mode 100644 index 0000000000000..e73331c2ab9e7 --- /dev/null +++ b/clang/lib/Headers/devicelib/__devicelib_assert.h @@ -0,0 +1,70 @@ +//==--------- devicelib-assert.h - wrapper definition for C assert ---------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __DEVICELIB_ASSERT_H__ +#define __DEVICELIB_ASSERT_H__ + +#include "__devicelib.h" + +#ifdef __DEVICELIB_DEVICE_ONLY__ + +#include +#include + +#include "spirv_vars.h" + +DEVICE_EXTERN_C +void __devicelib_assert_fail(const char *expr, const char *file, int32_t line, + const char *func, uint64_t gid0, uint64_t gid1, + uint64_t gid2, uint64_t lid0, uint64_t lid1, + uint64_t lid2); + +#ifdef __DEVICELIB_GLIBC__ +EXTERN_C inline void +__assert_fail(const char *expr, const char *file, + unsigned int line, const char *func) __THROW __attribute__ ((__noreturn__)) { + __devicelib_assert_fail( + expr, file, line, func, __spirv_GlobalInvocationId_x(), + __spirv_GlobalInvocationId_y(), __spirv_GlobalInvocationId_z(), + __spirv_LocalInvocationId_x(), __spirv_LocalInvocationId_y(), + __spirv_LocalInvocationId_z()); +} +#elif defined(__DEVICELIB_MSLIBC__) +// Truncates a wide (16 or 32 bit) string (wstr) into an ASCII string (str). +// Any non-ASCII characters are replaced by question mark '?'. +static inline void __truncate_wchar_char_str(const wchar_t *wstr, char *str, + size_t str_size) { + str_size -= 1; // reserve for NULL terminator + while (str_size > 0 && *wstr != L'\0') { + wchar_t w = *wstr++; + *str++ = (w > 0 && w < 127) ? (char)w : '?'; + str_size--; + } + *str = '\0'; +} + +EXTERN_C inline void _wassert(const wchar_t *wexpr, const wchar_t *wfile, + unsigned line) { + // Paths and expressions that are longer than 256 characters are going to be + // truncated. + char file[256]; + __truncate_wchar_char_str(wfile, file, sizeof(file)); + char expr[256]; + __truncate_wchar_char_str(wexpr, expr, sizeof(expr)); + + __devicelib_assert_fail( + expr, file, line, /*func=*/nullptr, __spirv_GlobalInvocationId_x(), + __spirv_GlobalInvocationId_y(), __spirv_GlobalInvocationId_z(), + __spirv_LocalInvocationId_x(), __spirv_LocalInvocationId_y(), + __spirv_LocalInvocationId_z()); +} + +#endif + +#endif // __DEVICELIB_DEVICE_ONLY__ +#endif // __DEVICELIB_ASSERT_H__ diff --git a/clang/lib/Headers/devicelib/spirv_vars.h b/clang/lib/Headers/devicelib/spirv_vars.h new file mode 100644 index 0000000000000..43958278b9b29 --- /dev/null +++ b/clang/lib/Headers/devicelib/spirv_vars.h @@ -0,0 +1,147 @@ +//==---------- spirv_vars.hpp --- SPIRV variables -------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// ===-------------------------------------------------------------------=== // + +#ifndef __SPIRV_VARS_H__ +#define __SPIRV_VARS_H__ + +#include +#include + +#ifdef __cplusplus +#define __EXTERN_C extern "C" +#else +#define __EXTERN_C +#endif + +#ifdef __SYCL_DEVICE_ONLY__ + +#ifdef __SYCL_NVPTX__ + +SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_x(); +SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_y(); +SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_z(); + +SYCL_EXTERNAL size_t __spirv_GlobalSize_x(); +SYCL_EXTERNAL size_t __spirv_GlobalSize_y(); +SYCL_EXTERNAL size_t __spirv_GlobalSize_z(); + +SYCL_EXTERNAL size_t __spirv_GlobalOffset_x(); +SYCL_EXTERNAL size_t __spirv_GlobalOffset_y(); +SYCL_EXTERNAL size_t __spirv_GlobalOffset_z(); + +SYCL_EXTERNAL size_t __spirv_NumWorkgroups_x(); +SYCL_EXTERNAL size_t __spirv_NumWorkgroups_y(); +SYCL_EXTERNAL size_t __spirv_NumWorkgroups_z(); + +SYCL_EXTERNAL size_t __spirv_WorkgroupSize_x(); +SYCL_EXTERNAL size_t __spirv_WorkgroupSize_y(); +SYCL_EXTERNAL size_t __spirv_WorkgroupSize_z(); + +SYCL_EXTERNAL size_t __spirv_WorkgroupId_x(); +SYCL_EXTERNAL size_t __spirv_WorkgroupId_y(); +SYCL_EXTERNAL size_t __spirv_WorkgroupId_z(); + +SYCL_EXTERNAL size_t __spirv_LocalInvocationId_x(); +SYCL_EXTERNAL size_t __spirv_LocalInvocationId_y(); +SYCL_EXTERNAL size_t __spirv_LocalInvocationId_z(); + +#else // __SYCL_NVPTX__ + +typedef size_t size_t_vec __attribute__((ext_vector_type(3))); +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInGlobalInvocationId; +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInGlobalSize; +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInGlobalOffset; +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInNumWorkgroups; +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInWorkgroupSize; +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInWorkgroupId; +__EXTERN_C const __attribute__((opencl_constant)) +size_t_vec __spirv_BuiltInLocalInvocationId; + +SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_x() { + return __spirv_BuiltInGlobalInvocationId.x; +} +SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_y() { + return __spirv_BuiltInGlobalInvocationId.y; +} +SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_z() { + return __spirv_BuiltInGlobalInvocationId.z; +} + +SYCL_EXTERNAL inline size_t __spirv_GlobalSize_x() { + return __spirv_BuiltInGlobalSize.x; +} +SYCL_EXTERNAL inline size_t __spirv_GlobalSize_y() { + return __spirv_BuiltInGlobalSize.y; +} +SYCL_EXTERNAL inline size_t __spirv_GlobalSize_z() { + return __spirv_BuiltInGlobalSize.z; +} + +SYCL_EXTERNAL inline size_t __spirv_GlobalOffset_x() { + return __spirv_BuiltInGlobalOffset.x; +} +SYCL_EXTERNAL inline size_t __spirv_GlobalOffset_y() { + return __spirv_BuiltInGlobalOffset.y; +} +SYCL_EXTERNAL inline size_t __spirv_GlobalOffset_z() { + return __spirv_BuiltInGlobalOffset.z; +} + +SYCL_EXTERNAL inline size_t __spirv_NumWorkgroups_x() { + return __spirv_BuiltInNumWorkgroups.x; +} +SYCL_EXTERNAL inline size_t __spirv_NumWorkgroups_y() { + return __spirv_BuiltInNumWorkgroups.y; +} +SYCL_EXTERNAL inline size_t __spirv_NumWorkgroups_z() { + return __spirv_BuiltInNumWorkgroups.z; +} + +SYCL_EXTERNAL inline size_t __spirv_WorkgroupSize_x() { + return __spirv_BuiltInWorkgroupSize.x; +} +SYCL_EXTERNAL inline size_t __spirv_WorkgroupSize_y() { + return __spirv_BuiltInWorkgroupSize.y; +} +SYCL_EXTERNAL inline size_t __spirv_WorkgroupSize_z() { + return __spirv_BuiltInWorkgroupSize.z; +} + +SYCL_EXTERNAL inline size_t __spirv_WorkgroupId_x() { + return __spirv_BuiltInWorkgroupId.x; +} +SYCL_EXTERNAL inline size_t __spirv_WorkgroupId_y() { + return __spirv_BuiltInWorkgroupId.y; +} +SYCL_EXTERNAL inline size_t __spirv_WorkgroupId_z() { + return __spirv_BuiltInWorkgroupId.z; +} + +SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_x() { + return __spirv_BuiltInLocalInvocationId.x; +} +SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_y() { + return __spirv_BuiltInLocalInvocationId.y; +} +SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_z() { + return __spirv_BuiltInLocalInvocationId.z; +} + +#endif // __SYCL_NVPTX__ + +#endif // __SYCL_DEVICE_ONLY__ + +#undef __EXTERN_C + +#endif // __SPIRV_VARS_H__ diff --git a/clang/test/Driver/sycl-device.cpp b/clang/test/Driver/sycl-device.cpp index 0cb2c327ba8ca..b8515dfdfbf22 100644 --- a/clang/test/Driver/sycl-device.cpp +++ b/clang/test/Driver/sycl-device.cpp @@ -8,6 +8,9 @@ // RUN: | FileCheck -check-prefix=CHECK-SYCL-DEV %s // CHECK-SYCL-DEV: "-fsycl-is-device"{{.*}} "-internal-isystem" "{{.*}}bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl" +/// Check that devicelib include path is added +// CHECK-SYCL-DEV: "-include" "devicelib{{[/\\]}}__devicelib_assert.h" + /// Check that "-Wno-sycl-strict" is set on compiler invocation with "-fsycl" /// or "-fsycl-device-only" or both: // RUN: %clang -### -fsycl %s 2>&1 \ diff --git a/libdevice/cmake/modules/SYCLLibdevice.cmake b/libdevice/cmake/modules/SYCLLibdevice.cmake index 847cac46f4a42..d16fb8ee7e7f2 100644 --- a/libdevice/cmake/modules/SYCLLibdevice.cmake +++ b/libdevice/cmake/modules/SYCLLibdevice.cmake @@ -18,28 +18,6 @@ set(compile_opts -sycl-std=2017 ) -if (WIN32) - set(devicelib-obj-file ${binary_dir}/libsycl-msvc.o) - add_custom_command(OUTPUT ${devicelib-obj-file} - COMMAND ${clang} -fsycl -c - ${compile_opts} - ${CMAKE_CURRENT_SOURCE_DIR}/msvc_wrapper.cpp - -o ${devicelib-obj-file} - MAIN_DEPENDENCY msvc_wrapper.cpp - DEPENDS wrapper.h device.h clang - VERBATIM) -else() - set(devicelib-obj-file ${binary_dir}/libsycl-glibc.o) - add_custom_command(OUTPUT ${devicelib-obj-file} - COMMAND ${clang} -fsycl -c - ${compile_opts} - ${CMAKE_CURRENT_SOURCE_DIR}/glibc_wrapper.cpp - -o ${devicelib-obj-file} - MAIN_DEPENDENCY glibc_wrapper.cpp - DEPENDS wrapper.h device.h clang - VERBATIM) -endif() - set(devicelib-obj-complex ${binary_dir}/libsycl-complex.o) add_custom_command(OUTPUT ${devicelib-obj-complex} COMMAND ${clang} -fsycl -c @@ -126,7 +104,6 @@ add_custom_command(OUTPUT ${binary_dir}/libsycl-fallback-cmath-fp64.spv VERBATIM) add_custom_target(libsycldevice-obj DEPENDS - ${devicelib-obj-file} ${devicelib-obj-complex} ${devicelib-obj-complex-fp64} ${devicelib-obj-cmath} @@ -149,8 +126,7 @@ else() set(install_dest lib${LLVM_LIBDIR_SUFFIX}) endif() -install(FILES ${devicelib-obj-file} - ${binary_dir}/libsycl-fallback-cassert.spv +install(FILES ${binary_dir}/libsycl-fallback-cassert.spv ${devicelib-obj-complex} ${binary_dir}/libsycl-fallback-complex.spv ${devicelib-obj-complex-fp64} diff --git a/libdevice/device.h b/libdevice/device.h index 72b2511e63e83..537d499085f7f 100644 --- a/libdevice/device.h +++ b/libdevice/device.h @@ -11,7 +11,9 @@ // We need the following header to ensure the definition of all spirv variables // required by the wrapper libraries. -#include "spirv_vars.hpp" +// +// Include from clang internal headers +#include "devicelib/spirv_vars.h" #ifdef __cplusplus #define EXTERN_C extern "C" diff --git a/libdevice/spirv_vars.hpp b/libdevice/spirv_vars.hpp deleted file mode 100644 index c1cd0358f62e1..0000000000000 --- a/libdevice/spirv_vars.hpp +++ /dev/null @@ -1,102 +0,0 @@ -//==---------- spirv_vars.hpp --- SPIRV variables -------------------------==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// ===-------------------------------------------------------------------=== // - -#pragma once - -#include -#include - -#ifdef __SYCL_DEVICE_ONLY__ - -#ifdef __SYCL_NVPTX__ - -SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_x(); -SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_y(); -SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_z(); - -SYCL_EXTERNAL size_t __spirv_LocalInvocationId_x(); -SYCL_EXTERNAL size_t __spirv_LocalInvocationId_y(); -SYCL_EXTERNAL size_t __spirv_LocalInvocationId_z(); - -#else // __SYCL_NVPTX__ - -typedef size_t size_t_vec __attribute__((ext_vector_type(3))); -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInGlobalInvocationId; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInLocalInvocationId; - -SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_x() { - return __spirv_BuiltInGlobalInvocationId.x; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_y() { - return __spirv_BuiltInGlobalInvocationId.y; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_z() { - return __spirv_BuiltInGlobalInvocationId.z; -} - -SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_x() { - return __spirv_BuiltInLocalInvocationId.x; -} -SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_y() { - return __spirv_BuiltInLocalInvocationId.y; -} -SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_z() { - return __spirv_BuiltInLocalInvocationId.z; -} - -#endif // __SYCL_NVPTX__ - -#define DEFINE_FUNC_ID_TO_XYZ_CONVERTER(POSTFIX) \ - template static inline size_t get##POSTFIX(); \ - template <> size_t get##POSTFIX<0>() { return __spirv_##POSTFIX##_x(); } \ - template <> size_t get##POSTFIX<1>() { return __spirv_##POSTFIX##_y(); } \ - template <> size_t get##POSTFIX<2>() { return __spirv_##POSTFIX##_z(); } - -namespace __spirv { - -DEFINE_FUNC_ID_TO_XYZ_CONVERTER(GlobalInvocationId); -DEFINE_FUNC_ID_TO_XYZ_CONVERTER(LocalInvocationId); - -} // namespace __spirv - -#undef DEFINE_FUNC_ID_TO_XYZ_CONVERTER - -#define DEFINE_INIT_SIZES(POSTFIX) \ - \ - template struct InitSizesST##POSTFIX; \ - \ - template struct InitSizesST##POSTFIX<1, DstT> { \ - static DstT initSize() { return {get##POSTFIX<0>()}; } \ - }; \ - \ - template struct InitSizesST##POSTFIX<2, DstT> { \ - static DstT initSize() { return {get##POSTFIX<1>(), get##POSTFIX<0>()}; } \ - }; \ - \ - template struct InitSizesST##POSTFIX<3, DstT> { \ - static DstT initSize() { \ - return {get##POSTFIX<2>(), get##POSTFIX<1>(), get##POSTFIX<0>()}; \ - } \ - }; \ - \ - template static DstT init##POSTFIX() { \ - return InitSizesST##POSTFIX::initSize(); \ - } - -namespace __spirv { - -DEFINE_INIT_SIZES(GlobalInvocationId) -DEFINE_INIT_SIZES(LocalInvocationId) - -} // namespace __spirv - -#undef DEFINE_INIT_SIZES - -#endif // __SYCL_DEVICE_ONLY__ diff --git a/sycl/doc/extensions/C-CXX-StandardLibrary/C-CXX-StandardLibrary.rst b/sycl/doc/extensions/C-CXX-StandardLibrary/C-CXX-StandardLibrary.rst index 608739b3521ed..139e334c1c17f 100644 --- a/sycl/doc/extensions/C-CXX-StandardLibrary/C-CXX-StandardLibrary.rst +++ b/sycl/doc/extensions/C-CXX-StandardLibrary/C-CXX-StandardLibrary.rst @@ -22,6 +22,10 @@ or, in case of Windows: clang++ -fsycl -c main.cpp -o main.obj clang++ -fsycl main.obj %SYCL_INSTALL%/lib/libsycl-msvc.o -o a.exe +NOTE: `assert` macro no longer requires to link a device library +object file. Other functions still require corresponding device +libraries to be linked. + List of supported functions from C standard library: - assert macro (from or ) - logf, log (from or ) @@ -210,6 +214,10 @@ definitions for glibc specific library function, and these definitions call the corresponding functions from `__devicelib_*` set of functions. +NOTE: a new approach is used for `assert` now, see `Header-based +wrappers`_ section for details. Other functions still use wrappers as +object files. + For example, `__assert_fail` from IR above gets transformed into: .. code: ; Function Attrs: noreturn nounwind @@ -232,6 +240,30 @@ glibc) has its own wrapper library object: - libsycl-glibc.o - libsycl-msvc.o +Header-based wrappers +===================== + +Wrappers around standard library functions can be provided in header +files: + +.. code: + #ifdef __DEVICELIB_GLIBC__ + extern "C" inline void + __assert_fail(const char *expr, const char *file, + unsigned int line, const char *func) { + // call __devicelib_assert_fail(...) + } + #elif defined(__DEVICELIB_MSLIBC__) + extern "C" inline void _wassert(const wchar_t *wexpr, const wchar_t *wfile, + unsigned line) { + // call __devicelib_assert_fail(...) + } + #endif + +These header files are automatically included by the Clang driver for +SYCL device compilation (SPIR target). + + SPIR-V ====== diff --git a/sycl/include/CL/__spirv/spirv_vars.hpp b/sycl/include/CL/__spirv/spirv_vars.hpp index 8d46b68872672..293705dec3e69 100644 --- a/sycl/include/CL/__spirv/spirv_vars.hpp +++ b/sycl/include/CL/__spirv/spirv_vars.hpp @@ -13,125 +13,7 @@ #ifdef __SYCL_DEVICE_ONLY__ -#ifdef __SYCL_NVPTX__ - -SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_x(); -SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_y(); -SYCL_EXTERNAL size_t __spirv_GlobalInvocationId_z(); - -SYCL_EXTERNAL size_t __spirv_GlobalSize_x(); -SYCL_EXTERNAL size_t __spirv_GlobalSize_y(); -SYCL_EXTERNAL size_t __spirv_GlobalSize_z(); - -SYCL_EXTERNAL size_t __spirv_GlobalOffset_x(); -SYCL_EXTERNAL size_t __spirv_GlobalOffset_y(); -SYCL_EXTERNAL size_t __spirv_GlobalOffset_z(); - -SYCL_EXTERNAL size_t __spirv_NumWorkgroups_x(); -SYCL_EXTERNAL size_t __spirv_NumWorkgroups_y(); -SYCL_EXTERNAL size_t __spirv_NumWorkgroups_z(); - -SYCL_EXTERNAL size_t __spirv_WorkgroupSize_x(); -SYCL_EXTERNAL size_t __spirv_WorkgroupSize_y(); -SYCL_EXTERNAL size_t __spirv_WorkgroupSize_z(); - -SYCL_EXTERNAL size_t __spirv_WorkgroupId_x(); -SYCL_EXTERNAL size_t __spirv_WorkgroupId_y(); -SYCL_EXTERNAL size_t __spirv_WorkgroupId_z(); - -SYCL_EXTERNAL size_t __spirv_LocalInvocationId_x(); -SYCL_EXTERNAL size_t __spirv_LocalInvocationId_y(); -SYCL_EXTERNAL size_t __spirv_LocalInvocationId_z(); - -#else // __SYCL_NVPTX__ - -typedef size_t size_t_vec __attribute__((ext_vector_type(3))); -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInGlobalInvocationId; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInGlobalSize; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInGlobalOffset; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInNumWorkgroups; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInWorkgroupSize; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInWorkgroupId; -extern "C" const __attribute__((opencl_constant)) -size_t_vec __spirv_BuiltInLocalInvocationId; - -SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_x() { - return __spirv_BuiltInGlobalInvocationId.x; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_y() { - return __spirv_BuiltInGlobalInvocationId.y; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalInvocationId_z() { - return __spirv_BuiltInGlobalInvocationId.z; -} - -SYCL_EXTERNAL inline size_t __spirv_GlobalSize_x() { - return __spirv_BuiltInGlobalSize.x; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalSize_y() { - return __spirv_BuiltInGlobalSize.y; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalSize_z() { - return __spirv_BuiltInGlobalSize.z; -} - -SYCL_EXTERNAL inline size_t __spirv_GlobalOffset_x() { - return __spirv_BuiltInGlobalOffset.x; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalOffset_y() { - return __spirv_BuiltInGlobalOffset.y; -} -SYCL_EXTERNAL inline size_t __spirv_GlobalOffset_z() { - return __spirv_BuiltInGlobalOffset.z; -} - -SYCL_EXTERNAL inline size_t __spirv_NumWorkgroups_x() { - return __spirv_BuiltInNumWorkgroups.x; -} -SYCL_EXTERNAL inline size_t __spirv_NumWorkgroups_y() { - return __spirv_BuiltInNumWorkgroups.y; -} -SYCL_EXTERNAL inline size_t __spirv_NumWorkgroups_z() { - return __spirv_BuiltInNumWorkgroups.z; -} - -SYCL_EXTERNAL inline size_t __spirv_WorkgroupSize_x() { - return __spirv_BuiltInWorkgroupSize.x; -} -SYCL_EXTERNAL inline size_t __spirv_WorkgroupSize_y() { - return __spirv_BuiltInWorkgroupSize.y; -} -SYCL_EXTERNAL inline size_t __spirv_WorkgroupSize_z() { - return __spirv_BuiltInWorkgroupSize.z; -} - -SYCL_EXTERNAL inline size_t __spirv_WorkgroupId_x() { - return __spirv_BuiltInWorkgroupId.x; -} -SYCL_EXTERNAL inline size_t __spirv_WorkgroupId_y() { - return __spirv_BuiltInWorkgroupId.y; -} -SYCL_EXTERNAL inline size_t __spirv_WorkgroupId_z() { - return __spirv_BuiltInWorkgroupId.z; -} - -SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_x() { - return __spirv_BuiltInLocalInvocationId.x; -} -SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_y() { - return __spirv_BuiltInLocalInvocationId.y; -} -SYCL_EXTERNAL inline size_t __spirv_LocalInvocationId_z() { - return __spirv_BuiltInLocalInvocationId.z; -} - -#endif // __SYCL_NVPTX__ +#include #define DEFINE_FUNC_ID_TO_XYZ_CONVERTER(POSTFIX) \ template static inline size_t get##POSTFIX(); \ diff --git a/sycl/include/CL/sycl/builtins.hpp b/sycl/include/CL/sycl/builtins.hpp index 400fd080cef1f..2def6c2285e7b 100644 --- a/sycl/include/CL/sycl/builtins.hpp +++ b/sycl/include/CL/sycl/builtins.hpp @@ -1546,18 +1546,4 @@ detail::enable_if_t::value, T> tan(T x) __NOEXC { } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) -#ifdef __SYCL_DEVICE_ONLY__ -#ifdef __GLIBC__ -extern "C" { -extern SYCL_EXTERNAL void __assert_fail(const char *expr, const char *file, - unsigned int line, const char *func); -} -#elif defined(_WIN32) -extern "C" { -extern SYCL_EXTERNAL void _wassert(const wchar_t *wexpr, const wchar_t *wfile, - unsigned line); -} -#endif -#endif // __SYCL_DEVICE_ONLY__ - #undef __NOEXC diff --git a/sycl/test/devicelib/assert-windows.cpp b/sycl/test/devicelib/assert-windows.cpp index fb38520601d98..01db1858e5e67 100644 --- a/sycl/test/devicelib/assert-windows.cpp +++ b/sycl/test/devicelib/assert-windows.cpp @@ -4,8 +4,7 @@ // Disable the test until the fix reaches SYCL test infrastructure. // XFAIL: * // -// RUN: %clangxx -fsycl -c %s -o %t.o -// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/../bin/libsycl-msvc.o -o %t.out +// RUN: %clangxx -fsycl %s -o %t.out // // MSVC implementation of assert does not call an unreachable built-in, so the // program doesn't terminate when fallback is used. diff --git a/sycl/test/devicelib/assert.cpp b/sycl/test/devicelib/assert.cpp index 9170d2557e283..6ec0feed12f59 100644 --- a/sycl/test/devicelib/assert.cpp +++ b/sycl/test/devicelib/assert.cpp @@ -1,6 +1,5 @@ // REQUIRES: cpu,linux -// RUN: %clangxx -fsycl -c %s -o %t.o -// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-glibc.o -o %t.out +// RUN: %clangxx -fsycl %s -o %t.out // (see the other RUN lines below; it is a bit complicated) // // assert() call in device code guarantees nothing: on some devices it behaves