Skip to content

[libc] Implement placeholder memory functions on the GPU #101082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 30, 2024

Conversation

jhuber6
Copy link
Contributor

@jhuber6 jhuber6 commented Jul 29, 2024

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™.

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™.
@llvmbot
Copy link
Member

llvmbot commented Jul 29, 2024

@llvm/pr-subscribers-libc

Author: Joseph Huber (jhuber6)

Changes

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™.


Full diff: https://github.com/llvm/llvm-project/pull/101082.diff

6 Files Affected:

  • (modified) libc/config/gpu/entrypoints.txt (+2-1)
  • (modified) libc/src/stdlib/CMakeLists.txt (+14-5)
  • (modified) libc/src/stdlib/gpu/CMakeLists.txt (+33)
  • (added) libc/src/stdlib/gpu/aligned_alloc.cpp (+29)
  • (added) libc/src/stdlib/gpu/calloc.cpp (+31)
  • (added) libc/src/stdlib/gpu/realloc.cpp (+32)
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

@jhuber6 jhuber6 merged commit bf42a78 into llvm:main Jul 30, 2024
8 checks passed
@jhuber6 jhuber6 deleted the aligned_alloc branch July 30, 2024 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants