Add runtime dispatching for loongarch (#2575)

* loongarch runtime dispatching

* remove CMake config for Loongarch.

* make lasx available

* flipping

* moving...

* fixing minor logic error

* minor fixes

* flipping

* adding hackish header

* better comment and reordering

* adding dispatch
This commit is contained in:
Daniel Lemire
2026-01-02 14:28:23 -05:00
committed by GitHub
parent 135c173053
commit f504e57e7a
13 changed files with 68 additions and 58 deletions
-18
View File
@@ -140,24 +140,6 @@ if(SIMDJSON_MINUS_ZERO_AS_FLOAT)
simdjson_add_props(target_compile_definitions PRIVATE SIMDJSON_MINUS_ZERO_AS_FLOAT=1)
endif(SIMDJSON_MINUS_ZERO_AS_FLOAT)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(loongarch64)$")
option(SIMDJSON_PREFER_LSX "Prefer LoongArch SX" ON)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-mlasx COMPILER_SUPPORTS_LASX)
check_cxx_compiler_flag(-mlsx COMPILER_SUPPORTS_LSX)
if(COMPILER_SUPPORTS_LASX AND NOT SIMDJSON_PREFER_LSX)
simdjson_add_props(
target_compile_options PRIVATE
-mlasx
)
elseif(COMPILER_SUPPORTS_LSX)
simdjson_add_props(
target_compile_options PRIVATE
-mlsx
)
endif()
endif()
# GCC and Clang have horrendous Debug builds when using SIMD.
# A common fix is to use '-Og' instead.
# bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412
+2 -2
View File
@@ -20,10 +20,10 @@
#include "simdjson/ppc64.h"
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(westmere)
#include "simdjson/westmere.h"
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lsx)
#include "simdjson/lsx.h"
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
#include "simdjson/lasx.h"
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lsx)
#include "simdjson/lsx.h"
#else
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
#endif
+2 -2
View File
@@ -17,10 +17,10 @@
#include "simdjson/arm64/begin.h"
#elif SIMDJSON_IMPLEMENTATION_PPC64
#include "simdjson/ppc64/begin.h"
#elif SIMDJSON_IMPLEMENTATION_LSX
#include "simdjson/lsx/begin.h"
#elif SIMDJSON_IMPLEMENTATION_LASX
#include "simdjson/lasx/begin.h"
#elif SIMDJSON_IMPLEMENTATION_LSX
#include "simdjson/lsx/begin.h"
#elif SIMDJSON_IMPLEMENTATION_FALLBACK
#include "simdjson/fallback/begin.h"
#else
+4 -4
View File
@@ -113,15 +113,15 @@
#endif
#ifndef SIMDJSON_IMPLEMENTATION_LASX
#define SIMDJSON_IMPLEMENTATION_LASX (SIMDJSON_IS_LOONGARCH64 && __loongarch_asx)
#define SIMDJSON_IMPLEMENTATION_LASX (SIMDJSON_IS_LSX)
#endif
#define SIMDJSON_CAN_ALWAYS_RUN_LASX (SIMDJSON_IMPLEMENTATION_LASX)
#define SIMDJSON_CAN_ALWAYS_RUN_LASX (SIMDJSON_IS_LASX)
#ifndef SIMDJSON_IMPLEMENTATION_LSX
#if SIMDJSON_CAN_ALWAYS_RUN_LASX
#define SIMDJSON_IMPLEMENTATION_LSX 0
#else
#define SIMDJSON_IMPLEMENTATION_LSX (SIMDJSON_IS_LOONGARCH64 && __loongarch_sx)
#define SIMDJSON_IMPLEMENTATION_LSX (SIMDJSON_IS_LSX)
#endif
#endif
#define SIMDJSON_CAN_ALWAYS_RUN_LSX (SIMDJSON_IMPLEMENTATION_LSX)
@@ -165,4 +165,4 @@
#define SIMDJSON_BUILTIN_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_BUILTIN_IMPLEMENTATION)
#define SIMDJSON_BUILTIN_IMPLEMENTATION_IS(IMPL) SIMDJSON_BUILTIN_IMPLEMENTATION_ID == SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL)
#endif // SIMDJSON_IMPLEMENTATION_DETECTION_H
#endif // SIMDJSON_IMPLEMENTATION_DETECTION_H
+9
View File
@@ -1,4 +1,11 @@
#define SIMDJSON_IMPLEMENTATION lasx
#include <lsxintrin.h> // This is a hack. We should not need to put this include here.
#if SIMDJSON_CAN_ALWAYS_RUN_LASX
// nothing needed.
#else
SIMDJSON_TARGET_REGION("lasx,lsx")
#endif
#include "simdjson/lasx/base.h"
#include "simdjson/lasx/intrinsics.h"
#include "simdjson/lasx/bitmanipulation.h"
@@ -8,3 +15,5 @@
#include "simdjson/lasx/stringparsing_defs.h"
#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1
+7
View File
@@ -4,3 +4,10 @@
#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT
#undef SIMDJSON_IMPLEMENTATION
#if SIMDJSON_CAN_ALWAYS_RUN_LASX
// nothing needed.
#else
SIMDJSON_UNTARGET_REGION
#endif
+1 -2
View File
@@ -5,8 +5,7 @@
#include "simdjson/lasx/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
// This should be the correct header whether
// you use visual studio or other compilers.
#include <lsxintrin.h>
#include <lasxintrin.h>
static_assert(sizeof(__m256i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for LoongArch ASX");
+1 -1
View File
@@ -61,7 +61,7 @@ simdjson_inline escaping escaping::copy_and_find(const uint8_t *src, uint8_t *ds
simd8<bool> is_backslash = (v == '\\');
simd8<bool> is_control = (v < 32);
return {
(is_backslash | is_quote | is_control).to_bitmask()
static_cast<uint64_t>((is_backslash | is_quote | is_control).to_bitmask())
};
}
-2
View File
@@ -5,8 +5,6 @@
#include "simdjson/lsx/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
// This should be the correct header whether
// you use visual studio or other compilers.
#include <lsxintrin.h>
static_assert(sizeof(__m128i) <= simdjson::SIMDJSON_PADDING, "insufficient padding for LoongArch SX");
+8 -2
View File
@@ -63,6 +63,12 @@ using std::size_t;
#endif
#elif defined(__loongarch_lp64)
#define SIMDJSON_IS_LOONGARCH64 1
#if defined(__loongarch_sx) && defined(__loongarch_asx)
#define SIMDJSON_IS_LSX 1
#define SIMDJSON_IS_LASX 1 // We can always run both
#elif defined(__loongarch_sx)
#define SIMDJSON_IS_LSX 1
#endif
#elif defined(__PPC64__) || defined(_M_PPC64)
#define SIMDJSON_IS_PPC64 1
#if defined(__ALTIVEC__)
@@ -118,7 +124,7 @@ using std::size_t;
//
// We are going to use runtime dispatch.
#if SIMDJSON_IS_X86_64
#if defined(SIMDJSON_IS_X86_64) || defined(SIMDJSON_IS_LSX)
#ifdef __clang__
// clang does not have GCC push pop
// warning: clang attribute push can't be used within a namespace in clang up
@@ -135,7 +141,7 @@ using std::size_t;
#define SIMDJSON_UNTARGET_REGION _Pragma("GCC pop_options")
#endif // clang then gcc
#endif // x86
#endif // defined(SIMDJSON_IS_X86_64) || defined(SIMDJSON_IS_LSX)
// Default target region macros don't do anything.
#ifndef SIMDJSON_TARGET_REGION
+15 -14
View File
@@ -94,6 +94,18 @@ static const simdjson::westmere::implementation* get_westmere_singleton() {
} // namespace simdjson
#endif // SIMDJSON_IMPLEMENTATION_WESTMERE
#if SIMDJSON_IMPLEMENTATION_LASX
#include <simdjson/lasx/implementation.h>
namespace simdjson {
namespace internal {
static const simdjson::lasx::implementation* get_lasx_singleton() {
static const simdjson::lasx::implementation lasx_singleton{};
return &lasx_singleton;
}
} // namespace internal
} // namespace simdjson
#endif // SIMDJSON_IMPLEMENTATION_LASX
#if SIMDJSON_IMPLEMENTATION_LSX
#include <simdjson/lsx/implementation.h>
namespace simdjson {
@@ -106,17 +118,6 @@ static const simdjson::lsx::implementation* get_lsx_singleton() {
} // namespace simdjson
#endif // SIMDJSON_IMPLEMENTATION_LSX
#if SIMDJSON_IMPLEMENTATION_LASX
#include <simdjson/lasx/implementation.h>
namespace simdjson {
namespace internal {
static const simdjson::lasx::implementation* get_lasx_singleton() {
static const simdjson::lasx::implementation lasx_singleton{};
return &lasx_singleton;
}
} // namespace internal
} // namespace simdjson
#endif // SIMDJSON_IMPLEMENTATION_LASX
#undef SIMDJSON_CONDITIONAL_INCLUDE
@@ -210,12 +211,12 @@ static const std::initializer_list<const implementation *>& get_available_implem
#if SIMDJSON_IMPLEMENTATION_PPC64
get_ppc64_singleton(),
#endif
#if SIMDJSON_IMPLEMENTATION_LSX
get_lsx_singleton(),
#endif
#if SIMDJSON_IMPLEMENTATION_LASX
get_lasx_singleton(),
#endif
#if SIMDJSON_IMPLEMENTATION_LSX
get_lsx_singleton(),
#endif
#if SIMDJSON_IMPLEMENTATION_FALLBACK
get_fallback_singleton(),
#endif
+16 -8
View File
@@ -55,6 +55,9 @@ POSSIBILITY OF SUCH DAMAGE.
#elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID)
#include <cpuid.h>
#endif
#if defined(__loongarch__) && defined(__linux__)
#include <sys/auxv.h>
#endif
namespace simdjson {
namespace internal {
@@ -219,16 +222,21 @@ static inline uint32_t detect_supported_architectures() {
return host_isa;
}
#elif defined(__loongarch_sx) && !defined(__loongarch_asx)
#elif defined(__loongarch__)
static inline uint32_t detect_supported_architectures() {
return instruction_set::LSX;
}
#elif defined(__loongarch_asx)
static inline uint32_t detect_supported_architectures() {
return instruction_set::LASX;
uint32_t host_isa = instruction_set::DEFAULT;
#if defined(__linux__)
uint64_t hwcap = 0;
hwcap = getauxval(AT_HWCAP);
if (hwcap & HWCAP_LOONGARCH_LSX) {
host_isa |= instruction_set::LSX;
}
if (hwcap & HWCAP_LOONGARCH_LASX) {
host_isa |= instruction_set::LASX;
}
#endif
return host_isa;
}
#else // fallback
+3 -3
View File
@@ -35,12 +35,12 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
#if SIMDJSON_IMPLEMENTATION_WESTMERE
#include <westmere.cpp>
#endif
#if SIMDJSON_IMPLEMENTATION_LSX
#include <lsx.cpp>
#endif
#if SIMDJSON_IMPLEMENTATION_LASX
#include <lasx.cpp>
#endif
#if SIMDJSON_IMPLEMENTATION_LSX
#include <lsx.cpp>
#endif
#if SIMDJSON_IMPLEMENTATION_FALLBACK
#include <fallback.cpp>
#endif