[libc-commits] [libc] [libc] Add `scanf` support to the GPU build (PR #104812)

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Mon Aug 19 09:26:14 PDT 2024


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

Summary:
The `scanf` function has a "system file" configuration, which is pretty
much what the GPU implementation does at this point. So we should be
able to use it in much the same way.


>From ff7dcb8e8431d4a35ea21a91436e27a47832521c Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Mon, 19 Aug 2024 11:22:36 -0500
Subject: [PATCH] [libc] Add `scanf` support to the GPU build

Summary:
The `scanf` function has a "system file" configuration, which is pretty
much what the GPU implementation does at this point. So we should be
able to use it in much the same way.
---
 libc/config/gpu/entrypoints.txt              |  2 +
 libc/docs/gpu/support.rst                    |  2 +
 libc/src/stdio/CMakeLists.txt                |  2 +-
 libc/src/stdio/scanf_core/CMakeLists.txt     | 46 ++++++++++++--------
 libc/src/stdio/scanf_core/vfscanf_internal.h | 26 ++++++++++-
 5 files changed, 59 insertions(+), 19 deletions(-)

diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index bbae3298fae615..d7f35bc1edf5a0 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -192,6 +192,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.vsprintf
     libc.src.stdio.asprintf
     libc.src.stdio.vasprintf
+    libc.src.stdio.scanf
+    libc.src.stdio.fscanf
     libc.src.stdio.sscanf
     libc.src.stdio.vsscanf
     libc.src.stdio.feof
diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index 5ef298a2ba58f2..c8b1052ce16895 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -239,6 +239,8 @@ snprintf       |check|
 vsprintf       |check|
 vsnprintf      |check|
 sscanf         |check|
+scanf          |check|
+fscanf         |check|
 putchar        |check|    |check|
 fclose         |check|    |check|
 fopen          |check|    |check|
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index bc5ef5fe0e9b48..372b8fc8192455 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -101,7 +101,7 @@ list(APPEND scanf_deps
       libc.hdr.types.FILE
 )
 
-if(LLVM_LIBC_FULL_BUILD)
+if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU)
   list(APPEND scanf_deps
       libc.src.__support.File.file
       libc.src.__support.File.platform_file
diff --git a/libc/src/stdio/scanf_core/CMakeLists.txt b/libc/src/stdio/scanf_core/CMakeLists.txt
index e2b49e0c915284..5c00ae0c9973c2 100644
--- a/libc/src/stdio/scanf_core/CMakeLists.txt
+++ b/libc/src/stdio/scanf_core/CMakeLists.txt
@@ -92,21 +92,33 @@ add_object_library(
     libc.src.__support.str_to_float
 )
 
-if(NOT (TARGET libc.src.__support.File.file) AND LLVM_LIBC_FULL_BUILD)
-  # Not all platforms have a file implementation. If file is unvailable, and a
-  # full build is requested, then we must skip all file based printf sections.
-  return()
+if(LIBC_TARGET_OS_IS_GPU)
+  add_header_library(
+    vfscanf_internal
+    HDRS
+      vfscanf_internal.h
+    DEPENDS
+      .reader
+      .scanf_main
+      libc.include.stdio
+      libc.src.__support.arg_list
+      libc.src.stdio.getc
+      libc.src.stdio.ungetc
+      libc.src.stdio.ferror
+    COMPILE_OPTIONS
+      -DLIBC_COPT_STDIO_USE_SYSTEM_FILE
+  )
+elseif(TARGET libc.src.__support.File.file OR (NOT LLVM_LIBC_FULL_BUILD))
+  add_header_library(
+    vfscanf_internal
+    HDRS
+      vfscanf_internal.h
+    DEPENDS
+      .reader
+      .scanf_main
+      libc.include.stdio
+      libc.src.__support.File.file
+      libc.src.__support.arg_list
+    ${use_system_file}
+  )
 endif()
-
-add_header_library(
-  vfscanf_internal
-  HDRS
-    vfscanf_internal.h
-  DEPENDS
-    .reader
-    .scanf_main
-    libc.include.stdio
-    libc.src.__support.File.file
-    libc.src.__support.arg_list
-  ${use_system_file}
-)
diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.h b/libc/src/stdio/scanf_core/vfscanf_internal.h
index 2b0072a6ae35f3..68848375eee229 100644
--- a/libc/src/stdio/scanf_core/vfscanf_internal.h
+++ b/libc/src/stdio/scanf_core/vfscanf_internal.h
@@ -12,9 +12,16 @@
 #include "src/__support/File/file.h"
 #include "src/__support/arg_list.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/architectures.h"
 #include "src/stdio/scanf_core/reader.h"
 #include "src/stdio/scanf_core/scanf_main.h"
 
+#if defined(LIBC_TARGET_ARCH_IS_GPU)
+#include "src/stdio/ferror.h"
+#include "src/stdio/getc.h"
+#include "src/stdio/ungetc.h"
+#endif
+
 #include "hdr/types/FILE.h"
 #include <stddef.h>
 
@@ -22,7 +29,24 @@ namespace LIBC_NAMESPACE_DECL {
 
 namespace internal {
 
-#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
+#if defined(LIBC_TARGET_ARCH_IS_GPU)
+// Since ungetc_unlocked isn't always available, we don't acquire the lock for
+// system files.
+LIBC_INLINE void flockfile(::FILE *) { return; }
+
+LIBC_INLINE void funlockfile(::FILE *) { return; }
+
+LIBC_INLINE int getc(void *f) {
+  return LIBC_NAMESPACE::getc(reinterpret_cast<::FILE *>(f));
+}
+
+LIBC_INLINE void ungetc(int c, void *f) {
+  LIBC_NAMESPACE::ungetc(c, reinterpret_cast<::FILE *>(f));
+}
+
+LIBC_INLINE int ferror_unlocked(::FILE *f) { return LIBC_NAMESPACE::ferror(f); }
+
+#elif !defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
 
 LIBC_INLINE void flockfile(FILE *f) {
   reinterpret_cast<LIBC_NAMESPACE::File *>(f)->lock();



More information about the libc-commits mailing list