[libc-commits] [libc] c92d1aa - [libc] Decouple string functions.

via libc-commits libc-commits at lists.llvm.org
Mon Sep 14 09:23:20 PDT 2020


Author: cgyurgyik
Date: 2020-09-14T12:22:05-04:00
New Revision: c92d1aa44b132597d57523a90342b3e620dbdb1e

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

LOG: [libc] Decouple string functions.

This revision removes dependencies that exist between different string functions. This allows for the libc user to use a specific function X of this library without also depending on Y and Z.

Reviewed By: sivachandra

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

Added: 
    

Modified: 
    libc/src/string/CMakeLists.txt
    libc/src/string/memchr.cpp
    libc/src/string/strcat.cpp
    libc/src/string/strcpy.cpp
    libc/src/string/string_utils.h
    libc/src/string/strlen.cpp
    libc/src/string/strnlen.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index a347f2bf5267..8a2adbe08e0b 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -16,8 +16,7 @@ add_entrypoint_object(
     strcat.h
   DEPENDS
     .strcpy
-    .strlen
-    libc.include.string
+    .string_utils
 )
 
 add_entrypoint_object(
@@ -28,8 +27,7 @@ add_entrypoint_object(
     strcpy.h
   DEPENDS
     .memcpy
-    .strlen
-    libc.include.string
+    .string_utils
 )
 
 add_entrypoint_object(
@@ -56,6 +54,8 @@ add_entrypoint_object(
     memchr.cpp
   HDRS
     memchr.h
+  DEPENDS
+    .string_utils
 )
 
 add_entrypoint_object(
@@ -81,7 +81,7 @@ add_entrypoint_object(
   HDRS
     strnlen.h
   DEPENDS
-    .memchr
+    .string_utils
 )
 
 add_entrypoint_object(

diff  --git a/libc/src/string/memchr.cpp b/libc/src/string/memchr.cpp
index 303f78185f49..c95e2724f1a1 100644
--- a/libc/src/string/memchr.cpp
+++ b/libc/src/string/memchr.cpp
@@ -7,6 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/string/memchr.h"
+#include "src/string/string_utils.h"
+
 #include "src/__support/common.h"
 #include <stddef.h>
 
@@ -14,11 +16,8 @@ namespace __llvm_libc {
 
 // TODO: Look at performance benefits of comparing words.
 void *LLVM_LIBC_ENTRYPOINT(memchr)(const void *src, int c, size_t n) {
-  const unsigned char *str = reinterpret_cast<const unsigned char *>(src);
-  const unsigned char ch = c;
-  for (; n && *str != ch; --n, ++str)
-    ;
-  return n ? const_cast<unsigned char *>(str) : nullptr;
+  return internal::find_first_character(
+      reinterpret_cast<const unsigned char *>(src), c, n);
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/string/strcat.cpp b/libc/src/string/strcat.cpp
index c02de2d21b93..f5e8616f022a 100644
--- a/libc/src/string/strcat.cpp
+++ b/libc/src/string/strcat.cpp
@@ -8,7 +8,7 @@
 
 #include "src/string/strcat.h"
 #include "src/string/strcpy.h"
-#include "src/string/strlen.h"
+#include "src/string/string_utils.h"
 
 #include "src/__support/common.h"
 
@@ -16,7 +16,7 @@ namespace __llvm_libc {
 
 char *LLVM_LIBC_ENTRYPOINT(strcat)(char *__restrict dest,
                                    const char *__restrict src) {
-  __llvm_libc::strcpy(dest + __llvm_libc::strlen(dest), src);
+  __llvm_libc::strcpy(dest + internal::string_length(dest), src);
   return dest;
 }
 

diff  --git a/libc/src/string/strcpy.cpp b/libc/src/string/strcpy.cpp
index 6927d9d3ec89..69a40c9f5392 100644
--- a/libc/src/string/strcpy.cpp
+++ b/libc/src/string/strcpy.cpp
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/string/strcpy.h"
-#include "src/string/strlen.h"
 #include "src/string/memcpy.h"
+#include "src/string/string_utils.h"
 
 #include "src/__support/common.h"
 
@@ -17,7 +17,7 @@ namespace __llvm_libc {
 char *LLVM_LIBC_ENTRYPOINT(strcpy)(char *__restrict dest,
                                    const char *__restrict src) {
   return reinterpret_cast<char *>(
-      __llvm_libc::memcpy(dest, src, __llvm_libc::strlen(src) + 1));
+      __llvm_libc::memcpy(dest, src, internal::string_length(src) + 1));
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h
index 234246c10b06..dfb2c8af4527 100644
--- a/libc/src/string/string_utils.h
+++ b/libc/src/string/string_utils.h
@@ -15,6 +15,24 @@
 namespace __llvm_libc {
 namespace internal {
 
+// Returns the length of a string, denoted by the first occurrence
+// of a null terminator.
+static inline size_t string_length(const char *src) {
+  size_t length;
+  for (length = 0; *src; ++src, ++length)
+    ;
+  return length;
+}
+
+// Returns the first occurrence of 'ch' within the first 'n' characters of
+// 'src'. If 'ch' is not found, returns nullptr.
+static inline void *find_first_character(const unsigned char *src,
+                                         unsigned char ch, size_t n) {
+  for (; n && *src != ch; --n, ++src)
+    ;
+  return n ? const_cast<unsigned char *>(src) : nullptr;
+}
+
 // Returns the maximum length span that contains only characters not found in
 // 'segment'. If no characters are found, returns the length of 'src'.
 static inline size_t complementary_span(const char *src, const char *segment) {

diff  --git a/libc/src/string/strlen.cpp b/libc/src/string/strlen.cpp
index 0b7597ec52b6..81e1f17e7c11 100644
--- a/libc/src/string/strlen.cpp
+++ b/libc/src/string/strlen.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/string/strlen.h"
+#include "src/string/string_utils.h"
 
 #include "src/__support/common.h"
 
@@ -15,10 +16,7 @@ namespace __llvm_libc {
 // TODO: investigate the performance of this function.
 // There might be potential for compiler optimization.
 size_t LLVM_LIBC_ENTRYPOINT(strlen)(const char *src) {
-  const char *end = src;
-  while (*end != '\0')
-    ++end;
-  return end - src;
+  return internal::string_length(src);
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/string/strnlen.cpp b/libc/src/string/strnlen.cpp
index 17dd6e171504..ea8fa9c26d54 100644
--- a/libc/src/string/strnlen.cpp
+++ b/libc/src/string/strnlen.cpp
@@ -7,17 +7,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/string/strnlen.h"
+#include "src/string/string_utils.h"
 
 #include "src/__support/common.h"
-#include "src/string/memchr.h"
 #include <stddef.h>
 
 namespace __llvm_libc {
 
 size_t LLVM_LIBC_ENTRYPOINT(strnlen)(const char *src, size_t n) {
-  const char *temp =
-      reinterpret_cast<char *>(__llvm_libc::memchr(src, '\0', n));
-  return temp ? temp - src : n;
+  const void *temp = internal::find_first_character(
+      reinterpret_cast<const unsigned char *>(src), '\0', n);
+  return temp ? reinterpret_cast<const char *>(temp) - src : n;
 }
 
 } // namespace __llvm_libc


        


More information about the libc-commits mailing list