diff --git a/benchmark/minifiercompetition.cpp b/benchmark/minifiercompetition.cpp index 824238649..35c54bab6 100644 --- a/benchmark/minifiercompetition.cpp +++ b/benchmark/minifiercompetition.cpp @@ -48,7 +48,9 @@ std::string rapid_stringme(char *json) { std::string simdjson_stringme(simdjson::padded_string & json) { std::stringstream ss; dom::parser parser; - dom::element doc = parser.parse(json); + dom::element doc; + auto error = parser.parse(json).get(doc); + if (error) { std::cerr << error << std::endl; abort(); } ss << simdjson::minify(doc); return ss.str(); } diff --git a/benchmark/parseandstatcompetition.cpp b/benchmark/parseandstatcompetition.cpp index 65647759d..63889bdbb 100644 --- a/benchmark/parseandstatcompetition.cpp +++ b/benchmark/parseandstatcompetition.cpp @@ -131,24 +131,34 @@ struct Stat { size_t stringLength; // Number of code units in all strings }; -static void GenStatPlus(Stat &stat, const dom::element v) { +static error_code GenStatPlus(Stat &stat, const dom::element &v); +static error_code GenStatPlus(Stat &stat, const simdjson_result &r) { + dom::element v; + SIMDJSON_TRY( r.get(v) ); + return GenStatPlus(stat, v); +} +static error_code GenStatPlus(Stat &stat, const dom::element &v) { switch (v.type()) { - case dom::element_type::ARRAY: - for (dom::element child : dom::array(v)) { + case dom::element_type::ARRAY: { + dom::array a; + SIMDJSON_TRY( v.get(a) ) + for (auto child : a) { GenStatPlus(stat, child); stat.elementCount++; } stat.arrayCount++; - break; - case dom::element_type::OBJECT: - for (dom::key_value_pair kv : dom::object(v)) { + } break; + case dom::element_type::OBJECT: { + dom::object o; + SIMDJSON_TRY( v.get(o) ); + for (dom::key_value_pair kv : o) { GenStatPlus(stat, kv.value); stat.stringLength += kv.key.size(); stat.memberCount++; stat.stringCount++; } stat.objectCount++; - break; + } break; case dom::element_type::INT64: case dom::element_type::UINT64: case dom::element_type::DOUBLE: @@ -156,20 +166,24 @@ static void GenStatPlus(Stat &stat, const dom::element v) { break; case dom::element_type::STRING: { stat.stringCount++; - auto sv = std::string_view(v); + std::string_view sv; + SIMDJSON_TRY( v.get(sv) ); stat.stringLength += sv.size(); } break; - case dom::element_type::BOOL: - if (bool(v)) { + case dom::element_type::BOOL: { + bool b; + SIMDJSON_TRY( v.get(b) ); + if (b) { stat.trueCount++; } else { stat.falseCount++; } - break; + } break; case dom::element_type::NULL_VALUE: ++stat.nullCount; break; } + return SUCCESS; } static void RapidGenStat(Stat &stat, const rapidjson::Value &v) { @@ -221,7 +235,8 @@ simdjson_never_inline Stat rapidjson_compute_stats_ref(const rapidjson::Value &d simdjson_never_inline Stat simdjson_compute_stats_refplus(const simdjson::dom::element &doc) { Stat s{}; - GenStatPlus(s, doc); + auto error = GenStatPlus(s, doc); + if (error) { std::cerr << error << std::endl; abort(); } return s; } @@ -469,9 +484,7 @@ int main(int argc, char *argv[]) { simdjson::dom::parser parser; simdjson::dom::element doc; auto error = parser.parse(p).get(doc); - if (error) { - std::cerr << error << std::endl; - } + if (error) { std::cerr << error << std::endl; abort(); } size_t refval = simdjson_compute_stats_refplus(doc).objectCount; BEST_TIME("simdjson ", diff --git a/cmake/simdjson-flags.cmake b/cmake/simdjson-flags.cmake index 17d1abd5b..900934b79 100644 --- a/cmake/simdjson-flags.cmake +++ b/cmake/simdjson-flags.cmake @@ -98,44 +98,82 @@ endif() # Optional flags # +# # Implementation selection +# +set(SIMDJSON_ALL_IMPLEMENTATIONS "fallback;westmere;haswell;arm64") + +set(SIMDJSON_IMPLEMENTATION "" CACHE STRING "Semicolon-separated list of implementations to include (${SIMDJSON_ALL_IMPLEMENTATIONS}). If this is not set, any implementations that are supported at compile time and may be selected at runtime will be included.") +foreach(implementation ${SIMDJSON_IMPLEMENTATION}) + if(NOT (implementation IN_LIST SIMDJSON_ALL_IMPLEMENTATIONS)) + message(ERROR "Implementation ${implementation} not supported by simdjson. Possible implementations: ${SIMDJSON_ALL_IMPLEMENTATIONS}") + endif() +endforeach(implementation) + +set(SIMDJSON_EXCLUDE_IMPLEMENTATION "" CACHE STRING "Semicolon-separated list of implementations to exclude (haswell/westmere/arm64/fallback). By default, excludes any implementations that are unsupported at compile time or cannot be selected at runtime.") +foreach(implementation ${SIMDJSON_EXCLUDE_IMPLEMENTATION}) + if(NOT (implementation IN_LIST SIMDJSON_ALL_IMPLEMENTATIONS)) + message(ERROR "Implementation ${implementation} not supported by simdjson. Possible implementations: ${SIMDJSON_ALL_IMPLEMENTATIONS}") + endif() +endforeach(implementation) + +foreach(implementation ${SIMDJSON_ALL_IMPLEMENTATIONS}) + string(TOUPPER ${implementation} implementation_upper) + if(implementation IN_LIST SIMDJSON_EXCLUDE_IMPLEMENTATION) + message(STATUS "Excluding implementation ${implementation} due to SIMDJSON_EXCLUDE_IMPLEMENTATION=${SIMDJSON_EXCLUDE_IMPLEMENTATION}") + target_compile_definitions(simdjson-flags INTERFACE "SIMDJSON_IMPLEMENTATION_${implementation_upper}=0") + elseif(implementation IN_LIST SIMDJSON_IMPLEMENTATION) + message(STATUS "Including implementation ${implementation} due to SIMDJSON_IMPLEMENTATION=${SIMDJSON_IMPLEMENTATION}") + target_compile_definitions(simdjson-flags INTERFACE "SIMDJSON_IMPLEMENTATION_${implementation_upper}=1") + elseif(SIMDJSON_IMPLEMENTATION) + message(STATUS "Excluding implementation ${implementation} due to SIMDJSON_IMPLEMENTATION=${SIMDJSON_IMPLEMENTATION}") + target_compile_definitions(simdjson-flags INTERFACE "SIMDJSON_IMPLEMENTATION_${implementation_upper}=0") + endif() +endforeach(implementation) + +# TODO make it so this generates the necessary compiler flags to select the given implementation as the builtin automatically! +option(SIMDJSON_BUILTIN_IMPLEMENTATION "Select the implementation that will be used for user code. Defaults to the most universal implementation in SIMDJSON_IMPLEMENTATION (in the order ${SIMDJSON_ALL_IMPLEMENTATIONS}) if specified; otherwise, by default the compiler will pick the best implementation that can always be selected given the compiler flags." "") +if(SIMDJSON_BUILTIN_IMPLEMENTATION) + target_compile_definitions(simdjson-flags INTERFACE "SIMDJSON_BUILTIN_IMPLEMENTATION=${SIMDJSON_BUILTIN_IMPLEMENTATION}") +else() + # Pick the most universal implementation out of the selected implementations (if any) + foreach(implementation ${SIMDJSON_ALL_IMPLEMENTATIONS}) + if(implementation IN_LIST SIMDJSON_IMPLEMENTATION AND NOT (implementation IN_LIST SIMDJSON_EXCLUDE_IMPLEMENTATION)) + message(STATUS "Selected implementation ${implementation} as builtin implementation based on ${SIMDJSON_IMPLEMENTATION}.") + target_compile_definitions(simdjson-flags INTERFACE "SIMDJSON_BUILTIN_IMPLEMENTATION=${implementation}") + break() + endif() + endforeach(implementation) +endif(SIMDJSON_BUILTIN_IMPLEMENTATION) + option(SIMDJSON_IMPLEMENTATION_HASWELL "Include the haswell implementation" ON) if(NOT SIMDJSON_IMPLEMENTATION_HASWELL) - message(DEPRECATION "SIMDJSON_IMPLEMENTATION_HASWELL is deprecated. Use SIMDJSON_IMPLEMENTATION=haswell or SIMDJSON_IMPLEMENTATION=-haswell instead.") - target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_HASWELL=0) + message(DEPRECATION "SIMDJSON_IMPLEMENTATION_HASWELL is deprecated. Use SIMDJSON_IMPLEMENTATION=-haswell instead.") + target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_HASWELL=0) endif() option(SIMDJSON_IMPLEMENTATION_WESTMERE "Include the westmere implementation" ON) if(NOT SIMDJSON_IMPLEMENTATION_WESTMERE) message(DEPRECATION "SIMDJSON_IMPLEMENTATION_WESTMERE is deprecated. SIMDJSON_IMPLEMENTATION=-westmere instead.") - target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_WESTMERE=0) + target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_WESTMERE=0) endif() option(SIMDJSON_IMPLEMENTATION_ARM64 "Include the arm64 implementation" ON) if(NOT SIMDJSON_IMPLEMENTATION_ARM64) message(DEPRECATION "SIMDJSON_IMPLEMENTATION_ARM64 is deprecated. Use SIMDJSON_IMPLEMENTATION=-arm64 instead.") - target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_ARM64=0) + target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_ARM64=0) endif() option(SIMDJSON_IMPLEMENTATION_FALLBACK "Include the fallback implementation" ON) if(NOT SIMDJSON_IMPLEMENTATION_FALLBACK) message(DEPRECATION "SIMDJSON_IMPLEMENTATION_FALLBACK is deprecated. Use SIMDJSON_IMPLEMENTATION=-fallback instead.") - target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_IMPLEMENTATION_FALLBACK=0) + target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_FALLBACK=0) endif() -# e.g. SIMDJSON_IMPLEMENTATION="haswell;westmere;-fallback" -set(SIMDJSON_IMPLEMENTATION "" CACHE STRING "Implementations to include/exclude: semicolon separated list of architectures (haswell/westmere/arm64/fallback). Prepend with - to force an implementation off. (e.g. -DSIMDJSON_IMPLEMENTATION=\"haswell;-fallback\" .) Defaults to compile-time detection.") -foreach(implementation ${SIMDJSON_IMPLEMENTATION}) - string(TOUPPER ${implementation} implementation_upper) - string(SUBSTRING ${implementation_upper} 0 1 first_char) - if(first_char STREQUAL "-") - string(SUBSTRING ${implementation_upper} 1 -1 neg_implementation_upper) - target_compile_definitions(simdjson-internal-flags INTERFACE "SIMDJSON_IMPLEMENTATION_${neg_implementation_upper}=0") - else() - target_compile_definitions(simdjson-internal-flags INTERFACE "SIMDJSON_IMPLEMENTATION_${implementation_upper}=1") - endif() -endforeach(implementation) +# +# Other optional flags +# option(SIMDJSON_ONDEMAND_SAFETY_RAILS "Validate ondemand user code at runtime to ensure it is being used correctly. Defaults to ON for debug builds, OFF for release builds." $,ON,OFF>) if(SIMDJSON_ONDEMAND_SAFETY_RAILS) message(STATUS "Ondemand safety rails enabled. Ondemand user code will be checked at runtime. This will be slower than normal!") - target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_ONDEMAND_SAFETY_RAILS) + target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_ONDEMAND_SAFETY_RAILS) endif(SIMDJSON_ONDEMAND_SAFETY_RAILS) option(SIMDJSON_BASH "Allow usage of bash within CMake" ON) @@ -145,7 +183,7 @@ option(SIMDJSON_GIT "Allow usage of git within CMake" ON) option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON) if(NOT SIMDJSON_EXCEPTIONS) message(STATUS "simdjson exception interface turned off. Code that does not check error codes will not compile.") - target_compile_definitions(simdjson-internal-flags INTERFACE SIMDJSON_EXCEPTIONS=0) + target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_EXCEPTIONS=0) endif() option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON) diff --git a/fuzz/build_fuzzer_variants.sh b/fuzz/build_fuzzer_variants.sh index aff1e1301..4ae574e43 100755 --- a/fuzz/build_fuzzer_variants.sh +++ b/fuzz/build_fuzzer_variants.sh @@ -45,7 +45,12 @@ variant=sanitizers -DCMAKE_C_FLAGS="-fsanitize=fuzzer-no-link,address,undefined -fno-sanitize-recover=undefined" \ -DCMAKE_BUILD_TYPE=Debug \ -DSIMDJSON_FUZZ_LINKMAIN=Off \ +<<<<<<< HEAD -DSIMDJSON_FUZZ_LDFLAGS="-fsanitize=fuzzer" +======= + -DSIMDJSON_FUZZ_LDFLAGS=$LIB_FUZZING_ENGINE \ + -DSIMDJSON_EXCLUDE_IMPLEMENTATION=haswell +>>>>>>> Kinder, gentler implementation selection ninja all_fuzzers cd .. diff --git a/include/simdjson.h b/include/simdjson.h index 17c28f6c1..e7116cd61 100644 --- a/include/simdjson.h +++ b/include/simdjson.h @@ -83,23 +83,10 @@ SIMDJSON_DISABLE_UNDESIRED_WARNINGS // Implementations #include "simdjson/arm64.h" -#include "simdjson/fallback.h" #include "simdjson/haswell.h" #include "simdjson/westmere.h" - -namespace simdjson { - /** - * Represents the best statically linked simdjson implementation that can be used by the compiling - * program. - * - * Detects what options the program is compiled against, and picks the minimum implementation that - * will work on any computer that can run the program. For example, if you compile with g++ - * -march=westmere, it will pick the westmere implementation. The haswell implementation will - * still be available, and can be selected at runtime, but the builtin implementation (and any - * code that uses it) will use westmere. - */ - namespace builtin = SIMDJSON_BUILTIN_IMPLEMENTATION; -} // namespace simdjson +#include "simdjson/fallback.h" +#include "simdjson/builtin.h" SIMDJSON_POP_DISABLE_WARNINGS diff --git a/include/simdjson/arm64.h b/include/simdjson/arm64.h index e0d9cbb54..6cbc0bffc 100644 --- a/include/simdjson/arm64.h +++ b/include/simdjson/arm64.h @@ -1,8 +1,17 @@ #ifndef SIMDJSON_ARM64_H #define SIMDJSON_ARM64_H +#ifdef SIMDJSON_FALLBACK_H +#error "arm64.h must be included before fallback.h" +#endif + #include "simdjson/portability.h" +#include "simdjson/internal/isadetection.h" +#include "simdjson/internal/jsoncharutils_tables.h" +#include "simdjson/internal/numberparsing_tables.h" +#include "simdjson/internal/simdprune_tables.h" + #if SIMDJSON_IMPLEMENTATION_ARM64 namespace simdjson { diff --git a/include/simdjson/builtin.h b/include/simdjson/builtin.h new file mode 100644 index 000000000..7611458c1 --- /dev/null +++ b/include/simdjson/builtin.h @@ -0,0 +1,34 @@ +#ifndef SIMDJSON_BUILTIN_H +#define SIMDJSON_BUILTIN_H + +#include "simdjson/portability.h" + +#ifndef SIMDJSON_BUILTIN_IMPLEMENTATION +#if SIMDJSON_CAN_ALWAYS_RUN_HASWELL +#define SIMDJSON_BUILTIN_IMPLEMENTATION haswell +#elif SIMDJSON_CAN_ALWAYS_RUN_WESTMERE +#define SIMDJSON_BUILTIN_IMPLEMENTATION westmere +#elif SIMDJSON_CAN_ALWAYS_RUN_ARM64 +#define SIMDJSON_BUILTIN_IMPLEMENTATION arm64 +#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK +#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback +#else +#error "All possible implementations (including fallback) have been disabled! simdjson will not run." +#endif +#endif // SIMDJSON_BUILTIN_IMPLEMENTATION + +namespace simdjson { + /** + * Represents the best statically linked simdjson implementation that can be used by the compiling + * program. + * + * Detects what options the program is compiled against, and picks the minimum implementation that + * will work on any computer that can run the program. For example, if you compile with g++ + * -march=westmere, it will pick the westmere implementation. The haswell implementation will + * still be available, and can be selected at runtime, but the builtin implementation (and any + * code that uses it) will use westmere. + */ + namespace builtin = SIMDJSON_BUILTIN_IMPLEMENTATION; +} // namespace simdjson + +#endif // SIMDJSON_BUILTIN_H diff --git a/include/simdjson/fallback.h b/include/simdjson/fallback.h index f1253a064..1f7dc31d8 100644 --- a/include/simdjson/fallback.h +++ b/include/simdjson/fallback.h @@ -3,6 +3,12 @@ #include "simdjson/portability.h" +// Default Fallback to on unless a builtin implementation has already been selected. +#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK +#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 // (!SIMDJSON_CAN_ALWAYS_RUN_ARM64 && !SIMDJSON_CAN_ALWAYS_RUN_HASWELL && !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_FALLBACK SIMDJSON_IMPLEMENTATION_FALLBACK + #if SIMDJSON_IMPLEMENTATION_FALLBACK namespace simdjson { diff --git a/include/simdjson/haswell.h b/include/simdjson/haswell.h index e197fbbca..39679ed29 100644 --- a/include/simdjson/haswell.h +++ b/include/simdjson/haswell.h @@ -1,8 +1,22 @@ #ifndef SIMDJSON_HASWELL_H #define SIMDJSON_HASWELL_H +#ifdef SIMDJSON_WESTMERE_H +#error "haswell.h must be included before westmere.h" +#endif +#ifdef SIMDJSON_FALLBACK_H +#error "haswell.h must be included before fallback.h" +#endif + #include "simdjson/portability.h" +// Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected +// at runtime. +#ifndef SIMDJSON_IMPLEMENTATION_HASWELL +#define SIMDJSON_IMPLEMENTATION_HASWELL (SIMDJSON_IS_X86_64) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__)) + #if SIMDJSON_IMPLEMENTATION_HASWELL #define SIMDJSON_TARGET_HASWELL SIMDJSON_TARGET_REGION("avx2,bmi,pclmul,lzcnt") diff --git a/include/simdjson/internal/simdprune_tables.h b/include/simdjson/internal/simdprune_tables.h index 59e2e5467..3d30fece9 100644 --- a/include/simdjson/internal/simdprune_tables.h +++ b/include/simdjson/internal/simdprune_tables.h @@ -1,8 +1,6 @@ #ifndef SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H #define SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H -#if SIMDJSON_IMPLEMENTATION_ARM64 || SIMDJSON_IMPLEMENTATION_HASWELL || SIMDJSON_IMPLEMENTATION_WESTMERE - #include namespace simdjson { // table modified and copied from @@ -18,6 +16,4 @@ extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256]; } // namespace internal } // namespace simdjson -#endif // SIMDJSON_IMPLEMENTATION_ARM64 || SIMDJSON_IMPLEMENTATION_HASWELL || SIMDJSON_IMPLEMENTATION_WESTMERE - #endif // SIMDJSON_INTERNAL_SIMDPRUNE_TABLES_H diff --git a/include/simdjson/portability.h b/include/simdjson/portability.h index ed1780853..966d7a8bd 100644 --- a/include/simdjson/portability.h +++ b/include/simdjson/portability.h @@ -84,88 +84,6 @@ use a 64-bit target such as x64 or 64-bit ARM.") // Enable valid runtime implementations, and select SIMDJSON_BUILTIN_IMPLEMENTATION // -// -// ARM 64-bit (NEON / Other) -// -#if SIMDJSON_IS_ARM64 -// Default ARM64 to on: it could be selected at runtime. -#ifndef SIMDJSON_IMPLEMENTATION_ARM64 -#define SIMDJSON_IMPLEMENTATION_ARM64 1 -#endif -#if __ARM_NEON -// -// NEON -// -// We're compiled natively for NEON, so arm64 will *always* work (the program is going -// to fail in other ways if it's not run on a machine supporting NEON). -// -// Set builtin to arm64, and leave fallback defaulted to off. -// It can still be enabled with SIMDJSON_IMPLEMENTATION_XXX flags, though it's unclear why one -// would do so). -// -#define SIMDJSON_BUILTIN_IMPLEMENTATION arm64 -#endif -#endif // SIMDJSON_IS_ARM64 - -// -// Intel 64-bit (Haswell / Westmere / Other) -// -#if SIMDJSON_IS_X86_64 - -// Default Haswell to on: it could be selected at runtime. -#ifndef SIMDJSON_IMPLEMENTATION_HASWELL -#define SIMDJSON_IMPLEMENTATION_HASWELL 1 -#endif - -#if __AVX2__ && __BMI__ && __PCLMUL__ && __LZCNT__ && SIMDJSON_IMPLEMENTATION_HASWELL -// -// Haswell -// -// We're compiled natively for Haswell, so Haswell will *always* work (more specifically, the -// program is going to fail in other ways if it's not run on a machine supporting AVX2). -// -// Set builtin to haswell, and leave westmere and fallback defaulted to off. -// They can still be enabled with SIMDJSON_IMPLEMENTATION_XXX flags, though it's unclear why one -// would do so). -// -#define SIMDJSON_BUILTIN_IMPLEMENTATION haswell -#else // Haswell - -// We're not compiled natively for Haswell. Default Westmere to on: it could be selected at runtime. -#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE -#define SIMDJSON_IMPLEMENTATION_WESTMERE 1 -#endif -#if __SSE4_2__ && __PCLMUL__ && SIMDJSON_IMPLEMENTATION_WESTMERE -// -// Westmere -// -// We're compiled natively for Westmere, so Westmere will *always* work (the program is going -// to fail in other ways if it's not run on a machine supporting SSE4.2). -// -// Set builtin to westmere, and leave fallback defaulted to off. -// It can still be enabled with SIMDJSON_IMPLEMENTATION_XXX flags, though it's unclear why one -// would do so). -// -#define SIMDJSON_BUILTIN_IMPLEMENTATION westmere -#endif // Westmere -#endif // Haswell -#endif // SIMDJSON_IS_X86_64 - -// -// If no specific builtin architecture was discovered, set builtin to fallback and make sure it's -// enabled. -// -#ifndef SIMDJSON_BUILTIN_IMPLEMENTATION -#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK -#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 -#endif -#if SIMDJSON_IMPLEMENTATION_FALLBACK -#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback -#else -#error "fallback architecture is disabled, but is compiled with flags that allow it to run on machines that require fallback." -#endif -#endif // SIMDJSON_BUILTIN_IMPLEMENTATION - // We are going to use runtime dispatch. #ifdef SIMDJSON_IS_X86_64 #ifdef __clang__ diff --git a/include/simdjson/simdjson.h b/include/simdjson/simdjson.h index 8efab2a39..3fe721122 100644 --- a/include/simdjson/simdjson.h +++ b/include/simdjson/simdjson.h @@ -7,4 +7,5 @@ #include "simdjson/compiler_check.h" #include "simdjson/error.h" + #endif // SIMDJSON_SIMDJSON_H diff --git a/include/simdjson/westmere.h b/include/simdjson/westmere.h index a72e003ef..2f202c71a 100644 --- a/include/simdjson/westmere.h +++ b/include/simdjson/westmere.h @@ -1,8 +1,18 @@ #ifndef SIMDJSON_WESTMERE_H #define SIMDJSON_WESTMERE_H +#ifdef SIMDJSON_FALLBACK_H +#error "westmere.h must be included before fallback.h" +#endif + #include "simdjson/portability.h" +// Default Westmere to on if this is x86-64, unless we'll always select Haswell. +#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE +#define SIMDJSON_IMPLEMENTATION_WESTMERE (SIMDJSON_IS_X86_64 && !SIMDJSON_REQUIRES_HASWELL) +#endif +#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__) + #if SIMDJSON_IMPLEMENTATION_WESTMERE #define SIMDJSON_TARGET_WESTMERE SIMDJSON_TARGET_REGION("sse4.2,pclmul") diff --git a/singleheader/simdjson.h b/singleheader/simdjson.h index 5223cfc82..e7dbeed4e 100644 --- a/singleheader/simdjson.h +++ b/singleheader/simdjson.h @@ -151,37 +151,6 @@ use a 64-bit target such as x64 or 64-bit ARM.") #define STRINGIFY_IMPLEMENTATION_(a) #a #define STRINGIFY(a) STRINGIFY_IMPLEMENTATION_(a) -#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK -#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 -#endif - -#if SIMDJSON_IS_ARM64 -#ifndef SIMDJSON_IMPLEMENTATION_ARM64 -#define SIMDJSON_IMPLEMENTATION_ARM64 1 -#endif -#define SIMDJSON_IMPLEMENTATION_HASWELL 0 -#define SIMDJSON_IMPLEMENTATION_WESTMERE 0 -#endif // SIMDJSON_IS_ARM64 - -// Our fast kernels require 64-bit systems. -// -// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions. -// Furthermore, the number of SIMD registers is reduced. -// -// On 32-bit ARM, we would have smaller registers. -// -// The simdjson users should still have the fallback kernel. It is -// slower, but it should run everywhere. -#if SIMDJSON_IS_X86_64 -#ifndef SIMDJSON_IMPLEMENTATION_HASWELL -#define SIMDJSON_IMPLEMENTATION_HASWELL 1 -#endif -#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE -#define SIMDJSON_IMPLEMENTATION_WESTMERE 1 -#endif -#define SIMDJSON_IMPLEMENTATION_ARM64 0 -#endif // SIMDJSON_IS_X86_64 - // We are going to use runtime dispatch. #ifdef SIMDJSON_IS_X86_64 #ifdef __clang__