[libc-commits] [libc] [libc] Implement placeholder memory functions on the GPU (PR #101082)

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Mon Jul 29 13:55:16 PDT 2024


https://github.com/jhuber6 created https://github.com/llvm/llvm-project/pull/101082

Summary:
These functions are needed for `libc++` to link successfully. We can't
implement them well currently, so simply provide some stand-in
implementations. `realloc` will currently copy garbage and potentially
fault and `aligned_alloc` will work unless your alignment is more than
4K alignment. However, these should work in practice to get tests
running. I will write a real allocator soon™.


>From 93fa7c08f5057bac9bb93e73d6dfa29b3c3c6312 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Mon, 29 Jul 2024 15:53:17 -0500
Subject: [PATCH] [libc] Implement placeholder memory functions on the GPU
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Summary:
These functions are needed for `libc++` to link successfully. We can't
implement them well currently, so simply provide some stand-in
implementations. `realloc` will currently copy garbage and potentially
fault and `aligned_alloc` will work unless your alignment is more than
4K alignment. However, these should work in practice to get tests
running. I will write a real allocator soon™.
---
 libc/config/gpu/entrypoints.txt       |  3 ++-
 libc/src/stdlib/CMakeLists.txt        | 19 +++++++++++----
 libc/src/stdlib/gpu/CMakeLists.txt    | 33 +++++++++++++++++++++++++++
 libc/src/stdlib/gpu/aligned_alloc.cpp | 29 +++++++++++++++++++++++
 libc/src/stdlib/gpu/calloc.cpp        | 31 +++++++++++++++++++++++++
 libc/src/stdlib/gpu/realloc.cpp       | 32 ++++++++++++++++++++++++++
 6 files changed, 141 insertions(+), 6 deletions(-)
 create mode 100644 libc/src/stdlib/gpu/aligned_alloc.cpp
 create mode 100644 libc/src/stdlib/gpu/calloc.cpp
 create mode 100644 libc/src/stdlib/gpu/realloc.cpp

diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 157f6f8af00a9..04a42c3019495 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -166,8 +166,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.strtoul
     libc.src.stdlib.strtoull
 
-    # Only implemented in the test suite
+    # TODO: Implement these correctly
     libc.src.stdlib.aligned_alloc
+    libc.src.stdlib.calloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
     libc.src.stdlib.realloc
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index d79acb390ff91..0f363eecc6251 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -443,14 +443,23 @@ if(LIBC_TARGET_OS_IS_GPU)
     DEPENDS
       .${LIBC_TARGET_OS}.free
   )
-  add_entrypoint_external(
-    calloc
-  )
-  add_entrypoint_external(
+  add_entrypoint_object(
     realloc
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.realloc
   )
-  add_entrypoint_external(
+  add_entrypoint_object(
+    calloc
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.calloc
+  )
+  add_entrypoint_object(
     aligned_alloc
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.aligned_alloc
   )
 endif()
 
diff --git a/libc/src/stdlib/gpu/CMakeLists.txt b/libc/src/stdlib/gpu/CMakeLists.txt
index f8a11ec3ffb00..073f81515870b 100644
--- a/libc/src/stdlib/gpu/CMakeLists.txt
+++ b/libc/src/stdlib/gpu/CMakeLists.txt
@@ -20,6 +20,39 @@ add_entrypoint_object(
     libc.src.__support.RPC.rpc_client
 )
 
+add_entrypoint_object(
+  realloc
+  SRCS
+    realloc.cpp
+  HDRS
+    ../realloc.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.__support.GPU.allocator
+)
+
+add_entrypoint_object(
+  calloc
+  SRCS
+    calloc.cpp
+  HDRS
+    ../calloc.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.__support.GPU.allocator
+)
+
+add_entrypoint_object(
+  aligned_alloc
+  SRCS
+    aligned_alloc.cpp
+  HDRS
+    ../aligned_alloc.h
+  DEPENDS
+    libc.include.stdlib
+    libc.src.__support.GPU.allocator
+)
+
 add_entrypoint_object(
   abort
   SRCS
diff --git a/libc/src/stdlib/gpu/aligned_alloc.cpp b/libc/src/stdlib/gpu/aligned_alloc.cpp
new file mode 100644
index 0000000000000..cd2c7e55128fe
--- /dev/null
+++ b/libc/src/stdlib/gpu/aligned_alloc.cpp
@@ -0,0 +1,29 @@
+//===-- GPU Implementation of aligned_alloc -------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/aligned_alloc.h"
+
+#include "src/__support/GPU/allocator.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void *, aligned_alloc, (size_t alignment, size_t size)) {
+  if ((alignment & -alignment) != alignment)
+    return nullptr;
+
+  void *ptr = gpu::allocate(size);
+  if ((reinterpret_cast<uintptr_t>(ptr) & (alignment - 1)) != 0) {
+    gpu::deallocate(ptr);
+    return nullptr;
+  }
+  return ptr;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/gpu/calloc.cpp b/libc/src/stdlib/gpu/calloc.cpp
new file mode 100644
index 0000000000000..9150affc7c200
--- /dev/null
+++ b/libc/src/stdlib/gpu/calloc.cpp
@@ -0,0 +1,31 @@
+//===-- GPU Implementation of calloc --------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/calloc.h"
+
+#include "src/__support/GPU/allocator.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/memory_utils/inline_memset.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void *, calloc, (size_t num, size_t size)) {
+  size_t bytes = num * size;
+  if (bytes == 0)
+    return nullptr;
+
+  void *ptr = gpu::allocate(bytes);
+  if (!ptr)
+    return nullptr;
+
+  inline_memset(ptr, 0, bytes);
+  return ptr;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/gpu/realloc.cpp b/libc/src/stdlib/gpu/realloc.cpp
new file mode 100644
index 0000000000000..4fd4d6b278179
--- /dev/null
+++ b/libc/src/stdlib/gpu/realloc.cpp
@@ -0,0 +1,32 @@
+//===-- GPU Implementation of realloc -------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/realloc.h"
+
+#include "src/__support/GPU/allocator.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/string/memory_utils/inline_memcpy.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void *, realloc, (void *ptr, size_t size)) {
+  if (ptr == nullptr)
+    return gpu::allocate(size);
+
+  void *newmem = gpu::allocate(size);
+  if (newmem == nullptr)
+    return nullptr;
+
+  // This will copy garbage if it goes beyond the old allocation size.
+  inline_memcpy(newmem, ptr, size);
+  gpu::deallocate(ptr);
+  return newmem;
+}
+
+} // namespace LIBC_NAMESPACE_DECL



More information about the libc-commits mailing list