[libc-commits] [libc] 458734b - [reland][libc] handle memset sequence as a separate struct
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Wed Apr 19 01:37:58 PDT 2023
Author: Guillaume Chatelet
Date: 2023-04-19T08:37:49Z
New Revision: 458734b8b9ab457e3c88b76e87761a8f4c27a290
URL: https://github.com/llvm/llvm-project/commit/458734b8b9ab457e3c88b76e87761a8f4c27a290
DIFF: https://github.com/llvm/llvm-project/commit/458734b8b9ab457e3c88b76e87761a8f4c27a290.diff
LOG: [reland][libc] handle memset sequence as a separate struct
These sequence of calls don't really make sense for head_tail and loop_and_tail.
Added:
Modified:
libc/src/string/memory_utils/memset_implementations.h
libc/src/string/memory_utils/op_generic.h
libc/test/src/string/memory_utils/op_tests.cpp
Removed:
################################################################################
diff --git a/libc/src/string/memory_utils/memset_implementations.h b/libc/src/string/memory_utils/memset_implementations.h
index dfc7df87aceb2..e78a4470f4985 100644
--- a/libc/src/string/memory_utils/memset_implementations.h
+++ b/libc/src/string/memory_utils/memset_implementations.h
@@ -57,7 +57,7 @@ inline_memset_x86(Ptr dst, uint8_t value, size_t count) {
if (count == 2)
return generic::Memset<uint16_t>::block(dst, value);
if (count == 3)
- return generic::Memset<uint16_t, uint8_t>::block(dst, value);
+ return generic::MemsetSequence<uint16_t, uint8_t>::block(dst, value);
if (count <= 8)
return generic::Memset<uint32_t>::head_tail(dst, value, count);
if (count <= 16)
diff --git a/libc/src/string/memory_utils/op_generic.h b/libc/src/string/memory_utils/op_generic.h
index 1d203d6261403..663f42809ecc9 100644
--- a/libc/src/string/memory_utils/op_generic.h
+++ b/libc/src/string/memory_utils/op_generic.h
@@ -165,11 +165,6 @@ template <typename First, typename... Ts> struct SupportedTypes {
using TypeFor = typename details::Largest<Size, First, Ts...>::type;
};
-// Returns the sum of the sizeof of all the TS types.
-template <typename... TS> static constexpr size_t sum_sizeof() {
- return (... + sizeof(TS));
-}
-
// Map from sizes to structures offering static load, store and splat methods.
// Note: On platforms lacking vector support, we use the ArrayType below and
// decompose the operation in smaller pieces.
@@ -213,8 +208,8 @@ using getTypeFor = cpp::conditional_t<
// Memset
///////////////////////////////////////////////////////////////////////////////
-template <typename T, typename... TS> struct Memset {
- static constexpr size_t SIZE = sum_sizeof<T, TS...>();
+template <typename T> struct Memset {
+ static constexpr size_t SIZE = sizeof(T);
LIBC_INLINE static void block(Ptr dst, uint8_t value) {
static_assert(is_element_type_v<T>);
@@ -226,8 +221,6 @@ template <typename T, typename... TS> struct Memset {
for (size_t I = 0; I < array_size_v<T>; ++I)
store<value_type>(dst + (I * sizeof(value_type)), Splat);
}
- if constexpr (sizeof...(TS))
- Memset<TS...>::block(dst + sizeof(T), value);
}
LIBC_INLINE static void tail(Ptr dst, uint8_t value, size_t count) {
@@ -250,12 +243,22 @@ template <typename T, typename... TS> struct Memset {
}
};
+template <typename T, typename... TS> struct MemsetSequence {
+ static constexpr size_t SIZE = (sizeof(T) + ... + sizeof(TS));
+ LIBC_INLINE static void block(Ptr dst, uint8_t value) {
+ Memset<T>::block(dst, value);
+ if constexpr (sizeof...(TS) > 0) {
+ return MemsetSequence<TS...>::block(dst + sizeof(T), value);
+ }
+ }
+};
+
///////////////////////////////////////////////////////////////////////////////
// Memmove
///////////////////////////////////////////////////////////////////////////////
template <typename T> struct Memmove {
- static constexpr size_t SIZE = sum_sizeof<T>();
+ static constexpr size_t SIZE = sizeof(T);
LIBC_INLINE static void block(Ptr dst, CPtr src) {
store<T>(dst, load<T>(src));
diff --git a/libc/test/src/string/memory_utils/op_tests.cpp b/libc/test/src/string/memory_utils/op_tests.cpp
index b63a629da3f05..f845f49a01d90 100644
--- a/libc/test/src/string/memory_utils/op_tests.cpp
+++ b/libc/test/src/string/memory_utils/op_tests.cpp
@@ -21,6 +21,18 @@
namespace __llvm_libc {
+template <typename T> struct has_head_tail {
+ template <typename C> static char sfinae(decltype(&C::head_tail));
+ template <typename C> static uint16_t sfinae(...);
+ static constexpr bool value = sizeof(sfinae<T>(0)) == sizeof(char);
+};
+
+template <typename T> struct has_loop_and_tail {
+ template <typename C> static char sfinae(decltype(&C::loop_and_tail));
+ template <typename C> static uint16_t sfinae(...);
+ static constexpr bool value = sizeof(sfinae<T>(0)) == sizeof(char);
+};
+
// Allocates two Buffer and extracts two spans out of them, one
// aligned and one misaligned. Tests are run on both spans.
struct Buffers {
@@ -132,7 +144,10 @@ using MemsetImplementations = testing::TypeList<
#endif
generic::Memset<uint32_t>, generic::Memset<cpp::array<uint32_t, 2>>, //
generic::Memset<uint16_t>, generic::Memset<cpp::array<uint16_t, 2>>, //
- generic::Memset<uint8_t>, generic::Memset<cpp::array<uint8_t, 2>> //
+ generic::Memset<uint8_t>, generic::Memset<cpp::array<uint8_t, 2>>, //
+ generic::MemsetSequence<uint8_t, uint8_t>, //
+ generic::MemsetSequence<uint16_t, uint8_t>, //
+ generic::MemsetSequence<uint32_t, uint16_t, uint8_t> //
>;
// Adapt CheckMemset signature to op implementation signatures.
@@ -158,7 +173,8 @@ TYPED_TEST(LlvmLibcOpTest, Memset, MemsetImplementations) {
}
}
}
- { // Test head tail operations from kSize to 2 * kSize.
+ if constexpr (has_head_tail<Impl>::value) {
+ // Test head tail operations from kSize to 2 * kSize.
static constexpr auto HeadTailImpl = SetAdaptor<Impl::head_tail>;
Buffer DstBuffer(2 * kSize);
for (size_t size = kSize; size < 2 * kSize; ++size) {
@@ -167,7 +183,8 @@ TYPED_TEST(LlvmLibcOpTest, Memset, MemsetImplementations) {
ASSERT_TRUE(CheckMemset<HeadTailImpl>(dst, value, size));
}
}
- { // Test loop operations from kSize to 3 * kSize.
+ if constexpr (has_loop_and_tail<Impl>::value) {
+ // Test loop operations from kSize to 3 * kSize.
if constexpr (kSize > 1) {
static constexpr auto LoopImpl = SetAdaptor<Impl::loop_and_tail>;
Buffer DstBuffer(3 * kSize);
More information about the libc-commits
mailing list