From 34cc6acc81758e29f8c88607c21ab11d8807f87c Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 16 Jul 2020 15:18:55 -0400 Subject: Add ISPC compiler support to CMake --- Modules/CMakeCompilerIdDetection.cmake | 3 +- Modules/CMakeDetermineCompilerId.cmake | 22 +++++++ Modules/CMakeDetermineISPCCompiler.cmake | 96 +++++++++++++++++++++++++++++ Modules/CMakeISPCCompiler.cmake.in | 30 +++++++++ Modules/CMakeISPCCompilerABI.ispc | 20 ++++++ Modules/CMakeISPCCompilerId.ispc.in | 62 +++++++++++++++++++ Modules/CMakeISPCInformation.cmake | 56 +++++++++++++++++ Modules/CMakeTestISPCCompiler.cmake | 43 +++++++++++++ Modules/Compiler/Intel-ISPC.cmake | 22 +++++++ Source/cmCoreTryCompile.cxx | 12 ++++ Source/cmGeneratorExpressionNode.cxx | 5 +- Source/cmLocalUnixMakefileGenerator3.cxx | 6 +- Source/cmMakefileTargetGenerator.cxx | 3 +- Source/cmake.cxx | 3 + Source/cmake.h | 4 +- Tests/CMakeLists.txt | 4 ++ Tests/ISPC/CMakeLists.txt | 14 +++++ Tests/ISPC/Defines/CMakeLists.txt | 11 ++++ Tests/ISPC/Defines/main.cxx | 15 +++++ Tests/ISPC/Defines/simple.ispc | 15 +++++ Tests/ISPC/ObjectLibrary/CMakeLists.txt | 14 +++++ Tests/ISPC/ObjectLibrary/main.cxx | 15 +++++ Tests/ISPC/ObjectLibrary/simple.ispc | 12 ++++ Tests/ISPC/ResponseAndDefine/CMakeLists.txt | 24 ++++++++ Tests/ISPC/ResponseAndDefine/main.cxx | 15 +++++ Tests/ISPC/ResponseAndDefine/simple.ispc | 16 +++++ Tests/ISPC/StaticLibrary/CMakeLists.txt | 12 ++++ Tests/ISPC/StaticLibrary/main.cxx | 15 +++++ Tests/ISPC/StaticLibrary/simple.ispc | 12 ++++ Tests/ISPC/TryCompile/CMakeLists.txt | 16 +++++ Tests/ISPC/TryCompile/main.cxx | 19 ++++++ Tests/ISPC/TryCompile/simple.ispc | 12 ++++ 32 files changed, 621 insertions(+), 7 deletions(-) create mode 100644 Modules/CMakeDetermineISPCCompiler.cmake create mode 100644 Modules/CMakeISPCCompiler.cmake.in create mode 100644 Modules/CMakeISPCCompilerABI.ispc create mode 100644 Modules/CMakeISPCCompilerId.ispc.in create mode 100644 Modules/CMakeISPCInformation.cmake create mode 100644 Modules/CMakeTestISPCCompiler.cmake create mode 100644 Modules/Compiler/Intel-ISPC.cmake create mode 100644 Tests/ISPC/CMakeLists.txt create mode 100644 Tests/ISPC/Defines/CMakeLists.txt create mode 100644 Tests/ISPC/Defines/main.cxx create mode 100644 Tests/ISPC/Defines/simple.ispc create mode 100644 Tests/ISPC/ObjectLibrary/CMakeLists.txt create mode 100644 Tests/ISPC/ObjectLibrary/main.cxx create mode 100644 Tests/ISPC/ObjectLibrary/simple.ispc create mode 100644 Tests/ISPC/ResponseAndDefine/CMakeLists.txt create mode 100644 Tests/ISPC/ResponseAndDefine/main.cxx create mode 100644 Tests/ISPC/ResponseAndDefine/simple.ispc create mode 100644 Tests/ISPC/StaticLibrary/CMakeLists.txt create mode 100644 Tests/ISPC/StaticLibrary/main.cxx create mode 100644 Tests/ISPC/StaticLibrary/simple.ispc create mode 100644 Tests/ISPC/TryCompile/CMakeLists.txt create mode 100644 Tests/ISPC/TryCompile/main.cxx create mode 100644 Tests/ISPC/TryCompile/simple.ispc diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index acd15df..a0f0dfa 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -13,7 +13,8 @@ endfunction() function(compiler_id_detection outvar lang) - if (NOT lang STREQUAL Fortran AND NOT lang STREQUAL CSharp) + if (NOT lang STREQUAL Fortran AND NOT lang STREQUAL CSharp + AND NOT lang STREQUAL ISPC) file(GLOB lang_files "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake") set(nonlang CXX) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index d7a35e1..8724ed8 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -110,6 +110,28 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) endif() endif() + # For ISPC we need to explicitly query the version. + if(lang STREQUAL "ISPC" + AND CMAKE_${lang}_COMPILER + AND NOT CMAKE_${lang}_COMPILER_VERSION) + execute_process( + COMMAND "${CMAKE_${lang}_COMPILER}" + --version + OUTPUT_VARIABLE output ERROR_VARIABLE output + RESULT_VARIABLE result + TIMEOUT 10 + ) + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n" + "${output}\n" + ) + + if(output MATCHES [[ISPC\), ([0-9]+\.[0-9]+(\.[0-9]+)?)]]) + set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}") + endif() + endif() + + if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU") execute_process( COMMAND "${CMAKE_${lang}_COMPILER}" diff --git a/Modules/CMakeDetermineISPCCompiler.cmake b/Modules/CMakeDetermineISPCCompiler.cmake new file mode 100644 index 0000000..ff2bf20 --- /dev/null +++ b/Modules/CMakeDetermineISPCCompiler.cmake @@ -0,0 +1,96 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# determine the compiler to use for ISPC programs + +include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) + +if( NOT (("${CMAKE_GENERATOR}" MATCHES "Make") OR ("${CMAKE_GENERATOR}" MATCHES "Ninja")) ) + message(FATAL_ERROR "ISPC language not currently supported by \"${CMAKE_GENERATOR}\" generator") +endif() + +# Load system-specific compiler preferences for this language. +include(Platform/${CMAKE_SYSTEM_NAME}-Determine-ISPC OPTIONAL) +include(Platform/${CMAKE_SYSTEM_NAME}-ISPC OPTIONAL) +if(NOT CMAKE_ISPC_COMPILER_NAMES) + set(CMAKE_ISPC_COMPILER_NAMES ispc) +endif() + + +if(NOT CMAKE_ISPC_COMPILER) + + set(CMAKE_ISPC_COMPILER_INIT NOTFOUND) + + # prefer the environment variable CC + if(NOT $ENV{ISPC} STREQUAL "") + get_filename_component(CMAKE_ISPC_COMPILER_INIT $ENV{ISPC} PROGRAM PROGRAM_ARGS CMAKE_ISPC_FLAGS_ENV_INIT) + if(CMAKE_ISPC_FLAGS_ENV_INIT) + set(CMAKE_ISPC_COMPILER_ARG1 "${CMAKE_ISPC_FLAGS_ENV_INIT}" CACHE STRING "First argument to ISPC compiler") + endif() + if(NOT EXISTS ${CMAKE_ISPC_COMPILER_INIT}) + message(FATAL_ERROR "Could not find compiler set in environment variable ISPC:\n$ENV{ISPC}.") + endif() + endif() + + # next try prefer the compiler specified by the generator + if(CMAKE_GENERATOR_ISPC) + if(NOT CMAKE_ISPC_COMPILER_INIT) + set(CMAKE_ISPC_COMPILER_INIT ${CMAKE_GENERATOR_ISPC}) + endif() + endif() + + # finally list compilers to try + if(NOT CMAKE_ISPC_COMPILER_INIT) + set(CMAKE_ISPC_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}ispc ispc) + endif() + + # Find the compiler. + _cmake_find_compiler(ISPC) + +else() + _cmake_find_compiler_path(ISPC) +endif() +mark_as_advanced(CMAKE_ISPC_COMPILER) + +if(NOT CMAKE_ISPC_COMPILER_ID_RUN) +set(CMAKE_ISPC_COMPILER_ID_RUN 1) + + # Try to identify the compiler. + set(CMAKE_ISPC_COMPILER_ID) + set(CMAKE_ISPC_PLATFORM_ID) + + + set(CMAKE_ISPC_COMPILER_ID_TEST_FLAGS_FIRST + # setup logic to make sure ISPC outputs a file + "-o cmake_ispc_output" + ) + + include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) + CMAKE_DETERMINE_COMPILER_ID(ISPC ISPCFLAGS CMakeISPCCompilerId.ispc) + + _cmake_find_compiler_sysroot(ISPC) +endif() + +if (NOT _CMAKE_TOOLCHAIN_LOCATION) + get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_ISPC_COMPILER}" PATH) +endif () + +set(_CMAKE_PROCESSING_LANGUAGE "ISPC") +include(CMakeFindBinUtils) +include(Compiler/${CMAKE_ISPC_COMPILER_ID}-FindBinUtils OPTIONAL) +unset(_CMAKE_PROCESSING_LANGUAGE) + +if(CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH) + set(_SET_CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH + "set(CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH [==[${CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH}]==])") +else() + set(_SET_CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH "") +endif() + + +# configure variables set in this file for fast reload later on +configure_file(${CMAKE_ROOT}/Modules/CMakeISPCCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeISPCCompiler.cmake @ONLY) + +set(CMAKE_ISPC_COMPILER_ENV_VAR "ISPC") diff --git a/Modules/CMakeISPCCompiler.cmake.in b/Modules/CMakeISPCCompiler.cmake.in new file mode 100644 index 0000000..28c31cc --- /dev/null +++ b/Modules/CMakeISPCCompiler.cmake.in @@ -0,0 +1,30 @@ +set(CMAKE_ISPC_COMPILER "@CMAKE_ISPC_COMPILER@") +set(CMAKE_ISPC_COMPILER_ARG1 "@CMAKE_ISPC_COMPILER_ARG1@") +set(CMAKE_ISPC_COMPILER_ID "@CMAKE_ISPC_COMPILER_ID@") +set(CMAKE_ISPC_COMPILER_VERSION "@CMAKE_ISPC_COMPILER_VERSION@") +set(CMAKE_ISPC_COMPILER_VERSION_INTERNAL "@CMAKE_ISPC_COMPILER_VERSION_INTERNAL@") + +set(CMAKE_ISPC_PLATFORM_ID "@CMAKE_ISPC_PLATFORM_ID@") +set(CMAKE_ISPC_SIMULATE_ID "@CMAKE_ISPC_SIMULATE_ID@") +set(CMAKE_ISPC_COMPILER_FRONTEND_VARIANT "@CMAKE_ISPC_COMPILER_FRONTEND_VARIANT@") +set(CMAKE_ISPC_SIMULATE_VERSION "@CMAKE_ISPC_SIMULATE_VERSION@") + +set(CMAKE_AR "@CMAKE_AR@") +set(CMAKE_ISPC_COMPILER_AR "@CMAKE_ISPC_COMPILER_AR@") +set(CMAKE_RANLIB "@CMAKE_RANLIB@") +set(CMAKE_ISPC_COMPILER_RANLIB "@CMAKE_ISPC_COMPILER_RANLIB@") + +set(CMAKE_ISPC_COMPILER_LOADED 1) +set(CMAKE_ISPC_COMPILER_WORKS @CMAKE_ISPC_COMPILER_WORKS@) +set(CMAKE_ISPC_ABI_COMPILED @CMAKE_ISPC_ABI_COMPILED@) + +set(CMAKE_ISPC_COMPILER_ENV_VAR "ISPC") + +set(CMAKE_ISPC_COMPILER_ID_RUN 1) +set(CMAKE_ISPC_SOURCE_FILE_EXTENSIONS ispc) +set(CMAKE_ISPC_IGNORE_EXTENSIONS o;O) + +set(CMAKE_ISPC_LINKER_PREFERENCE 0) +set(CMAKE_ISPC_LINKER_PREFERENCE_PROPAGATES 0) + +@CMAKE_ISPC_COMPILER_CUSTOM_CODE@ diff --git a/Modules/CMakeISPCCompilerABI.ispc b/Modules/CMakeISPCCompilerABI.ispc new file mode 100644 index 0000000..e23abce --- /dev/null +++ b/Modules/CMakeISPCCompilerABI.ispc @@ -0,0 +1,20 @@ + +export void ispcCompilerABI() { + +#if defined(__GNU__) && defined(__ELF__) && defined(__ARM_EABI__) + print("INFO:abi[ELF ARMEABI]"); + static char const info_abi[] = +#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEB__) + print("INFO:abi[ELF ARM]"); +#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEL__) + print("INFO:abi[ELF ARM]"); + +#elif defined(__linux__) && defined(__ELF__) && defined(__amd64__) && \ + defined(__ILP32__) +print("INFO:abi[ELF X32]"); + +#elif defined(__ELF__) +print("INFO:abi[ELF]"); +#endif + +} diff --git a/Modules/CMakeISPCCompilerId.ispc.in b/Modules/CMakeISPCCompilerId.ispc.in new file mode 100644 index 0000000..03380f3 --- /dev/null +++ b/Modules/CMakeISPCCompilerId.ispc.in @@ -0,0 +1,62 @@ + +export void ispcCompilerId() { + +// Identify the compiler +#if defined(ISPC) + print("INFO:compiler[Intel]"); +#endif + +// Identify the platform +#if defined(__linux) || defined(__linux__) || defined(linux) + print("INFO:platform[Linux]"); +#elif defined(__CYGWIN__) + print("INFO:platform[Cygwin]"); +#elif defined(__MINGW32__) + print("INFO:platform[MinGW]"); +#elif defined(__APPLE__) + print("INFO:platform[Darwin]"); +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + print("INFO:platform[Windows]"); +#elif defined(__FreeBSD__) || defined(__FreeBSD) + print("INFO:platform[FreeBSD]"); +#elif defined(__NetBSD__) || defined(__NetBSD) + print("INFO:platform[NetBSD]"); +#elif defined(__OpenBSD__) || defined(__OPENBSD) + print("INFO:platform[OpenBSD]"); +#elif defined(__sun) || defined(sun) + print("INFO:platform[SunOS]"); +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) + print("INFO:platform[AIX]"); +#elif defined(__hpux) || defined(__hpux__) + print("INFO:platform[HP-UX]"); +#elif defined(__HAIKU__) + print("INFO:platform[Haiku]"); +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) + print("INFO:platform[BeOS]"); +#elif defined(__QNX__) || defined(__QNXNTO__) + print("INFO:platform[QNX]"); +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) + print("INFO:platform[Tru64]"); +#elif defined(__riscos) || defined(__riscos__) + print("INFO:platform[RISCos]"); +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) + print("INFO:platform[SINIX]"); +#elif defined(__UNIX_SV__) + print("INFO:platform[UNIX_SV]"); +#elif defined(__bsdos__) + print("INFO:platform[BSDOS]"); +#elif defined(_MPRAS) || defined(MPRAS) + print("INFO:platform[MP-RAS]"); +#elif defined(__osf) || defined(__osf__) + print("INFO:platform[OSF1]"); +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) + print("INFO:platform[SCO_SV]"); +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) + print("INFO:platform[ULTRIX]"); +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) + print("INFO:platform[Xenix]"); +#else + print("INFO:platform[]"); +#endif + +} diff --git a/Modules/CMakeISPCInformation.cmake b/Modules/CMakeISPCInformation.cmake new file mode 100644 index 0000000..37057d9 --- /dev/null +++ b/Modules/CMakeISPCInformation.cmake @@ -0,0 +1,56 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +set(CMAKE_ISPC_OUTPUT_EXTENSION .o) +set(CMAKE_INCLUDE_FLAG_ISPC "-I") + +# Load compiler-specific information. +if(CMAKE_ISPC_COMPILER_ID) + include(Compiler/${CMAKE_ISPC_COMPILER_ID}-ISPC OPTIONAL) +endif() + +# load the system- and compiler specific files +if(CMAKE_ISPC_COMPILER_ID) + # load a hardware specific file, mostly useful for embedded compilers + if(CMAKE_SYSTEM_PROCESSOR) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ISPC_COMPILER_ID}-ISPC-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + endif() + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ISPC_COMPILER_ID}-ISPC OPTIONAL) +endif() + +# add the flags to the cache based +# on the initial values computed in the platform/*.cmake files +# use _INIT variables so that this only happens the first time +# and you can set these flags in the cmake cache +set(CMAKE_ISPC_FLAGS_INIT "$ENV{ISPCFLAGS} ${CMAKE_ISPC_FLAGS_INIT}") + +cmake_initialize_per_config_variable(CMAKE_ISPC_FLAGS "Flags used by the ISPC compiler") + +if(CMAKE_ISPC_STANDARD_LIBRARIES_INIT) + set(CMAKE_ISPC_STANDARD_LIBRARIES "${CMAKE_ISPC_STANDARD_LIBRARIES_INIT}" + CACHE STRING "Libraries linked by default with all ISPC applications.") + mark_as_advanced(CMAKE_ISPC_STANDARD_LIBRARIES) +endif() + +include(CMakeCommonLanguageInclude) + +# now define the following rules: +# CMAKE_ISPC_COMPILE_OBJECT + +# Create a static archive incrementally for large object file counts. +if(NOT DEFINED CMAKE_ISPC_ARCHIVE_CREATE) + set(CMAKE_ISPC_ARCHIVE_CREATE " qc ") +endif() +if(NOT DEFINED CMAKE_ISPC_ARCHIVE_APPEND) + set(CMAKE_ISPC_ARCHIVE_APPEND " q ") +endif() +if(NOT DEFINED CMAKE_ISPC_ARCHIVE_FINISH) + set(CMAKE_ISPC_ARCHIVE_FINISH " ") +endif() + +if(NOT CMAKE_ISPC_COMPILE_OBJECT) + set(CMAKE_ISPC_COMPILE_OBJECT + " -o --emit-obj ") +endif() + +set(CMAKE_ISPC_INFORMATION_LOADED 1) diff --git a/Modules/CMakeTestISPCCompiler.cmake b/Modules/CMakeTestISPCCompiler.cmake new file mode 100644 index 0000000..6b16393 --- /dev/null +++ b/Modules/CMakeTestISPCCompiler.cmake @@ -0,0 +1,43 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + + +if(CMAKE_ISPC_COMPILER_FORCED) + # The compiler configuration was forced by the user. + # Assume the user has configured all compiler information. + set(CMAKE_ISPC_COMPILER_WORKS TRUE) + return() +endif() + +include(CMakeTestCompilerCommon) + +# Make sure we try to compile as a STATIC_LIBRARY +set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE}) +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +# # Try to identify the ABI and configure it into CMakeISPCCompiler.cmake +include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake) +CMAKE_DETERMINE_COMPILER_ABI(ISPC ${CMAKE_ROOT}/Modules/CMakeISPCCompilerABI.ispc) +if(CMAKE_ISPC_ABI_COMPILED) +# # The compiler worked so skip dedicated test below. + set(CMAKE_ISPC_COMPILER_WORKS TRUE) + message(STATUS "Check for working ISPC compiler: ${CMAKE_ISPC_COMPILER} - skipped") +endif() + +# Re-configure to save learned information. +configure_file( + ${CMAKE_ROOT}/Modules/CMakeISPCCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeISPCCompiler.cmake + @ONLY + ) +include(${CMAKE_PLATFORM_INFO_DIR}/CMakeISPCCompiler.cmake) + +if(CMAKE_ISPC_SIZEOF_DATA_PTR) + foreach(f ${CMAKE_ISPC_ABI_FILES}) + include(${f}) + endforeach() + unset(CMAKE_ISPC_ABI_FILES) +endif() + +set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE}) diff --git a/Modules/Compiler/Intel-ISPC.cmake b/Modules/Compiler/Intel-ISPC.cmake new file mode 100644 index 0000000..2e9792a --- /dev/null +++ b/Modules/Compiler/Intel-ISPC.cmake @@ -0,0 +1,22 @@ +include(Compiler/CMakeCommonCompilerMacros) + +# Not aware of any verbose flag for ISPC +#set(CMAKE_ISPC_VERBOSE_FLAG ) + +set(CMAKE_DEPFILE_FLAGS_ISPC "-M -MT -MF ") + +string(APPEND CMAKE_ISPC_FLAGS_INIT " ") +string(APPEND CMAKE_ISPC_FLAGS_DEBUG_INIT "-O0 -g") +string(APPEND CMAKE_ISPC_FLAGS_RELEASE_INIT " -O3 -DNDEBUG") +string(APPEND CMAKE_ISPC_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG") +string(APPEND CMAKE_ISPC_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG") + +set(CMAKE_ISPC_COMPILE_OPTIONS_PIE --pic) +set(CMAKE_ISPC_COMPILE_OPTIONS_PIC --pic) + +set(CMAKE_INCLUDE_SYSTEM_FLAG_ISPC -isystem=) + +set(CMAKE_ISPC_RESPONSE_FILE_FLAG "@") +set(CMAKE_ISPC_USE_RESPONSE_FILE_FOR_INCLUDES 1) +set(CMAKE_ISPC_USE_RESPONSE_FILE_FOR_LIBRARIES 1) +set(CMAKE_ISPC_USE_RESPONSE_FILE_FOR_OBJECTS 1) diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 63c1484..b9b91f6 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -192,6 +192,8 @@ SETUP_LANGUAGE(objc_properties, OBJC); // NOLINTNEXTLINE(bugprone-suspicious-missing-comma) SETUP_LANGUAGE(objcxx_properties, OBJCXX); // NOLINTNEXTLINE(bugprone-suspicious-missing-comma) +SETUP_LANGUAGE(ispc_properties, ISPC); +// NOLINTNEXTLINE(bugprone-suspicious-missing-comma) SETUP_LANGUAGE(swift_properties, Swift); #undef SETUP_LANGUAGE @@ -499,6 +501,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv, } } + // when the only language is ISPC we know that the output + // type must by a static library + if (testLangs.size() == 1 && testLangs.count("ISPC") == 1) { + targetType = cmStateEnums::STATIC_LIBRARY; + } + std::string const tcConfig = this->Makefile->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); @@ -702,6 +710,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv, vars.insert( &objcxx_properties[lang_property_start], &objcxx_properties[lang_property_start + lang_property_size]); + vars.insert(&ispc_properties[lang_property_start], + &ispc_properties[lang_property_start + lang_property_size]); vars.insert(&swift_properties[lang_property_start], &swift_properties[lang_property_start + lang_property_size]); vars.insert(kCMAKE_CUDA_ARCHITECTURES); @@ -744,6 +754,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv, vars.insert( &objcxx_properties[pie_property_start], &objcxx_properties[pie_property_start + pie_property_size]); + vars.insert(&ispc_properties[pie_property_start], + &ispc_properties[pie_property_start + pie_property_size]); vars.insert(&swift_properties[pie_property_start], &swift_properties[pie_property_start + pie_property_size]); } diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index fdc8f29..83e9aac 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -715,7 +715,8 @@ struct CompilerIdNode : public cmGeneratorExpressionNode static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"), cudaCompilerIdNode("CUDA"), objcCompilerIdNode("OBJC"), - objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran"); + objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran"), + ispcCompilerIdNode("ISPC"); struct CompilerVersionNode : public cmGeneratorExpressionNode { @@ -780,7 +781,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode static const CompilerVersionNode cCompilerVersionNode("C"), cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"), objcCompilerVersionNode("OBJC"), objcxxCompilerVersionNode("OBJCXX"), - fortranCompilerVersionNode("Fortran"); + fortranCompilerVersionNode("Fortran"), ispcCompilerVersionNode("ISPC"); struct PlatformIdNode : public cmGeneratorExpressionNode { diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 8acd1e3..26b0989 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -235,7 +235,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() for (LocalObjectEntry const& entry : localObjectFile.second) { if (entry.Language == "C" || entry.Language == "CXX" || - entry.Language == "CUDA" || entry.Language == "Fortran") { + entry.Language == "CUDA" || entry.Language == "Fortran" || + entry.Language == "ISPC") { // Right now, C, C++, Fortran and CUDA have both a preprocessor and the // ability to generate assembly code lang_has_preprocessor = true; @@ -1444,7 +1445,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( // Create the scanner for this language std::unique_ptr scanner; if (lang == "C" || lang == "CXX" || lang == "RC" || lang == "ASM" || - lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA") { + lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA" || + lang == "ISPC") { // TODO: Handle RC (resource files) dependencies correctly. scanner = cm::make_unique(this, targetDir, lang, &validDeps); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 13c2fe9..854fc8b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -734,7 +734,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // ability to export compile commands bool lang_has_preprocessor = ((lang == "C") || (lang == "CXX") || (lang == "OBJC") || - (lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA")); + (lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA") || + lang == "ISPC"); bool const lang_has_assembly = lang_has_preprocessor; bool const lang_can_export_cmds = lang_has_preprocessor; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index dcb96f8..1d4cacc 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -201,6 +201,7 @@ cmake::cmake(Role role, cmState::Mode mode) setupExts(this->CudaFileExtensions, { "cu" }); setupExts(this->FortranFileExtensions, { "f", "F", "for", "f77", "f90", "f95", "f03" }); + setupExts(this->ISPCFileExtensions, { "ispc" }); } } @@ -1971,6 +1972,8 @@ std::vector cmake::GetAllExtensions() const // cuda extensions are also in SourceFileExtensions so we ignore it here allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(), this->FortranFileExtensions.ordered.end()); + allExt.insert(allExt.end(), this->ISPCFileExtensions.ordered.begin(), + this->ISPCFileExtensions.ordered.end()); return allExt; } diff --git a/Source/cmake.h b/Source/cmake.h index 0c4f429..06ab8ac 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -268,7 +268,8 @@ public: { return this->CLikeSourceFileExtensions.Test(ext) || this->CudaFileExtensions.Test(ext) || - this->FortranFileExtensions.Test(ext); + this->FortranFileExtensions.Test(ext) || + this->ISPCFileExtensions.Test(ext); } bool IsACLikeSourceExtension(cm::string_view ext) const @@ -617,6 +618,7 @@ private: FileExtensions CLikeSourceFileExtensions; FileExtensions HeaderFileExtensions; FileExtensions CudaFileExtensions; + FileExtensions ISPCFileExtensions; FileExtensions FortranFileExtensions; bool ClearBuildSystem = false; bool DebugTryCompile = false; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4a774dd..0daf4ae 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1479,6 +1479,10 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH add_subdirectory(CudaOnly) endif() + if(CMake_TEST_ISPC) + add_subdirectory(ISPC) + endif() + if(CMake_TEST_FindGTest) add_subdirectory(FindGTest) add_subdirectory(GoogleTest) diff --git a/Tests/ISPC/CMakeLists.txt b/Tests/ISPC/CMakeLists.txt new file mode 100644 index 0000000..c8d58fd --- /dev/null +++ b/Tests/ISPC/CMakeLists.txt @@ -0,0 +1,14 @@ + + +macro (add_ispc_test_macro name) + add_test_macro("${name}" ${ARGN}) + set_property(TEST "${name}" APPEND + PROPERTY LABELS "ISPC") +endmacro () + +# set (ISPC_IA_TARGETS "sse2-i32x4,sse4-i32x4,avx1-i32x8,avx2-i32x8,avx512knl-i32x16,avx512skx-i32x16") + +add_ispc_test_macro(ISPC.Defines ISPCDefines) +add_ispc_test_macro(ISPC.ObjectLibrary ISPCObjectLibrary) +add_ispc_test_macro(ISPC.StaticLibrary ISPCStaticLibrary) +add_ispc_test_macro(ISPC.TryCompile ISPCTryCompile) diff --git a/Tests/ISPC/Defines/CMakeLists.txt b/Tests/ISPC/Defines/CMakeLists.txt new file mode 100644 index 0000000..2c9f4c3 --- /dev/null +++ b/Tests/ISPC/Defines/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.18) +project(ISPCDefines CXX ISPC) + +set(CMAKE_ISPC_FLAGS -DM_PI=3.1415926535f [==[-DSTRUCT_DEFINE=struct{uniform int a]==]) + +add_executable(ISPCResponseFile + main.cxx + simple.ispc + ) +set_target_properties(ISPCResponseFile PROPERTIES POSITION_INDEPENDENT_CODE ON) +target_include_directories(ISPCResponseFile PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/Tests/ISPC/Defines/main.cxx b/Tests/ISPC/Defines/main.cxx new file mode 100644 index 0000000..a6b91a6 --- /dev/null +++ b/Tests/ISPC/Defines/main.cxx @@ -0,0 +1,15 @@ +#include + +#include "simple_ispc.h" + +int main() +{ + float vin[16], vout[16]; + for (int i = 0; i < 16; ++i) + vin[i] = i; + + ispc::simple(vin, vout, 16); + + for (int i = 0; i < 16; ++i) + printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]); +} diff --git a/Tests/ISPC/Defines/simple.ispc b/Tests/ISPC/Defines/simple.ispc new file mode 100644 index 0000000..d8d6465 --- /dev/null +++ b/Tests/ISPC/Defines/simple.ispc @@ -0,0 +1,15 @@ + +//textual error if STRUCT_DEFINE not set +STRUCT_DEFINE;}; + +export void simple(uniform float vin[], uniform float vout[], + uniform int count) { + foreach (index = 0 ... count) { + float v = vin[index]; + if (v < M_PI) + v = v * v; + else + v = sqrt(v); + vout[index] = v; + } +} diff --git a/Tests/ISPC/ObjectLibrary/CMakeLists.txt b/Tests/ISPC/ObjectLibrary/CMakeLists.txt new file mode 100644 index 0000000..edfbdd8 --- /dev/null +++ b/Tests/ISPC/ObjectLibrary/CMakeLists.txt @@ -0,0 +1,14 @@ + +cmake_minimum_required(VERSION 3.18) +project(ISPCObjectLibrary CXX ISPC) + +set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON) + +add_library(ispc_objects OBJECT simple.ispc) + +target_compile_options(ispc_objects PRIVATE "$<$:--target=sse2-i32x4;--arch=x86-64>") +target_include_directories(ispc_objects INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") +set_target_properties(ispc_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) + +add_executable(ISPCObjectLibrary main.cxx) +target_link_libraries(ISPCObjectLibrary PRIVATE ispc_objects) diff --git a/Tests/ISPC/ObjectLibrary/main.cxx b/Tests/ISPC/ObjectLibrary/main.cxx new file mode 100644 index 0000000..a6b91a6 --- /dev/null +++ b/Tests/ISPC/ObjectLibrary/main.cxx @@ -0,0 +1,15 @@ +#include + +#include "simple_ispc.h" + +int main() +{ + float vin[16], vout[16]; + for (int i = 0; i < 16; ++i) + vin[i] = i; + + ispc::simple(vin, vout, 16); + + for (int i = 0; i < 16; ++i) + printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]); +} diff --git a/Tests/ISPC/ObjectLibrary/simple.ispc b/Tests/ISPC/ObjectLibrary/simple.ispc new file mode 100644 index 0000000..70cb588 --- /dev/null +++ b/Tests/ISPC/ObjectLibrary/simple.ispc @@ -0,0 +1,12 @@ + +export void simple(uniform float vin[], uniform float vout[], + uniform int count) { + foreach (index = 0 ... count) { + float v = vin[index]; + if (v < 3.) + v = v * v; + else + v = sqrt(v); + vout[index] = v; + } +} diff --git a/Tests/ISPC/ResponseAndDefine/CMakeLists.txt b/Tests/ISPC/ResponseAndDefine/CMakeLists.txt new file mode 100644 index 0000000..0dc5320 --- /dev/null +++ b/Tests/ISPC/ResponseAndDefine/CMakeLists.txt @@ -0,0 +1,24 @@ + +project(ispc_spaces_in_path) + +set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON) + +# Make sure we can handle an arg file with tricky defines including spaces in -I include +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/path with spaces/simple_include.h" +" + typedef float FLOAT_TYPE; +" +) + +add_executable(SpacesInPath main.cxx simple.ispc) +set_target_properties(SpacesInPath PROPERTIES POSITION_INDEPENDENT_CODE ON) +target_include_directories(SpacesInPath PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + +target_compile_options(SpacesInPath PRIVATE + "$<$:--target=sse2-i32x4;--arch=x86-64>") + +target_compile_definitions(SpacesInPath PRIVATE + "$<$:STRUCT_DEFINE=\"struct{uniform int a;varying int b;\";M_PI=3.1415926535f>") +target_include_directories(SpacesInPath PRIVATE + "$<$:\"fake path with spaces\">"" + "$<$:\"path with spaces\">") diff --git a/Tests/ISPC/ResponseAndDefine/main.cxx b/Tests/ISPC/ResponseAndDefine/main.cxx new file mode 100644 index 0000000..a6b91a6 --- /dev/null +++ b/Tests/ISPC/ResponseAndDefine/main.cxx @@ -0,0 +1,15 @@ +#include + +#include "simple_ispc.h" + +int main() +{ + float vin[16], vout[16]; + for (int i = 0; i < 16; ++i) + vin[i] = i; + + ispc::simple(vin, vout, 16); + + for (int i = 0; i < 16; ++i) + printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]); +} diff --git a/Tests/ISPC/ResponseAndDefine/simple.ispc b/Tests/ISPC/ResponseAndDefine/simple.ispc new file mode 100644 index 0000000..3f32c37 --- /dev/null +++ b/Tests/ISPC/ResponseAndDefine/simple.ispc @@ -0,0 +1,16 @@ + +STRUCT_DEFINE}; + +#include "simple_include.h" + +export void simple(uniform FLOAT_TYPE vin[], uniform FLOAT_TYPE vout[], + uniform int count) { + foreach (index = 0 ... count) { + FLOAT_TYPE v = vin[index]; + if (v < M_PI) + v = v * v; + else + v = sqrt(v); + vout[index] = v; + } +} diff --git a/Tests/ISPC/StaticLibrary/CMakeLists.txt b/Tests/ISPC/StaticLibrary/CMakeLists.txt new file mode 100644 index 0000000..b057544 --- /dev/null +++ b/Tests/ISPC/StaticLibrary/CMakeLists.txt @@ -0,0 +1,12 @@ + +cmake_minimum_required(VERSION 3.18) +project(ISPCStaticLibrary CXX ISPC) + +add_library(ispc_objects STATIC simple.ispc) + +target_compile_options(ispc_objects PRIVATE "$<$:--target=sse2-i32x4;--arch=x86-64>") +target_include_directories(ispc_objects INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") +set_target_properties(ispc_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) + +add_executable(ISPCStaticLibrary main.cxx) +target_link_libraries(ISPCStaticLibrary PRIVATE ispc_objects) diff --git a/Tests/ISPC/StaticLibrary/main.cxx b/Tests/ISPC/StaticLibrary/main.cxx new file mode 100644 index 0000000..a6b91a6 --- /dev/null +++ b/Tests/ISPC/StaticLibrary/main.cxx @@ -0,0 +1,15 @@ +#include + +#include "simple_ispc.h" + +int main() +{ + float vin[16], vout[16]; + for (int i = 0; i < 16; ++i) + vin[i] = i; + + ispc::simple(vin, vout, 16); + + for (int i = 0; i < 16; ++i) + printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]); +} diff --git a/Tests/ISPC/StaticLibrary/simple.ispc b/Tests/ISPC/StaticLibrary/simple.ispc new file mode 100644 index 0000000..70cb588 --- /dev/null +++ b/Tests/ISPC/StaticLibrary/simple.ispc @@ -0,0 +1,12 @@ + +export void simple(uniform float vin[], uniform float vout[], + uniform int count) { + foreach (index = 0 ... count) { + float v = vin[index]; + if (v < 3.) + v = v * v; + else + v = sqrt(v); + vout[index] = v; + } +} diff --git a/Tests/ISPC/TryCompile/CMakeLists.txt b/Tests/ISPC/TryCompile/CMakeLists.txt new file mode 100644 index 0000000..742f511 --- /dev/null +++ b/Tests/ISPC/TryCompile/CMakeLists.txt @@ -0,0 +1,16 @@ + +cmake_minimum_required(VERSION 3.18) +project(ISPCTryCompile ISPC CXX) + +set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON) +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CMAKE_ISPC_FLAGS "--arch=x86") +endif() + +#Verify we can use try_compile with ISPC +try_compile(result "${CMAKE_CURRENT_BINARY_DIR}" + SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/simple.ispc" + COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/result.o") + +add_executable(ISPCTryCompile main.cxx ) +target_link_libraries(ISPCTryCompile "${CMAKE_CURRENT_BINARY_DIR}/result.o") diff --git a/Tests/ISPC/TryCompile/main.cxx b/Tests/ISPC/TryCompile/main.cxx new file mode 100644 index 0000000..c8d1ed6 --- /dev/null +++ b/Tests/ISPC/TryCompile/main.cxx @@ -0,0 +1,19 @@ +#include + +namespace ispc { +extern "C" { +void simple(float*, float*, int); +} +} + +int main() +{ + float vin[16], vout[16]; + for (int i = 0; i < 16; ++i) + vin[i] = i; + + ispc::simple(vin, vout, 16); + + for (int i = 0; i < 16; ++i) + printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]); +} diff --git a/Tests/ISPC/TryCompile/simple.ispc b/Tests/ISPC/TryCompile/simple.ispc new file mode 100644 index 0000000..70cb588 --- /dev/null +++ b/Tests/ISPC/TryCompile/simple.ispc @@ -0,0 +1,12 @@ + +export void simple(uniform float vin[], uniform float vout[], + uniform int count) { + foreach (index = 0 ... count) { + float v = vin[index]; + if (v < 3.) + v = v * v; + else + v = sqrt(v); + vout[index] = v; + } +} -- cgit v0.12