Skip to content

Commit

Permalink
Merge pull request #9 from i80287/update-vec-functions-and-tests
Browse files Browse the repository at this point in the history
Update vec functions and tests
  • Loading branch information
i80287 authored Oct 22, 2024
2 parents 0eeeb48 + 82d3283 commit 8abfd17
Show file tree
Hide file tree
Showing 15 changed files with 1,578 additions and 472 deletions.
13 changes: 2 additions & 11 deletions number_theory/bitmatrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,6 @@ constexpr void transpose64(uint64_t (&src)[64]) noexcept {
#define CONSTEXPR_POINTER_CAST
#endif

#if CONFIG_HAS_AT_LEAST_CXX_20
#define NODISCARD_WITH_MESSAGE(message) [[nodiscard(message)]]
#elif CONFIG_HAS_AT_LEAST_CXX_17
#define NODISCARD_WITH_MESSAGE(message) [[nodiscard]]
#else
#define NODISCARD_WITH_MESSAGE(message)
#endif

namespace detail {
struct square_bitmatrix_helper {
private:
Expand Down Expand Up @@ -685,7 +677,7 @@ struct alignas(std::uint64_t) alignas(word_type) square_bitmatrix {
do_flip_inplace(data_);
return *this;
}
NODISCARD_WITH_MESSAGE("This method is not inplace. Use flip() for this purpose")
ATTRIBUTE_NODISCARD_WITH_MESSAGE("This method is not inplace. Use flip() for this purpose")
ATTRIBUTE_PURE
CONSTEXPR_BITSET_OPS
square_bitmatrix operator~() const noexcept {
Expand All @@ -708,7 +700,7 @@ struct alignas(std::uint64_t) alignas(word_type) square_bitmatrix {
transpose_matrix(data_);
return *this;
}
NODISCARD_WITH_MESSAGE("This method is not inplace. Use transpose() for this purpose")
ATTRIBUTE_NODISCARD_WITH_MESSAGE("This method is not inplace. Use transpose() for this purpose")
ATTRIBUTE_PURE
CONSTEXPR_POINTER_CAST
square_bitmatrix T() const noexcept {
Expand Down Expand Up @@ -980,6 +972,5 @@ struct alignas(std::uint64_t) alignas(word_type) square_bitmatrix {
}
};

#undef NODISCARD_WITH_MESSAGE
#undef CONSTEXPR_POINTER_CAST
#undef CONSTEXPR_BITSET_OPS
157 changes: 151 additions & 6 deletions number_theory/config_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
#endif

/* Test for __has_attribute as per __glibc_has_attribute in glibc */
#if defined(__has_attribute) && (!defined(__clang__) || CONFIG_CLANG_AT_LEAST(2, 5))
#if defined(__has_attribute) && (!defined(__clang__) || CONFIG_CLANG_AT_LEAST(4, 5))
#define CONFIG_HAS_GCC_ATTRIBUTE(attr) __has_attribute(attr)
#else
#define CONFIG_HAS_GCC_ATTRIBUTE(attr) 0
#endif

#ifdef __has_cpp_attribute
#if defined(__cplusplus) && defined(__has_cpp_attribute)
#define CONFIG_HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr)
#else
#define CONFIG_HAS_CPP_ATTRIBUTE(attr) 0
Expand Down 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 @@ -116,15 +134,33 @@
#elif CONFIG_HAS_BUILTIN(__builtin_unreachable)
#define CONFIG_UNREACHABLE() __builtin_unreachable()
#elif CONFIG_HAS_BUILTIN(__builtin_assume)
#if defined(__cplusplus)
#define CONFIG_UNREACHABLE() __builtin_assume(false)
#else
#define CONFIG_UNREACHABLE() __builtin_assume(0)
#endif
#elif CONFIG_GNUC_AT_LEAST(13, 0) && CONFIG_HAS_GCC_ATTRIBUTE(assume)
#if defined(__cplusplus)
#define CONFIG_UNREACHABLE() __attribute__((assume(false)))
#else
#define CONFIG_UNREACHABLE() __attribute__((assume(0)))
#endif
#elif defined(_MSC_VER)
#if defined(__cplusplus)
#define CONFIG_UNREACHABLE() __assume(false)
#else
#define CONFIG_UNREACHABLE() __assume(0)
#endif
#else
#if defined(__cplusplus)
#define CONFIG_UNREACHABLE() \
do { \
} while (false)
#else
#define CONFIG_UNREACHABLE() \
do { \
} while (0)
#endif
#endif

#if CONFIG_HAS_AT_LEAST_CXX_23 && CONFIG_HAS_CPP_ATTRIBUTE(assume)
Expand All @@ -137,12 +173,21 @@
#elif defined(_MSC_VER)
#define ATTRIBUTE_ASSUME(expr) __assume(expr)
#else
#if defined(__cplusplus)
#define ATTRIBUTE_ASSUME(expr) \
do { \
if (!(expr)) { \
CONFIG_UNREACHABLE(); \
} \
} while (false)
#else
#define ATTRIBUTE_ASSUME(expr) \
do { \
if (!(expr)) { \
CONFIG_UNREACHABLE(); \
} \
} while (0)
#endif
#endif

/* __builtin_expect is in gcc 3.0 */
Expand All @@ -159,8 +204,8 @@
#define likely(x) __builtin_expect(static_cast<bool>(x), true)
#define unlikely(x) __builtin_expect(static_cast<bool>(x), false)
#else
#define likely(x) __builtin_expect((x), true)
#define unlikely(x) __builtin_expect((x), false)
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
#endif

#else
Expand Down Expand Up @@ -283,9 +328,15 @@
__attribute__((access(mode, memory_argument_pos)))
#define ATTRIBUTE_SIZED_ACCESS(mode, memory_argument_pos, range_size_argument_pos) \
__attribute__((access(mode, memory_argument_pos, range_size_argument_pos)))
#if CONFIG_GNUC_AT_LEAST(11, 0)
#define ATTRIBUTE_ACCESS_NONE(memory_argument_pos) ATTRIBUTE_ACCESS(none, memory_argument_pos)
#else
#define ATTRIBUTE_ACCESS_NONE(memory_argument_pos)
#endif
#else
#define ATTRIBUTE_ACCESS(mode, memory_argument_pos)
#define ATTRIBUTE_SIZED_ACCESS(mode, memory_argument_pos, range_size_argument_pos)
#define ATTRIBUTE_ACCESS_NONE(memory_argument_pos)
#endif

/**
Expand Down Expand Up @@ -323,6 +374,59 @@
#define ATTRIBUTE_REINITIALIZES
#endif

#if CONFIG_HAS_AT_LEAST_CXX_17
#define ATTRIBUTE_NODISCARD [[nodiscard]]
#if CONFIG_HAS_AT_LEAST_CXX_20
#define ATTRIBUTE_NODISCARD_WITH_MESSAGE(message) [[nodiscard(message)]]
#else
#define ATTRIBUTE_NODISCARD_WITH_MESSAGE(message) [[nodiscard]]
#endif
#elif CONFIG_GNUC_AT_LEAST(3, 4) || CONFIG_HAS_GCC_ATTRIBUTE(warn_unused_result)
#define ATTRIBUTE_NODISCARD __attribute__((warn_unused_result))
#define ATTRIBUTE_NODISCARD_WITH_MESSAGE(message) __attribute__((warn_unused_result))
#else
#define ATTRIBUTE_NODISCARD
#define ATTRIBUTE_NODISCARD_WITH_MESSAGE(message)
#endif

#if CONFIG_HAS_AT_LEAST_CXX_11
#define ATTRIBUTE_NORETURN [[noreturn]]
#elif CONFIG_HAS_AT_LEAST_C_23
#define ATTRIBUTE_NORETURN [[noreturn]]
#elif CONFIG_HAS_AT_LEAST_C_11
#define ATTRIBUTE_NORETURN _Noreturn
#elif CONFIG_GNUC_AT_LEAST(2, 8) || CONFIG_HAS_GCC_ATTRIBUTE(noreturn)
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
#else
#define ATTRIBUTE_NORETURN
#endif

#if defined(__cplusplus) && (CONFIG_GNUC_AT_LEAST(2, 8) || CONFIG_CLANG_AT_LEAST(4, 0))
#if CONFIG_HAS_AT_LEAST_CXX_11
#define CONFIG_NOEXCEPT_FUNCTION noexcept(true)
#else
#define CONFIG_NOEXCEPT_FUNCTION throw()
#endif
#else
#define CONFIG_NOEXCEPT_FUNCTION
#endif

#if CONFIG_GNUC_AT_LEAST(3, 4) || CONFIG_HAS_GCC_ATTRIBUTE(nothrow)
#define ATTRIBUTE_NOTHROW __attribute__((nothrow))
#else
#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 Expand Up @@ -436,6 +540,8 @@
#error Unable to determine endian
#endif /* Check we found an endianness correctly. */

#ifdef __cplusplus

#if (defined(_MSC_VER) || defined(__MINGW32__)) && CONFIG_HAS_INCLUDE(<intrin.h>)
#include <intrin.h> // for _ReadWriteBarrier
#endif
Expand All @@ -445,13 +551,21 @@ namespace config {
namespace detail {

#if (defined(_MSC_VER) || defined(__MINGW32__)) && CONFIG_HAS_INCLUDE(<intrin.h>)
ATTRIBUTE_NOINLINE inline void sink_char_ptr(char const volatile*) {}
#if defined(__GNUC__)
// inline function 'sink_char_ptr' given attribute 'noinline'
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
#endif
ATTRIBUTE_NOINLINE static inline void sink_char_ptr(char const volatile*) {}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif

} // namespace detail

template <class T>
ATTRIBUTE_ALWAYS_INLINE inline void do_not_optimize_away(T&& expr) noexcept {
ATTRIBUTE_ALWAYS_INLINE static inline void do_not_optimize_away(T&& expr) noexcept {
#if (defined(_MSC_VER) || defined(__MINGW32__)) && CONFIG_HAS_INCLUDE(<intrin.h>)
::config::detail::sink_char_ptr(&reinterpret_cast<volatile const char&>(expr));
_ReadWriteBarrier();
Expand Down Expand Up @@ -500,4 +614,35 @@ ATTRIBUTE_ALWAYS_INLINE constexpr bool is_gcc_constant_p(ATTRIBUTE_MAYBE_UNUSED

} // namespace config

#else

#if (defined(_MSC_VER) || defined(__MINGW32__)) && CONFIG_HAS_INCLUDE(<intrin.h>)
#include <intrin.h> // for _ReadWriteBarrier
#if defined(__GNUC__)
// inline function 'sink_char_ptr' given attribute 'noinline'
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
#endif
ATTRIBUTE_NOINLINE static inline void sink_char_ptr(
ATTRIBUTE_MAYBE_UNUSED char const volatile* ptr) {}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

#define do_not_optimize_away(expr) \
do { \
sink_char_ptr((volatile const char*)&(expr)); \
_ReadWriteBarrier(); \
} while (0)

#elif defined(__GNUG__)
#define do_not_optimize_away(expr) asm volatile("" ::"r,m,i"(expr))
#elif defined(__GNUC__)
#define do_not_optimize_away(expr) __asm__ volatile("" ::"r,m,i"(expr))
#else
#define do_not_optimize_away(expr) __asm__("" ::"r,m,i"(expr));
#endif

#endif

#endif // !CONFIG_MACROS_HPP
Loading

0 comments on commit 8abfd17

Please sign in to comment.