[libc-commits] [libc] 8e4efad - [libc] Optimize Loop strategy
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Mon Aug 16 15:18:09 PDT 2021
Author: Guillaume Chatelet
Date: 2021-08-16T22:17:56Z
New Revision: 8e4efad9917ce0b7d1751c34a8d6907e610050e6
URL: https://github.com/llvm/llvm-project/commit/8e4efad9917ce0b7d1751c34a8d6907e610050e6
DIFF: https://github.com/llvm/llvm-project/commit/8e4efad9917ce0b7d1751c34a8d6907e610050e6.diff
LOG: [libc] Optimize Loop strategy
Since the precondition for loop is `size >= T::kSize` we always expect
at least one run of the loop. This patch transforms the for-loop into a
do/while-loop which saves at least one test.
We also add a second template parameter to allow the Tail operation to
differ from the loop operation.
Added:
Modified:
libc/src/string/memory_utils/elements.h
Removed:
################################################################################
diff --git a/libc/src/string/memory_utils/elements.h b/libc/src/string/memory_utils/elements.h
index d3fadbb11c611..5f19e861e19f4 100644
--- a/libc/src/string/memory_utils/elements.h
+++ b/libc/src/string/memory_utils/elements.h
@@ -234,32 +234,47 @@ template <typename T> struct HeadTail {
//
// Precondition:
// - size >= T::kSize
-template <typename T> struct Loop {
+template <typename T, typename TailT = T> struct Loop {
+ static_assert(T::kSize == TailT::kSize,
+ "Tail type must have the same size as T");
+
static void Copy(char *__restrict dst, const char *__restrict src,
size_t size) {
- for (size_t offset = 0; offset < size - T::kSize; offset += T::kSize)
+ size_t offset = 0;
+ do {
T::Copy(dst + offset, src + offset);
- Tail<T>::Copy(dst, src, size);
+ offset += T::kSize;
+ } while (offset < size - T::kSize);
+ Tail<TailT>::Copy(dst, src, size);
}
static bool Equals(const char *lhs, const char *rhs, size_t size) {
- for (size_t offset = 0; offset < size - T::kSize; offset += T::kSize)
+ size_t offset = 0;
+ do {
if (!T::Equals(lhs + offset, rhs + offset))
return false;
- return Tail<T>::Equals(lhs, rhs, size);
+ offset += T::kSize;
+ } while (offset < size - T::kSize);
+ return Tail<TailT>::Equals(lhs, rhs, size);
}
static int ThreeWayCompare(const char *lhs, const char *rhs, size_t size) {
- for (size_t offset = 0; offset < size - T::kSize; offset += T::kSize)
+ size_t offset = 0;
+ do {
if (!T::Equals(lhs + offset, rhs + offset))
return T::ThreeWayCompare(lhs + offset, rhs + offset);
- return Tail<T>::ThreeWayCompare(lhs, rhs, size);
+ offset += T::kSize;
+ } while (offset < size - T::kSize);
+ return Tail<TailT>::ThreeWayCompare(lhs, rhs, size);
}
static void SplatSet(char *dst, const unsigned char value, size_t size) {
- for (size_t offset = 0; offset < size - T::kSize; offset += T::kSize)
+ size_t offset = 0;
+ do {
T::SplatSet(dst + offset, value);
- Tail<T>::SplatSet(dst, value, size);
+ offset += T::kSize;
+ } while (offset < size - T::kSize);
+ Tail<TailT>::SplatSet(dst, value, size);
}
};
More information about the libc-commits
mailing list