[libc-commits] [libc] af059df - [libc] Add a reasonably optimized version for bcmp

Guillaume Chatelet via libc-commits libc-commits at lists.llvm.org
Tue Nov 30 02:52:43 PST 2021


Author: Guillaume Chatelet
Date: 2021-11-30T10:52:34Z
New Revision: af059dfef5a766ceb0ac29318dfb7102131d933e

URL: https://github.com/llvm/llvm-project/commit/af059dfef5a766ceb0ac29318dfb7102131d933e
DIFF: https://github.com/llvm/llvm-project/commit/af059dfef5a766ceb0ac29318dfb7102131d933e.diff

LOG: [libc] Add a reasonably optimized version for bcmp

This is based on current memcmp implementation.

Differential Revision: https://reviews.llvm.org/D114432

Added: 
    libc/src/string/memory_utils/bcmp_implementations.h

Modified: 
    libc/src/string/CMakeLists.txt
    libc/src/string/bcmp.cpp
    libc/src/string/memory_utils/CMakeLists.txt
    libc/test/src/string/bcmp_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 2d52b3689161c..9bd1f538cfe92 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -271,7 +271,7 @@ endfunction()
 
 function(add_bcmp bcmp_name)
   add_implementation(bcmp ${bcmp_name}
-    SRCS ${LIBC_BCMP_SRC}
+    SRCS ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp
     HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h
     DEPENDS
       .memory_utils.memory_utils
@@ -284,7 +284,6 @@ function(add_bcmp bcmp_name)
 endfunction()
 
 if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
-  set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp)
   add_bcmp(bcmp_x86_64_opt_sse2   COMPILE_OPTIONS -march=k8             REQUIRE SSE2)
   add_bcmp(bcmp_x86_64_opt_sse4   COMPILE_OPTIONS -march=nehalem        REQUIRE SSE4_2)
   add_bcmp(bcmp_x86_64_opt_avx2   COMPILE_OPTIONS -march=haswell        REQUIRE AVX2)
@@ -292,7 +291,6 @@ if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
   add_bcmp(bcmp_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
   add_bcmp(bcmp)
 else()
-  set(LIBC_BCMP_SRC ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp)
   add_bcmp(bcmp_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
   add_bcmp(bcmp)
 endif()

diff  --git a/libc/src/string/bcmp.cpp b/libc/src/string/bcmp.cpp
index 196f3272eab1a..963a7f5bce17c 100644
--- a/libc/src/string/bcmp.cpp
+++ b/libc/src/string/bcmp.cpp
@@ -8,20 +8,14 @@
 
 #include "src/string/bcmp.h"
 #include "src/__support/common.h"
+#include "src/string/memory_utils/bcmp_implementations.h"
 
 namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(int, bcmp,
                    (const void *lhs, const void *rhs, size_t count)) {
-  const unsigned char *_lhs = reinterpret_cast<const unsigned char *>(lhs);
-  const unsigned char *_rhs = reinterpret_cast<const unsigned char *>(rhs);
-  for (size_t i = 0; i < count; ++i) {
-    if (_lhs[i] != _rhs[i]) {
-      return 1;
-    }
-  }
-  // count is 0 or _lhs and _rhs are the same.
-  return 0;
+  return inline_bcmp(static_cast<const char *>(lhs),
+                     static_cast<const char *>(rhs), count);
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/string/memory_utils/CMakeLists.txt b/libc/src/string/memory_utils/CMakeLists.txt
index f2bc09ec0cf59..51bbff3d27bfa 100644
--- a/libc/src/string/memory_utils/CMakeLists.txt
+++ b/libc/src/string/memory_utils/CMakeLists.txt
@@ -3,6 +3,10 @@ add_header_library(
   HDRS
     utils.h
     elements.h
+    bcmp_implementations.h
+    memcmp_implementations.h
+    memcpy_implementations.h
+    memset_implementations.h
 )
 
 add_header_library(

diff  --git a/libc/src/string/memory_utils/bcmp_implementations.h b/libc/src/string/memory_utils/bcmp_implementations.h
new file mode 100644
index 0000000000000..ec94af28c6a68
--- /dev/null
+++ b/libc/src/string/memory_utils/bcmp_implementations.h
@@ -0,0 +1,61 @@
+//===-- Implementation of bcmp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_BCMP_IMPLEMENTATIONS_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_BCMP_IMPLEMENTATIONS_H
+
+#include "src/__support/architectures.h"
+#include "src/__support/common.h"
+#include "src/string/memory_utils/elements.h"
+
+#include <stddef.h> // size_t
+
+namespace __llvm_libc {
+
+// Fixed-size 
diff erence between 'lhs' and 'rhs'.
+template <typename Element> bool Differs(const char *lhs, const char *rhs) {
+  return !Element::Equals(lhs, rhs);
+}
+// Runtime-size 
diff erence between 'lhs' and 'rhs'.
+template <typename Element>
+bool Differs(const char *lhs, const char *rhs, size_t size) {
+  return !Element::Equals(lhs, rhs, size);
+}
+
+static inline int inline_bcmp(const char *lhs, const char *rhs, size_t count) {
+#if defined(LLVM_LIBC_ARCH_X86)
+  using namespace ::__llvm_libc::x86;
+#elif defined(LLVM_LIBC_ARCH_AARCH64)
+  using namespace ::__llvm_libc::aarch64;
+#else
+  using namespace ::__llvm_libc::scalar;
+#endif
+  if (count == 0)
+    return 0;
+  if (count == 1)
+    return Differs<_1>(lhs, rhs);
+  if (count == 2)
+    return Differs<_2>(lhs, rhs);
+  if (count == 3)
+    return Differs<_3>(lhs, rhs);
+  if (count <= 8)
+    return Differs<HeadTail<_4>>(lhs, rhs, count);
+  if (count <= 16)
+    return Differs<HeadTail<_8>>(lhs, rhs, count);
+  if (count <= 32)
+    return Differs<HeadTail<_16>>(lhs, rhs, count);
+  if (count <= 64)
+    return Differs<HeadTail<_32>>(lhs, rhs, count);
+  if (count <= 128)
+    return Differs<HeadTail<_64>>(lhs, rhs, count);
+  return Differs<Align<_32>::Then<Loop<_32>>>(lhs, rhs, count);
+}
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_BCMP_IMPLEMENTATIONS_H

diff  --git a/libc/test/src/string/bcmp_test.cpp b/libc/test/src/string/bcmp_test.cpp
index 7c2353fcd7fc0..dfcad7aff259a 100644
--- a/libc/test/src/string/bcmp_test.cpp
+++ b/libc/test/src/string/bcmp_test.cpp
@@ -24,13 +24,13 @@ TEST(LlvmLibcBcmpTest, LhsRhsAreTheSame) {
 TEST(LlvmLibcBcmpTest, LhsBeforeRhsLexically) {
   const char *lhs = "ab";
   const char *rhs = "ac";
-  EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, 2), 1);
+  EXPECT_NE(__llvm_libc::bcmp(lhs, rhs, 2), 0);
 }
 
 TEST(LlvmLibcBcmpTest, LhsAfterRhsLexically) {
   const char *lhs = "ac";
   const char *rhs = "ab";
-  EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, 2), 1);
+  EXPECT_NE(__llvm_libc::bcmp(lhs, rhs, 2), 0);
 }
 
 TEST(LlvmLibcBcmpTest, Sweep) {
@@ -52,7 +52,7 @@ TEST(LlvmLibcBcmpTest, Sweep) {
   reset(rhs);
   for (size_t i = 0; i < kMaxSize; ++i) {
     rhs[i] = 'b';
-    EXPECT_EQ(__llvm_libc::bcmp(lhs, rhs, kMaxSize), 1);
+    EXPECT_NE(__llvm_libc::bcmp(lhs, rhs, kMaxSize), 0);
     rhs[i] = 'a';
   }
 }


        


More information about the libc-commits mailing list