Skip to content

Commit

Permalink
update config_macros.hpp and vec functions
Browse files Browse the repository at this point in the history
  • Loading branch information
i80287 committed Oct 22, 2024
1 parent fe52826 commit 13df003
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 170 deletions.
41 changes: 32 additions & 9 deletions number_theory/config_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@
#define CONFIG_HAS_AT_LEAST_CXX_23 0
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define CONFIG_HAS_AT_LEAST_C_11 1
#else
#define CONFIG_HAS_AT_LEAST_C_11 0
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L
#define CONFIG_HAS_AT_LEAST_C_17 1
#else
#define CONFIG_HAS_AT_LEAST_C_17 0
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define CONFIG_HAS_AT_LEAST_C_23 1
#else
#define CONFIG_HAS_AT_LEAST_C_23 0
#endif

// https://en.cppreference.com/w/cpp/feature_test
#if defined(__cpp_concepts) && __cpp_concepts >= 201907L
#define CONFIG_HAS_CONCEPTS 1
Expand Down Expand Up @@ -346,17 +364,12 @@

#if CONFIG_HAS_AT_LEAST_CXX_11
#define ATTRIBUTE_NORETURN [[noreturn]]
#elif (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L) && \
(CONFIG_GNUC_AT_LEAST(2, 8) || CONFIG_HAS_GCC_ATTRIBUTE(noreturn))
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(__STDC_VERSION__)
#if __STDC_VERSION__ > 201710L
#elif CONFIG_HAS_AT_LEAST_C_23
#define ATTRIBUTE_NORETURN [[noreturn]]
#elif __STDC_VERSION__ >= 201112L
#elif CONFIG_HAS_AT_LEAST_C_11
#define ATTRIBUTE_NORETURN _Noreturn
#else
#define ATTRIBUTE_NORETURN
#endif
#elif CONFIG_GNUC_AT_LEAST(2, 8) || CONFIG_HAS_GCC_ATTRIBUTE(noreturn)
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
#else
#define ATTRIBUTE_NORETURN
#endif
Expand All @@ -377,6 +390,16 @@
#define ATTRIBUTE_NOTHROW
#endif

#if CONFIG_HAS_AT_LEAST_CXX_17
#define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
#elif CONFIG_HAS_AT_LEAST_C_23
#define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
#elif CONFIG_GNUC_AT_LEAST(7, 1) || CONFIG_HAS_GCC_ATTRIBUTE(fallthrough)
#define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
#else
#define ATTRIBUTE_FALLTHROUGH
#endif

// Copypasted from LLVM's int_endianness.h

/* ===-- int_endianness.h - configuration header for compiler-rt ------------===
Expand Down
41 changes: 32 additions & 9 deletions vec_instructs/config_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@
#define CONFIG_HAS_AT_LEAST_CXX_23 0
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define CONFIG_HAS_AT_LEAST_C_11 1
#else
#define CONFIG_HAS_AT_LEAST_C_11 0
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L
#define CONFIG_HAS_AT_LEAST_C_17 1
#else
#define CONFIG_HAS_AT_LEAST_C_17 0
#endif

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define CONFIG_HAS_AT_LEAST_C_23 1
#else
#define CONFIG_HAS_AT_LEAST_C_23 0
#endif

// https://en.cppreference.com/w/cpp/feature_test
#if defined(__cpp_concepts) && __cpp_concepts >= 201907L
#define CONFIG_HAS_CONCEPTS 1
Expand Down Expand Up @@ -346,17 +364,12 @@

#if CONFIG_HAS_AT_LEAST_CXX_11
#define ATTRIBUTE_NORETURN [[noreturn]]
#elif (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L) && \
(CONFIG_GNUC_AT_LEAST(2, 8) || CONFIG_HAS_GCC_ATTRIBUTE(noreturn))
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(__STDC_VERSION__)
#if __STDC_VERSION__ > 201710L
#elif CONFIG_HAS_AT_LEAST_C_23
#define ATTRIBUTE_NORETURN [[noreturn]]
#elif __STDC_VERSION__ >= 201112L
#elif CONFIG_HAS_AT_LEAST_C_11
#define ATTRIBUTE_NORETURN _Noreturn
#else
#define ATTRIBUTE_NORETURN
#endif
#elif CONFIG_GNUC_AT_LEAST(2, 8) || CONFIG_HAS_GCC_ATTRIBUTE(noreturn)
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
#else
#define ATTRIBUTE_NORETURN
#endif
Expand All @@ -377,6 +390,16 @@
#define ATTRIBUTE_NOTHROW
#endif

#if CONFIG_HAS_AT_LEAST_CXX_17
#define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
#elif CONFIG_HAS_AT_LEAST_C_23
#define ATTRIBUTE_FALLTHROUGH [[fallthrough]]
#elif CONFIG_GNUC_AT_LEAST(7, 1) || CONFIG_HAS_GCC_ATTRIBUTE(fallthrough)
#define ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
#else
#define ATTRIBUTE_FALLTHROUGH
#endif

// Copypasted from LLVM's int_endianness.h

/* ===-- int_endianness.h - configuration header for compiler-rt ------------===
Expand Down
96 changes: 44 additions & 52 deletions vec_instructs/memcount.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#if !defined(MEMSET_COUNT_H)
#define MEMSET_COUNT_H 1
#if !defined(MEMCOUNT_H)
#define MEMCOUNT_H 1

#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif // __cplusplus
#define EXTERN_WITH_C_LINKAGE_BEGIN extern "C" {
#define EXTERN_WITH_C_LINKAGE_END }
#else
#define EXTERN_WITH_C_LINKAGE_BEGIN
#define EXTERN_WITH_C_LINKAGE_END
#endif

#include <stdint.h>
EXTERN_WITH_C_LINKAGE_BEGIN
#include <x86intrin.h>
#if defined(__cplusplus)
}
#endif // __cplusplus
EXTERN_WITH_C_LINKAGE_END

#include "config_macros.hpp"

#if defined(__cplusplus)
extern "C" {
#endif // __cplusplus
EXTERN_WITH_C_LINKAGE_BEGIN

#define MEMCOUNT_ATTRIBUTES \
ATTRIBUTE_NODISCARD_WITH_MESSAGE("return value of the memcount should not be ommited") \
Expand All @@ -28,44 +30,26 @@ extern "C" {

MEMCOUNT_ATTRIBUTES
FAST_MEMCOUNT_TARGET_ATTRIBUTE
size_t memcount_avx(const uint8_t* const src, const uint8_t chr,
size_t size) CONFIG_NOEXCEPT_FUNCTION {
#if defined(__GNUC__)
#if !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#endif
if (__builtin_expect(src == NULL, 0))
return 0;
#if !defined(__clang__)
#pragma GCC diagnostic pop
#else
#pragma clang diagnostic pop
#endif
#else
if (src == NULL)
return 0;
#endif

static inline size_t memcount_avx(const uint8_t* const src, const uint8_t chr,
size_t size) CONFIG_NOEXCEPT_FUNCTION {
#if defined(__cplusplus)
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
#endif

const uint8_t* not_aligned_address = src;
const __m256i* aligned_32_address =
(const __m256i*)(((uintptr_t)not_aligned_address + 31) & ~(uintptr_t)31);

uintptr_t mem_offset = (uintptr_t)aligned_32_address - (uintptr_t)not_aligned_address;
#if defined(__GNUC__)
if (__builtin_expect(mem_offset > size, 0))
#else
if (mem_offset > size)
#endif
if (unlikely(mem_offset > size)) {
mem_offset = size;
}
size -= mem_offset;

size_t eq_count = 0;
Expand All @@ -89,8 +73,12 @@ size_t memcount_avx(const uint8_t* const src, const uint8_t chr,
eq_count += *not_aligned_address == cmp_chr_u32;
}

#if defined(__cplusplus)
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif

return eq_count;
Expand All @@ -99,8 +87,8 @@ size_t memcount_avx(const uint8_t* const src, const uint8_t chr,
#undef FAST_MEMCOUNT_TARGET_ATTRIBUTE

MEMCOUNT_ATTRIBUTES
size_t memcount_default(const uint8_t* const src, const uint8_t chr,
size_t size) CONFIG_NOEXCEPT_FUNCTION {
static inline size_t memcount_default(const uint8_t* const src, const uint8_t chr,
size_t size) CONFIG_NOEXCEPT_FUNCTION {
size_t cnt = 0;
const uint32_t c = chr;
for (const uint8_t* s = src; size > 0; ++s, --size) {
Expand All @@ -111,8 +99,6 @@ size_t memcount_default(const uint8_t* const src, const uint8_t chr,

#if defined(__GNUC__) || defined(__clang__)

// clang-format off

ATTRIBUTE_NODISCARD_WITH_MESSAGE("this function is resolver and should not be used")
ATTRIBUTE_MAYBE_UNUSED
ATTRIBUTE_NOTHROW
Expand All @@ -122,22 +108,23 @@ __attribute__((no_sanitize("address", "thread", "memory", "undefined")))
#elif defined(__GNUC__)
__attribute__((no_sanitize_address, no_sanitize_thread, no_sanitize_undefined))
#endif
static inline size_t (*resolve_memcount(void))(const uint8_t*, uint8_t,
size_t) {
static inline size_t (*resolve_memcount(void))(const uint8_t*, uint8_t, size_t) {
__builtin_cpu_init();
return __builtin_cpu_supports("avx2") && __builtin_cpu_supports("popcnt") ? memcount_avx
: memcount_default;
}

#if defined(linux) || defined(__linux__)

// clang-format off

MEMCOUNT_ATTRIBUTES
#if defined(__cplusplus) && defined(__clang__)
__attribute__((ifunc("_ZL16resolve_memcountv")))
#else
__attribute__((ifunc("resolve_memcount")))
#endif
size_t memcount(const uint8_t* const src, const uint8_t chr, size_t size) CONFIG_NOEXCEPT_FUNCTION;
static inline size_t memcount(const uint8_t* const src, const uint8_t chr, size_t size) CONFIG_NOEXCEPT_FUNCTION;

#else // !__linux__

Expand All @@ -152,16 +139,18 @@ size_t (*const memcount)(const uint8_t* const src, const uint8_t chr, size_t siz

size_t (*memcount)(const uint8_t* const src, const uint8_t chr, size_t size) = NULL;

__attribute__((constructor)) static inline void memcount_initializer(void) {
// clang-format on

ATTRIBUTE_NOTHROW
__attribute__((constructor)) static inline void memcount_initializer(void)
CONFIG_NOEXCEPT_FUNCTION {
memcount = resolve_memcount();
}

#endif

#endif

// clang-format on

#else // !__GNUC__

MEMCOUNT_ATTRIBUTES
Expand All @@ -173,8 +162,11 @@ static inline size_t memcount(const uint8_t* const src, const uint8_t chr,

#endif

#if defined(__cplusplus)
}
#endif // __cplusplus
#undef MEMCOUNT_ATTRIBUTES

EXTERN_WITH_C_LINKAGE_END

#undef EXTERN_WITH_C_LINKAGE_END
#undef EXTERN_WITH_C_LINKAGE_BEGIN

#endif // !MEMSET_COUNT_H
#endif // !MEMCOUNT_H
Loading

0 comments on commit 13df003

Please sign in to comment.