[CMake,simd] unify WITH_SSE2, WITH_AVX2, WITH_NEON

* Add new CMake option WITH_SIMD to enable best available instruction
  type
* Unify simd related defines in single header
This commit is contained in:
akallabeth
2024-11-27 11:29:48 +01:00
parent 4b35fe8cfa
commit b4976163cd
39 changed files with 399 additions and 387 deletions

View File

@@ -22,11 +22,6 @@ option(WITH_MANPAGES "Generate manpages." ${MANPAGE_DEF})
option(WITH_PROFILER "Compile profiler." OFF)
option(WITH_GPROF "Compile with GProf profiler." OFF)
option(WITH_SSE2 "Enable SSE2 optimization." OFF)
cmake_dependent_option(WITH_AVX2 "Compile AVX2 optimizations" ON "WITH_SSE2" OFF)
option(WITH_NEON "Enable NEON optimization." OFF)
option(WITH_JPEG "Use JPEG decoding." OFF)
include(CompilerDetect)

View File

@@ -1,44 +1,104 @@
include(CheckSymbolExists)
option(WITH_SIMD "Enable best platform specific vector instruction support" ON)
cmake_dependent_option(WITH_AVX2 "Compile AVX2 optimizations." ON "WITH_SIMD" OFF)
check_symbol_exists("__i586__" "" X86_i586)
check_symbol_exists("__i686__" "" X86_i686)
check_symbol_exists("__X86__" "" X86_X86)
check_symbol_exists("_X86_" "" X86_X862)
check_symbol_exists("__I86__" "" X86_I86)
check_symbol_exists("__IA32__" "" X86_IA32)
check_symbol_exists("_M_IX86" "" X86_M_IX86)
check_symbol_exists("__amd64" "" X86_AMD64)
check_symbol_exists("__amd64__" "" X86_AMD642)
check_symbol_exists("__x86_64" "" X86_X86_64)
check_symbol_exists("__x86_64__" "" X86_X86_642)
check_symbol_exists("_M_X64" "" X86_X64)
check_symbol_exists("__ia64" "" X86_IA64)
check_symbol_exists("__ia64__" "" X86_IA642)
check_symbol_exists("_M_IA64" "" X86_M_IA64)
check_symbol_exists("_M_ARM64" "" MSVC_ARM64)
check_symbol_exists("__aarch64__" "" ARCH_ARM64)
check_symbol_exists("M_ARM" "" ARCH_M_ARM)
check_symbol_exists("_arm__" "" ARCH_ARM)
check_symbol_exists("_thumb__" "" ARCH_THUMB)
check_symbol_exists("_TARGET_ARCH_ARM" "" ARCH_ARM_TARGET)
check_symbol_exists("_TARGET_ARCH_THUMB" "" ARCH_ARM_TARGET_THUMB)
if(X86_i586 OR X86_i686 OR X86_X86 OR X86_X862 OR X86_I86 OR X86_IA32 OR X86_M_IX86 OR X86_AMD64 OR X86_AMD642
OR X86_X86_64 OR X86_X86_642 OR X86_X64 OR X86_IA64 OR X86_IA642 OR X86_M_IA64
)
set(HAVE_SSE_OR_AVX ON CACHE INTERNAL "internal")
else()
set(HAVE_SSE_OR_AVX OFF CACHE INTERNAL "internal")
if(WITH_SSE2)
message(WARNING "WITH_SSE2 is deprecated, use WITH_SIMD instead")
set(WITH_SIMD ON CACHE BOOL "WITH_SSE2")
endif()
if(WITH_NEON)
message(WARNING "WITH_NEON is deprecated, use WITH_SIMD instead")
set(WITH_SIMD ON CACHE BOOL "WITH_NEON")
endif()
if(MSVC_ARM64 OR ARCH_ARM64 OR ARCH_M_ARM OR ARCH_ARM OR ARCH_THUMB OR ARCH_ARM_TARGET OR ARCH_ARM_TARGET_THUMB)
set(HAVE_NEON ON CACHE INTERNAL "internal")
else()
set(HAVE_NEON OFF CACHE INTERNAL "internal")
endif()
macro(set_simd_source_file_properties INTRINSIC_TYPE)
if(ARGC LESS_EQUAL 1)
message(FATAL_ERROR "set_simd_source_file_properties called with invalid arguments: [${ARGC}] {${ARGN}")
endif()
if(MSVC_ARM64 OR ARCH_ARM64)
set(HAVE_NEON64 ON CACHE INTERNAL "internal")
else()
set(HAVE_NEON64 OFF CACHE INTERNAL "internal")
endif()
# see https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
set(GCC_CLANG_NAMES "AppleClang;Clang;CrayClang;FujitsuClang;GNU;IntelLLVM;TIClang;XLClang;IBMClang")
set(SSE_X86_LIST "i686;x86;X86")
set(SSE_LIST "x86_64;ia64;x64;AMD64;IA64;EM64T;${SSE_X86_LIST}")
set(NEON_LIST "arm;armv7;armv8b;armv8l")
set(SUPPORTED_INTRINSICS_LIST "neon;sse2;sse3;ssse3;sse4.1;sse4.2;avx2")
if(NOT "${INTRINSIC_TYPE}" IN_LIST SUPPORTED_INTRINSICS_LIST)
message(WARNING "Intrinsic type ${INTRINSIC_TYPE} not supported, only ${SUPPORTED_INTRINSICS_LIST} are available")
else()
set(SIMD_LINK_ARG "")
if(MSVC)
# https://learn.microsoft.com/en-us/cpp/build/reference/arch-x64?view=msvc-140
if("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST SSE_LIST)
if("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST SSE_X86_LIST)
# /arch:SSE2 is the default, so do nothing
set(SIMD_LINK_ARG "ignore")
if("${INTRINSIC_TYPE}" STREQUAL "avx2")
set(SIMD_LINK_ARG "/arch:AVX2")
endif()
else()
# /arch:SSE2 is the default, so do nothing
set(SIMD_LINK_ARG "ignore")
if("${INTRINSIC_TYPE}" STREQUAL "sse4.2")
set(SIMD_LINK_ARG "/arch:SSE4.2")
elseif("${INTRINSIC_TYPE}" STREQUAL "avx2")
set(SIMD_LINK_ARG "/arch:AVX2")
endif()
endif()
endif()
elseif("${CMAKE_C_COMPILER_ID}" IN_LIST GCC_CLANG_NAMES)
set(HAVE_SSE_AVX OFF)
foreach(ARCH ${CMAKE_OSX_ARCHITECTURES})
if("${ARCH}" IN_LIST SSE_LIST)
set(HAVE_SSE_AVX ON)
endif()
endforeach()
if("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST SSE_LIST OR HAVE_SSE_AVX)
if("${INTRINSIC_TYPE}" STREQUAL "sse2")
set(SIMD_LINK_ARG "-msse2")
elseif("${INTRINSIC_TYPE}" STREQUAL "sse3")
set(SIMD_LINK_ARG "-msse3")
elseif("${INTRINSIC_TYPE}" STREQUAL "ssse3")
set(SIMD_LINK_ARG "-mssse3")
elseif("${INTRINSIC_TYPE}" STREQUAL "sse4.1")
set(SIMD_LINK_ARG "-msse4.1")
elseif("${INTRINSIC_TYPE}" STREQUAL "sse4.2")
set(SIMD_LINK_ARG "-msse4.2")
elseif("${INTRINSIC_TYPE}" STREQUAL "avx2")
set(SIMD_LINK_ARG "-mavx2")
endif()
endif()
else()
message(WARNING "[SIMD] Unsupported compiler ${CMAKE_C_COMPILER_ID}, ignoring")
endif()
if("${INTRINSIC_TYPE}" STREQUAL "neon")
set(HAVE_NEON OFF)
foreach(ARCH ${CMAKE_OSX_ARCHITECTURES})
if("${ARCH}" IN_LIST NEON_LIST)
set(HAVE_NEON ON)
endif()
endforeach()
if("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST NEON_LIST OR HAVE_NEON)
if(MSVC)
set(SIMD_LINK_ARG "/arch:VFPv4")
elseif("${CMAKE_C_COMPILER_ID}" IN_LIST GCC_CLANG_NAMES)
set(SIMD_LINK_ARG "-mfpu=neon")
else()
message(WARNING "[SIMD] Unsupported compiler ${CMAKE_C_COMPILER_ID}, ignoring")
endif()
endif()
endif()
if(SIMD_LINK_ARG STREQUAL "")
message(NOTICE "INTRINSIC_TYPE=${INTRINSIC_TYPE}: not supported on target platform, ignoring")
elseif(SIMD_LINK_ARG STREQUAL "ignore")
message(NOTICE "INTRINSIC_TYPE=${INTRINSIC_TYPE}: does not require linker flags, enabled by default")
else()
message("[SIMD] linking ${INTRINSIC_TYPE} [${SIMD_LINK_ARG}]: ${ARGN}")
foreach(src ${ARGN})
set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS "${SIMD_LINK_ARG}")
endforeach()
endif()
endif()
endmacro()