Summary:
This patch implements the `fgets`, `getc`, `fgetc`, and `getchar`
functions on the GPU. Their implementations are straightforward enough.
One thing worth noting is that the implementation of `fgets` will be
extremely slow due to the high latency to read a single char. A faster
solution would be to make a new RPC call to call `fgets` (due to the
special rule that newline or null breaks the stream). But this is left
out because performance isn't the primary concern here.
This patch changes the size of time_t to be an int64_t. This still
follows the POSIX standard which only requires time_t to be an integer.
Making time_t a 64-bit integer also fixes two cases in 32 bits platforms
that use SYS_clock_nanosleep_time64 and SYS_clock_gettime64, as the name
of these calls implies, they require a 64-bit time_t. For instance, in rv32,
the 32-bit version of these syscalls is not available.
We also follow glibc here, where time_t is still a 32-bit integer in
arm32.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D159125
Summary:
This patch improves the implementation of the standard `rand()` function
by implementing it in terms of the xorshift64star pRNG as described in
https://en.wikipedia.org/wiki/Xorshift#xorshift*. This is a good,
general purpose random number generator that is sufficient for most
applications that do not require an extremely long period. This patch
also correctly initializes the seed to be `1` as described by the
standard. We also increase the `RAND_MAX` value to be `INT_MAX` as the
standard only specifies that it can be larger than 32768.
libc uses SYS_prlimit64 (which takes a struct rlimit64) to implement
setrlimt and getrlimit (which take a struct rlimit). In 64-bit bits
systems this is not an issue since the members of struct rlimit64 and
struct rlimit are 64 bits long, however, in 32-bit systems the members
of struct rlimit are only 32 bits long, causing wrong values being
passed to SYS_prlimit64.
This patch changes rlim_t to be __UINT64_TYPE__ (which also changes
rlimit as a side-effect), fixing the problem of mismatching types in
the syscall.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D159104
This function implements the `abort` function on the GPU. The
implementation here closely mirros the `exit` call where we first
synchornize with the RPC server to make sure it's listening and then we
exit on the GPU.
I was unsure if this should be a simple `__builtin_assert` on the GPU. I
elected to go with an RPC approach to make this a more "true" `abort`
call. That is, it should invoke some signal handlers and exit with the
proper code according to the implemented C library on the server.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D159210
Summary:
We should check for the GPU architectures first, since `__linux__` can
be set potentially during these compilations. Also the test needs to be
a hermetic test.
This patch implements the `clock()` function on the GPU. This function
is supposed to return a timestamp that can be converted into seconds
using the `CLOCKS_PER_SEC` macro. The GPU has a fixed frequency timer
that can be used for this purpose. However, there are some
considerations.
First is that AMDGPU does not have a statically known fixed frequency. I
know internally that the gfx10xx and gfx11xx series use a 100 MHz clock
which will probably remain for the future. Gfx9xx typically uses a 25
MHz clock except for the Vega 10 GPU. The only way to know for sure is
to look it up from the runtime. For this purpose, I elected to default
it to some known values and assign these to an exteranlly visible symbol
that can be initialized if needed. If we do not have a good guess we
just return zero.
Second is that the `CLOCKS_PER_SEC` macro only gives about a microsecond
of resolution. POSIX demands that it's 1,000,000 so it's best that we
keep with this tradition as almost all targets seem to respect this. The
reason this is important is because on the GPU we will almost assuredly
be copying the host's macro value (see the wrapper header) so we should
go with the POSIX version that's most likely to be set. (We could
probably make a warning if the included header doesn't match the
expected value).
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D159118
Currently all of this logic expects to include and link with the headers
in the `linux/` directory. This patch adds a wrapper macro to optionally
add the appropriate dependency if it exists. This is preliminary to
adding some GPU specific versions of these files.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D159021
limits.h currently interferes with Clang's limits.h. include_next
emits a warning because it is a GNU extension. Will re add this once
we figure out a good solution.
This reverts commits 13bbca8d69,
002cba0329, and
0fb3066873.
The LLVM-libc build itself will override include paths and prefer it's
own limits.h over the compiler's limits.h. Because we rely on the
compiler limits.h for numerical limits in LLVM-libc it needs to be
include_next:ed if not already included. The other method to work
around this is to define all numeric macros in place.
Signed-off-by: Alfred Persson Forsberg <cat@catcream.org>
Reviewed By: thesamesam
Differential Revision: https://reviews.llvm.org/D158040
This header contains implementation specific constants.
The compiler already provides its own limits.h with numerical limits
conforming to freestanding ISO C. But it is missing extensions like
POSIX, and does for example not include <linux/limits.h> which is
expected on a Linux system, therefore, an LLVM libc implementation of
limits.h is needed for hosted (__STDC_HOSTED__) environments.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D156961
The v variants of the printf functions take their variadic arguments as
a va_list instead of as individual arguments. They are otherwise
identical to the corresponding printf variants. This patch adds them
(vprintf, vfprintf, vsprintf, and vsnprintf) as well as tests.
Reviewed By: phosek
Differential Revision: https://reviews.llvm.org/D157138
This patch adds a bunch of ifdefs to handle the 32 bit versions of
some syscalls, which often only append a 64 to the name of the syscall
(with exception of SYS_lseek -> SYS_llseek and SYS_futex ->
SYS_futex_time64)
This patch also tries to handle cases where wait4 is not available
(as in riscv32): to implement wait, wait4 and waitpid when wait4 is
not available, we check for alternative wait calls and ultimately rely
on waitid to implement them all.
In riscv32, only waitid is available, so we need it to support this
platform.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D148371
This patch adds support for `fread` on the GPU via the RPC mechanism.
Here we simply pass the size of the read to the server and then copy it
back to the client via the RPC channel. This should allow us to do the
basic operations on files now. This will obviously be slow for large
sizes due ot the number of RPC calls involved, this could be optimized
further by having a special RPC call that can initiate a memcpy between
the two pointers.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D155121
This patch does the noisy work of removing the test opcodes from the
exported interface to an interface that is only visible in `libc`. The
benefit of this is that we both test the exported RPC registration more
directly, and we do not need to give this interface to users.
I have decided to export any opcode that is not a "core" libc feature as
having its MSB set in the opcode. We can think of these as non-libc
"extensions".
Reviewed By: JonChesterfield
Differential Revision: https://reviews.llvm.org/D154848
This patch adds the `rpc_host_call` function as a GPU extension. This is
exported from the `libc` project to use the RPC interface to call a
function pointer via RPC any copying the arguments by-value. The
interface can only support a single void pointer argument much like
pthreads. The function call here is the bare-bones version of what's
required for OpenMP reverse offloading. Full support will require
interfacing with the mapping table, nowait support, etc.
I decided to test this interface in `libomptarget` as that will be the
primary consumer and it would be more difficult to make a test in `libc`
due to the testing infrastructure not really having a concept of the
"host" as it runs directly on the GPU as if it were a CPU target.
Reviewed By: jplehr
Differential Revision: https://reviews.llvm.org/D155003
This is an alternate approach to the patches proposed in D153897 and
D153794. Rather than exporting a single header that can be included on
the GPU in all circumstances, this patch chooses to instead generate a
separate set of headers that only provides the declarations. This can
then be used by external tooling to set up what's on the GPU. This
leaves room for header hacks for offloading languages without needing to
worry about the `libc` implementation.
Currently this generates a set of headers that only contain the
declarations. These will then be installed to a new clang resource
directory called `llvm_libc_wrappers/` which will house the shim code.
We can then automaticlaly include this from `clang` when offloading to
wrap around the headers while specifying what's on the GPU.
Reviewed By: jdoerfert, JonChesterfield
Differential Revision: https://reviews.llvm.org/D154036
This reverts commit a4a26374aa.
This was causing some problems with the CPU build and CUDA buildbot.
Revert until I can figure out what those issues are and fix them. I
believe it is just some CMake.
This is an alternate approach to the patches proposed in D153897 and
D153794. Rather than exporting a single header that can be included on
the GPU in all circumstances, this patch chooses to instead generate a
separate set of headers that only provides the declarations. This can
then be used by external tooling to set up what's on the GPU. This
leaves room for header hacks for offloading languages without needing to
worry about the `libc` implementation.
Currently this generates a set of headers that only contain the
declarations. These will then be installed to a new clang resource
directory called `llvm_libc_wrappers/` which will house the shim code.
We can then automaticlaly include this from `clang` when offloading to
wrap around the headers while specifying what's on the GPU.
Reviewed By: jdoerfert, JonChesterfield
Differential Revision: https://reviews.llvm.org/D154036
This patch adds the necessary support for the fopen and fclose functions
to work on the GPU via RPC. I added a new test that enables testing this
with the minimal features we have on the GPU. I will update it once we
have `fread` and `fwrite` to actually check the outputted strings. For
now I just relied on checking manually via the outpuot temp file.
Reviewed By: JonChesterfield, sivachandra
Differential Revision: https://reviews.llvm.org/D154519
When LLVM_ENABLE_PER_TARGET_RUNTIME_DIR is enabled, place headers
in `include/<target>` directory, otherwise use `include/`.
Differential Revision: https://reviews.llvm.org/D152592
The GPU port of the LLVM C library needs to export a few extensions to
the interface such that users can interface with it. This patch adds the
necessary logic to define a GPU extension. Currently, this only exports
a `rpc_reset_client` function. This allows us to use the server in
D147054 to set up the RPC interface outside of `libc`.
Depends on https://reviews.llvm.org/D147054
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D152283
Fixing an issue with LLVM libc's fenv.h defined rounding mode macros
differently from system libc, making get_round() return different values from
fegetround(). Also letting math tests to skip rounding modes that cannot be
set. This should allow math tests to be run on platforms in which fenv.h is not
implemented yet.
This allows us to re-enable hermatic floating point tests in
https://reviews.llvm.org/D151123 and reverting https://reviews.llvm.org/D152742.
Reviewed By: jhuber6
Differential Revision: https://reviews.llvm.org/D152873
This patch adds the reentrent qsort entrypoint, qsort_r. This is done by
extending the qsort functionality and moving it to a shared utility
header. For this reason the qsort_r tests focus mostly on the places
where it differs from qsort, since they share the same sorting code.
Reviewed By: sivachandra, lntue
Differential Revision: https://reviews.llvm.org/D152467
Along the way, couple of additional things have been done:
1. Move `ErrnoSetterMatcher.h` to `test/UnitTest` as all other matchers live
there now.
2. `ErrnoSetterMatcher` ignores matching `errno` on GPUs.
Reviewed By: jhuber6
Differential Revision: https://reviews.llvm.org/D151129
This patch updates the struct dirent to be on par with glibc (by adding
a missing d_type member) and update the readdir call to use SYS_getdents64
instead of SYS_getdents.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D147738
This patch adds the function "socket" from the header "sys/socket". It's
a simple syscall wrapper, and I plan on adding the related functions in
a followup patch.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D149622
This patch enables us to use the existing `libc` support for string
conversion functions on the GPU. This required setting the `fenv_t` and
long double configuration. As far as I am aware, long doubles are
converted to doubles on the GPU and the floating point environment is
just an `uint32_t`.
This code is still untested as we are still working out how to run the
unit tests on the GPU.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D149306
The 'errno' value is most likely not useful on the GPU and it prevents
us from providing certain functions on the GPU that depend on it, like
`atoi`. This patch makes the necessary changes to support `errno` by
simple replacing it with a consumer class.
Supporting `errno` on the GPU is possible in some aspects. The first
approach would be to use a buffer of shared memory that has enough space
for all threads. Another option would be to change code generation to
support `thread_local` using `address_space(5)` memory allocated at
kernel launch. The former could look like the following, which could be
implemented in a later patch:
```
template <typename T>
using SharedBuffer = T[gpu::MAX_THREADS] [[clang::address_space(3)]];
template <typename T> struct ErrnoSetter {
constexpr ErrnoSetter(SharedBuffer<T> &storage) : storage(storage) {}
SharedBuffer<T> &storage;
void operator=(const T &val) { storage[gpu::get_thread_id()] = val; }
};
static SharedBuffer<int> thread_local_buffer [[clang::loader_uninitialized]];
ErrnoSetter<int> __llvmlibc_internal_errno(thread_local_buffer);
```
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D149107
The stdio test failures were due to headers potentially not being built
in the correct order. This should set up the dependencies correctly.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D146551
The GPU support for the `libc` generates all its own headers. Since
these headers use the same names as the system headers we need to make
sure that they are separate. Currently, we either use the system headers
on the GPU or the GPU headers on the system. This patch makes them
explicitly separate. A follow-up patch will then make `clang` look in
this folder by default.
Reviewed By: sivachandra, lntue
Differential Revision: https://reviews.llvm.org/D146970
This patch implements setjmp and longjmp in riscv using inline asm. The
following changes were required:
* Omit frame pointer: otherwise gcc won't allow us to use s0
* Use __attribute__((naked)): otherwise both gcc and clang will generate
function prologue and epilogue in both functions. This doesn't happen
in x86_64, so we guard it to only riscv
Furthermore, using __attribute__((naked)) causes two problems: we
can't use `return 0` (both gcc and clang) and the function arguments in
the function body (clang only), so we had to use a0 and a1 directly.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D145584
This patch adds the wchar header, as well as the functions to convert to
and from wide chars. The header also sets up the definitions for wint
and wchar.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D145995
To improve code generation for C++ code that directly includes our
headers, the external function definitions will now be marked noexcept.
This may not be necessary for the internal definitions since we build
with the -fno-exceptions flag.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D141095
We do not list macro definitions in api.td files anymore. Not all macros
definitions have been moved out. This change moves the definition of the
NULL macro out.
Reviewed By: lntue, jhuber6
Differential Revision: https://reviews.llvm.org/D140376