Reland: "[libc] Templatize str{,n}cmp"
authorAlex Brachet <abrachet@google.com>
Tue, 10 Jan 2023 15:37:58 +0000 (15:37 +0000)
committerAlex Brachet <abrachet@google.com>
Tue, 10 Jan 2023 15:39:54 +0000 (15:39 +0000)
This will be used to implement the case insensitive str{,n}casecmp

This was initially reverted because it broke tests on arm platforms.
Unfortunately, it didn't break on my arm machine, but I suspect the
problem was the old comparator returned char and not int.

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

libc/src/string/CMakeLists.txt
libc/src/string/memory_utils/CMakeLists.txt
libc/src/string/memory_utils/strcmp_implementations.h [new file with mode: 0644]
libc/src/string/strcmp.cpp
libc/src/string/strncmp.cpp
utils/bazel/llvm-project-overlay/libc/BUILD.bazel

index 0faa1db..cdce0bc 100644 (file)
@@ -111,6 +111,8 @@ add_entrypoint_object(
     strcmp.cpp
   HDRS
     strcmp.h
+  DEPENDS
+    .memory_utils.strcmp_implementation
 )
 
 add_entrypoint_object(
@@ -226,6 +228,8 @@ add_entrypoint_object(
     strncmp.cpp
   HDRS
     strncmp.h
+  DEPENDS
+    .memory_utils.strcmp_implementation
 )
 
 add_entrypoint_object(
index 3bf81e9..10e14e1 100644 (file)
@@ -60,3 +60,9 @@ add_header_library(
   DEPS
     .memset_implementation
 )
+
+add_header_library(
+  strcmp_implementation
+  HDRS
+    strcmp_implementations.h
+)
diff --git a/libc/src/string/memory_utils/strcmp_implementations.h b/libc/src/string/memory_utils/strcmp_implementations.h
new file mode 100644 (file)
index 0000000..3a7caee
--- /dev/null
@@ -0,0 +1,44 @@
+//===-- str{,case}cmp implementation ----------------------------*- C++ -*-===//
+//
+// 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_STRCMP_IMPLEMENTATIONS_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H
+
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+template <typename Comp>
+constexpr static int strcmp_implementation(const char *left, const char *right,
+                                           Comp &&comp) {
+  // TODO: Look at benefits for comparing words at a time.
+  for (; *left && !comp(*left, *right); ++left, ++right)
+    ;
+  return comp(*reinterpret_cast<const unsigned char *>(left),
+              *reinterpret_cast<const unsigned char *>(right));
+}
+
+template <typename Comp>
+constexpr static int strncmp_implementation(const char *left, const char *right,
+                                            size_t n, Comp &&comp) {
+  if (n == 0)
+    return 0;
+
+  // TODO: Look at benefits for comparing words at a time.
+  for (; n > 1; --n, ++left, ++right) {
+    char lc = *left;
+    if (!comp(lc, '\0') || comp(lc, *right))
+      break;
+  }
+  return comp(*reinterpret_cast<const unsigned char *>(left),
+              *reinterpret_cast<const unsigned char *>(right));
+}
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H
index 8468b3c..72a490c 100644 (file)
@@ -9,15 +9,13 @@
 #include "src/string/strcmp.h"
 
 #include "src/__support/common.h"
+#include "src/string/memory_utils/strcmp_implementations.h"
 
 namespace __llvm_libc {
 
-// TODO: Look at benefits for comparing words at a time.
 LLVM_LIBC_FUNCTION(int, strcmp, (const char *left, const char *right)) {
-  for (; *left && *left == *right; ++left, ++right)
-    ;
-  return *reinterpret_cast<const unsigned char *>(left) -
-         *reinterpret_cast<const unsigned char *>(right);
+  auto comp = [](char l, char r) -> int { return l - r; };
+  return strcmp_implementation(left, right, comp);
 }
 
 } // namespace __llvm_libc
index 94960e5..b850663 100644 (file)
@@ -9,24 +9,16 @@
 #include "src/string/strncmp.h"
 
 #include "src/__support/common.h"
+#include "src/string/memory_utils/strcmp_implementations.h"
+
 #include <stddef.h>
 
 namespace __llvm_libc {
 
-// TODO: Look at benefits for comparing words at a time.
 LLVM_LIBC_FUNCTION(int, strncmp,
                    (const char *left, const char *right, size_t n)) {
-
-  if (n == 0)
-    return 0;
-
-  for (; n > 1; --n, ++left, ++right) {
-    char lc = *left;
-    if (lc == '\0' || lc != *right)
-      break;
-  }
-  return *reinterpret_cast<const unsigned char *>(left) -
-         *reinterpret_cast<const unsigned char *>(right);
+  auto comp = [](char l, char r) -> int { return l - r; };
+  return strncmp_implementation(left, right, n, comp);
 }
 
 } // namespace __llvm_libc
index d75e578..534ecfd 100644 (file)
@@ -1089,6 +1089,7 @@ libc_support_library(
         "src/string/memory_utils/memcpy_implementations.h",
         "src/string/memory_utils/memmove_implementations.h",
         "src/string/memory_utils/memset_implementations.h",
+        "src/string/memory_utils/strcmp_implementations.h",
     ],
     deps = [
         ":__support_common",
@@ -1270,6 +1271,7 @@ libc_function(
     hdrs = ["src/string/strcmp.h"],
     deps = [
         ":__support_common",
+        ":string_memory_utils",
         ":string_utils",
     ],
 )