diff --git a/parallel_hashmap/phmap_bits.h b/parallel_hashmap/phmap_bits.h index 288844c..8e4f017 100644 --- a/parallel_hashmap/phmap_bits.h +++ b/parallel_hashmap/phmap_bits.h @@ -151,6 +151,102 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } #endif +// ----------------------------------------------------------------------------- +// File: optimization.h +// ----------------------------------------------------------------------------- + +#if defined(__pnacl__) + #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#elif defined(__clang__) + // Clang will not tail call given inline volatile assembly. + #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(__GNUC__) + // GCC will not tail call given inline volatile assembly. + #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(_MSC_VER) + #include + // The __nop() intrinsic blocks the optimisation. + #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() +#else + #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#endif + +#if defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpedantic" +#endif + +#ifdef PHMAP_HAVE_INTRINSIC_INT128 + __extension__ typedef unsigned __int128 phmap_uint128; + inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high) + { + auto result = static_cast(a) * static_cast(b); + *high = static_cast(result >> 64); + return static_cast(result); + } + #define PHMAP_HAS_UMUL128 1 +#elif (defined(_MSC_VER)) + #if defined(_M_X64) + #pragma intrinsic(_umul128) + inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high) + { + return _umul128(a, b, high); + } + #define PHMAP_HAS_UMUL128 1 + #endif +#endif + +#if defined(__GNUC__) + #pragma GCC diagnostic pop +#endif + +#if defined(__GNUC__) + // Cache line alignment + #if defined(__i386__) || defined(__x86_64__) + #define PHMAP_CACHELINE_SIZE 64 + #elif defined(__powerpc64__) + #define PHMAP_CACHELINE_SIZE 128 + #elif defined(__aarch64__) + // We would need to read special register ctr_el0 to find out L1 dcache size. + // This value is a good estimate based on a real aarch64 machine. + #define PHMAP_CACHELINE_SIZE 64 + #elif defined(__arm__) + // Cache line sizes for ARM: These values are not strictly correct since + // cache line sizes depend on implementations, not architectures. There + // are even implementations with cache line sizes configurable at boot + // time. + #if defined(__ARM_ARCH_5T__) + #define PHMAP_CACHELINE_SIZE 32 + #elif defined(__ARM_ARCH_7A__) + #define PHMAP_CACHELINE_SIZE 64 + #endif + #endif + + #ifndef PHMAP_CACHELINE_SIZE + // A reasonable default guess. Note that overestimates tend to waste more + // space, while underestimates tend to waste more time. + #define PHMAP_CACHELINE_SIZE 64 + #endif + + #define PHMAP_CACHELINE_ALIGNED __attribute__((aligned(PHMAP_CACHELINE_SIZE))) +#elif defined(_MSC_VER) + #define PHMAP_CACHELINE_SIZE 64 + #define PHMAP_CACHELINE_ALIGNED __declspec(align(PHMAP_CACHELINE_SIZE)) +#else + #define PHMAP_CACHELINE_SIZE 64 + #define PHMAP_CACHELINE_ALIGNED +#endif + + +#if PHMAP_HAVE_BUILTIN(__builtin_expect) || \ + (defined(__GNUC__) && !defined(__clang__)) + #define PHMAP_PREDICT_FALSE(x) (__builtin_expect(x, 0)) + #define PHMAP_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else + #define PHMAP_PREDICT_FALSE(x) (x) + #define PHMAP_PREDICT_TRUE(x) (x) +#endif + // ----------------------------------------------------------------------------- // File: bits.h // ----------------------------------------------------------------------------- @@ -311,102 +407,6 @@ PHMAP_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) { } // namespace base_internal } // namespace phmap -// ----------------------------------------------------------------------------- -// File: optimization.h -// ----------------------------------------------------------------------------- - -#if defined(__pnacl__) - #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } -#elif defined(__clang__) - // Clang will not tail call given inline volatile assembly. - #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") -#elif defined(__GNUC__) - // GCC will not tail call given inline volatile assembly. - #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") -#elif defined(_MSC_VER) - #include - // The __nop() intrinsic blocks the optimisation. - #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() -#else - #define PHMAP_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } -#endif - -#if defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpedantic" -#endif - -#ifdef PHMAP_HAVE_INTRINSIC_INT128 - __extension__ typedef unsigned __int128 phmap_uint128; - inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high) - { - auto result = static_cast(a) * static_cast(b); - *high = static_cast(result >> 64); - return static_cast(result); - } - #define PHMAP_HAS_UMUL128 1 -#elif (defined(_MSC_VER)) - #if defined(_M_X64) - #pragma intrinsic(_umul128) - inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high) - { - return _umul128(a, b, high); - } - #define PHMAP_HAS_UMUL128 1 - #endif -#endif - -#if defined(__GNUC__) - #pragma GCC diagnostic pop -#endif - -#if defined(__GNUC__) - // Cache line alignment - #if defined(__i386__) || defined(__x86_64__) - #define PHMAP_CACHELINE_SIZE 64 - #elif defined(__powerpc64__) - #define PHMAP_CACHELINE_SIZE 128 - #elif defined(__aarch64__) - // We would need to read special register ctr_el0 to find out L1 dcache size. - // This value is a good estimate based on a real aarch64 machine. - #define PHMAP_CACHELINE_SIZE 64 - #elif defined(__arm__) - // Cache line sizes for ARM: These values are not strictly correct since - // cache line sizes depend on implementations, not architectures. There - // are even implementations with cache line sizes configurable at boot - // time. - #if defined(__ARM_ARCH_5T__) - #define PHMAP_CACHELINE_SIZE 32 - #elif defined(__ARM_ARCH_7A__) - #define PHMAP_CACHELINE_SIZE 64 - #endif - #endif - - #ifndef PHMAP_CACHELINE_SIZE - // A reasonable default guess. Note that overestimates tend to waste more - // space, while underestimates tend to waste more time. - #define PHMAP_CACHELINE_SIZE 64 - #endif - - #define PHMAP_CACHELINE_ALIGNED __attribute__((aligned(PHMAP_CACHELINE_SIZE))) -#elif defined(_MSC_VER) - #define PHMAP_CACHELINE_SIZE 64 - #define PHMAP_CACHELINE_ALIGNED __declspec(align(PHMAP_CACHELINE_SIZE)) -#else - #define PHMAP_CACHELINE_SIZE 64 - #define PHMAP_CACHELINE_ALIGNED -#endif - - -#if PHMAP_HAVE_BUILTIN(__builtin_expect) || \ - (defined(__GNUC__) && !defined(__clang__)) - #define PHMAP_PREDICT_FALSE(x) (__builtin_expect(x, 0)) - #define PHMAP_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#else - #define PHMAP_PREDICT_FALSE(x) (x) - #define PHMAP_PREDICT_TRUE(x) (x) -#endif - // ----------------------------------------------------------------------------- // File: endian.h // -----------------------------------------------------------------------------