[libc-commits] [libc] 3ec60e8 - [libc] Optimize the GPU printf implementation with size hints (#222474)
via libc-commits
libc-commits at lists.llvm.org
Thu Sep 10 05:36:44 PDT 2026
Author: Joseph Huber
Date: 2026-09-10T07:36:39-05:00
New Revision: 3ec60e826f522bbe6b0af7c9392968a9f6c660c5
URL: https://github.com/llvm/llvm-project/commit/3ec60e826f522bbe6b0af7c9392968a9f6c660c5
DIFF: https://github.com/llvm/llvm-project/commit/3ec60e826f522bbe6b0af7c9392968a9f6c660c5.diff
LOG: [libc] Optimize the GPU printf implementation with size hints (#222474)
Summary:
The GPU printf interface is functionally a shim to pass a `va_list` and
format string to the CPU for formatting. The size of the argument list
isn't exposed by the C ABI, but we can use `__builtin_object_size` to
try to look it up. This will bind to the `alloca` holding our arguments
in the ABI and return a positive size if it is known.
We do this opportunistically, as the check is lossy. In cases where it
is known, this saves a stack spill to store the true size. Additionally,
we can use this to detect cases where `printf` is being used as a simple
`puts`.
This saves 10 VGPRs for the `printf("string")` case. It also saves 8
bytes of stack in most all cases.
Added:
Modified:
libc/src/stdio/gpu/vfprintf_utils.h
Removed:
################################################################################
diff --git a/libc/src/stdio/gpu/vfprintf_utils.h b/libc/src/stdio/gpu/vfprintf_utils.h
index 70eb98c838bec..a4d2ec8487b09 100644
--- a/libc/src/stdio/gpu/vfprintf_utils.h
+++ b/libc/src/stdio/gpu/vfprintf_utils.h
@@ -34,6 +34,11 @@ LIBC_INLINE int vfprintf_impl(::FILE *__restrict file,
port.recv([&](rpc::Buffer *buffer, uint32_t) {
args_size = static_cast<size_t>(buffer->data[0]);
});
+ // If the underlying argument buffer is of known size we use it directly. A
+ // value of one uniquely indicates an empty argument list.
+ if (size_t arg_max = __builtin_object_size(vlist, /*max=*/0b00);
+ arg_max == __builtin_object_size(vlist, /*min=*/0b10))
+ args_size = arg_max;
port.send_n(vlist, args_size);
uint32_t ret = 0;
@@ -44,7 +49,7 @@ LIBC_INLINE int vfprintf_impl(::FILE *__restrict file,
str = reinterpret_cast<const char *>(buffer->data[1]);
});
// If any lanes have a string argument it needs to be copied back.
- if (!gpu::ballot(mask, str))
+ if (!gpu::ballot(mask, str && args_size != 1))
break;
uint64_t size = str ? internal::string_length(str) + 1 : 0;
More information about the libc-commits
mailing list