[libc-commits] [libc] cd2f5d5 - [libc] rewrite aarch64 memcmp implementation
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Thu Jul 29 07:41:24 PDT 2021
Author: Guillaume Chatelet
Date: 2021-07-29T14:41:12Z
New Revision: cd2f5d5b496d43924c27e22f8abd9cff9266d028
URL: https://github.com/llvm/llvm-project/commit/cd2f5d5b496d43924c27e22f8abd9cff9266d028
DIFF: https://github.com/llvm/llvm-project/commit/cd2f5d5b496d43924c27e22f8abd9cff9266d028.diff
LOG: [libc] rewrite aarch64 memcmp implementation
This patch is simply rearranging the code layout so it's easier to understand.
Differential Revision: https://reviews.llvm.org/D106641
Added:
Modified:
libc/src/string/aarch64/memcmp.cpp
libc/src/string/memory_utils/elements.h
Removed:
################################################################################
diff --git a/libc/src/string/aarch64/memcmp.cpp b/libc/src/string/aarch64/memcmp.cpp
index 503c239e122b7..7ef3004a06150 100644
--- a/libc/src/string/aarch64/memcmp.cpp
+++ b/libc/src/string/aarch64/memcmp.cpp
@@ -12,48 +12,41 @@
#include <stddef.h> // size_t
namespace __llvm_libc {
-namespace aarch64 {
-static int memcmp_impl(const char *lhs, const char *rhs, size_t count) {
- if (count == 0)
+static int memcmp_aarch64(const char *lhs, const char *rhs, size_t count) {
+ // Use aarch64 strategies (_1, _2, _3 ...)
+ using namespace __llvm_libc::aarch64;
+
+ if (count == 0) // [0, 0]
return 0;
- if (count == 1)
+ if (count == 1) // [1, 1]
return ThreeWayCompare<_1>(lhs, rhs);
- else if (count == 2)
+ if (count == 2) // [2, 2]
return ThreeWayCompare<_2>(lhs, rhs);
- else if (count == 3)
+ if (count == 3) // [3, 3]
return ThreeWayCompare<_3>(lhs, rhs);
- else if (count < 8)
+ if (count < 8) // [4, 7]
return ThreeWayCompare<HeadTail<_4>>(lhs, rhs, count);
- else if (count < 16)
+ if (count < 16) // [8, 15]
return ThreeWayCompare<HeadTail<_8>>(lhs, rhs, count);
- else if (count < 128) {
- if (Equals<_16>(lhs, rhs)) {
- if (count < 32)
- return ThreeWayCompare<Tail<_16>>(lhs, rhs, count);
- else {
- if (Equals<_16>(lhs + 16, rhs + 16)) {
- if (count < 64)
- return ThreeWayCompare<Tail<_32>>(lhs, rhs, count);
- if (count < 128)
- return ThreeWayCompare<Loop<_16>>(lhs + 32, rhs + 32, count - 32);
- } else
- return ThreeWayCompare<_16>(lhs + count - 32, rhs + count - 32);
- }
- }
+ if (unlikely(count >= 128)) // [128, ∞]
+ return ThreeWayCompare<Align<_16>::Then<Loop<_32>>>(lhs, rhs, count);
+ if (!Equals<_16>(lhs, rhs)) // [16, 16]
return ThreeWayCompare<_16>(lhs, rhs);
- } else
- return ThreeWayCompare<Align<_16, Arg::Lhs>::Then<Loop<_32>>>(lhs, rhs,
- count);
+ if (count < 32) // [17, 31]
+ return ThreeWayCompare<Tail<_16>>(lhs, rhs, count);
+ if (!Equals<Skip<16>::Then<_16>>(lhs, rhs)) // [32, 32]
+ return ThreeWayCompare<Skip<16>::Then<_16>>(lhs, rhs);
+ if (count < 64) // [33, 63]
+ return ThreeWayCompare<Tail<_32>>(lhs, rhs, count);
+ // [64, 127]
+ return ThreeWayCompare<Skip<32>::Then<Loop<_16>>>(lhs, rhs, count);
}
-} // namespace aarch64
LLVM_LIBC_FUNCTION(int, memcmp,
(const void *lhs, const void *rhs, size_t count)) {
-
- const char *_lhs = reinterpret_cast<const char *>(lhs);
- const char *_rhs = reinterpret_cast<const char *>(rhs);
- return aarch64::memcmp_impl(_lhs, _rhs, count);
+ return memcmp_aarch64(reinterpret_cast<const char *>(lhs),
+ reinterpret_cast<const char *>(rhs), count);
}
} // namespace __llvm_libc
diff --git a/libc/src/string/memory_utils/elements.h b/libc/src/string/memory_utils/elements.h
index 48fb0084d610f..d3fadbb11c611 100644
--- a/libc/src/string/memory_utils/elements.h
+++ b/libc/src/string/memory_utils/elements.h
@@ -304,7 +304,7 @@ template <size_t Alignment> struct AlignHelper<Arg::_2, Alignment> {
//
// e.g. A 16-byte Destination Aligned 32-byte Loop Copy can be written as:
// Copy<Align<_16, Arg::Dst>::Then<Loop<_32>>>(dst, src, count);
-template <typename AlignmentT, Arg AlignOn> struct Align {
+template <typename AlignmentT, Arg AlignOn = Arg::_1> struct Align {
private:
static constexpr size_t Alignment = AlignmentT::kSize;
static_assert(Alignment > 1, "Alignment must be more than 1");
@@ -342,6 +342,44 @@ template <typename AlignmentT, Arg AlignOn> struct Align {
};
};
+// An operation that allows to skip the specified amount of bytes.
+template <ptr
diff _t Bytes> struct Skip {
+ template <typename NextT> struct Then {
+ static void Copy(char *__restrict dst, const char *__restrict src,
+ size_t size) {
+ NextT::Copy(dst + Bytes, src + Bytes, size - Bytes);
+ }
+
+ static void Copy(char *__restrict dst, const char *__restrict src) {
+ NextT::Copy(dst + Bytes, src + Bytes);
+ }
+
+ static bool Equals(const char *lhs, const char *rhs, size_t size) {
+ return NextT::Equals(lhs + Bytes, rhs + Bytes, size - Bytes);
+ }
+
+ static bool Equals(const char *lhs, const char *rhs) {
+ return NextT::Equals(lhs + Bytes, rhs + Bytes);
+ }
+
+ static int ThreeWayCompare(const char *lhs, const char *rhs, size_t size) {
+ return NextT::ThreeWayCompare(lhs + Bytes, rhs + Bytes, size - Bytes);
+ }
+
+ static int ThreeWayCompare(const char *lhs, const char *rhs) {
+ return NextT::ThreeWayCompare(lhs + Bytes, rhs + Bytes);
+ }
+
+ static void SplatSet(char *dst, const unsigned char value, size_t size) {
+ NextT::SplatSet(dst + Bytes, value, size - Bytes);
+ }
+
+ static void SplatSet(char *dst, const unsigned char value) {
+ NextT::SplatSet(dst + Bytes, value);
+ }
+ };
+};
+
// Fixed-size Builtin Operations
// -----------------------------
// Note: Do not use 'builtin' right now as it requires the implementation of the
More information about the libc-commits
mailing list