From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Bertalan <dani@danielbertalan.dev>
Date: Thu, 14 Apr 2022 09:54:22 +0200
Subject: [PATCH] [llvm] Add support for building LLVM on Minerva

Adds Minerva `#ifdef`s for platform-specific code.

We stub out wait4, as Minerva doesn't support querying a child
process's resource usage information.

POSIX shm is not supported by Minerva yet, so disable it in Orc.

Minerva gives each thread a default of 1MiB of stack. Increase the
default stack size for llvm applications when running on Minerva.

Co-Authored-By: sin-ack <sin-ack@users.noreply.github.com>
Co-Authored-By: Tim Schumacher <timschumi@gmx.de>
---
 llvm/cmake/modules/HandleLLVMOptions.cmake               | 3 +++
 llvm/include/llvm/ADT/bit.h                              | 2 +-
 llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp            | 3 ++-
 .../TargetProcess/ExecutorSharedMemoryMapperService.cpp  | 3 ++-
 llvm/lib/Support/Unix/Path.inc                           | 5 ++++-
 llvm/lib/Support/Unix/Program.inc                        | 9 ++++++++-
 6 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 5db06ccdadbebffb3d3eafe0e2b59594438147fe..e82cda307ddfd053fa1434c955b3a37e54f864c5 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -550,6 +550,9 @@ elseif(MINGW OR CYGWIN)
   if (NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
     append("-Wa,-mbig-obj" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
   endif()
+elseif(MINERVA)
+  # Minerva sets a very low default stack size value, so increase it to 4MB manually.
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,stack-size=4194304")
 endif()
 
 option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h
index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..ad4ad534f40cc60568ea9e4c953df8d4c64fe535 100644
--- a/llvm/include/llvm/ADT/bit.h
+++ b/llvm/include/llvm/ADT/bit.h
@@ -29,7 +29,7 @@
 
 #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) ||            \
     defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) ||  \
-    defined(__OpenBSD__) || defined(__DragonFly__)
+    defined(__OpenBSD__) || defined(__DragonFly__) || defined(__minerva__)
 #include <endian.h>
 #elif defined(_AIX)
 #include <sys/machine.h>
diff --git a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
index 944fca000d61f7d88d39116729f8f4028d530204..492ceb2d2ecef8aeaf5c29245c68e2ac6651480a 100644
--- a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
@@ -218,7 +218,8 @@ SharedMemoryMapper::Create(ExecutorProcessControl &EPC, SymbolAddrs SAs) {
 
 void SharedMemoryMapper::reserve(size_t NumBytes,
                                  OnReservedFunction OnReserved) {
-#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
+#if (defined(LLVM_ON_UNIX) && !(defined(__ANDROID__) || defined(__minerva__))) \
+    || defined(_WIN32)
 
   EPC.callSPSWrapperAsync<
       rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>(
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
index 4fbf232008c89e2cc3555cc40617524f8da8350e..579b5c7c40eadd6c9b5a1f42fa877b18f6bed178 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
@@ -50,7 +50,8 @@ static DWORD getWindowsProtectionFlags(MemProt MP) {
 
 Expected<std::pair<ExecutorAddr, std::string>>
 ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
-#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
+#if (defined(LLVM_ON_UNIX) && !(defined(__ANDROID__) || defined(__minerva__))) \
+    || defined(_WIN32)
 
 #if defined(LLVM_ON_UNIX)
 
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 6004e007c0c7a03e4c40118aeb738b92a3e71fee..8564c69a28a25b21aa96049361326fa84aa7e3b9 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -107,7 +107,7 @@ typedef uint_t uint;
 #endif
 
 #if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) ||       \
-    defined(__MVS__)
+    defined(__MVS__) || defined(__minerva__)
 #define STATVFS_F_FLAG(vfs) (vfs).f_flag
 #else
 #define STATVFS_F_FLAG(vfs) (vfs).f_flags
@@ -506,6 +506,9 @@ static bool is_local_impl(struct STATVFS &Vfs) {
 #elif defined(__HAIKU__)
   // Haiku doesn't expose this information.
   return false;
+#elif defined(__minerva__)
+  // Minerva doesn't yet support remote filesystem mounts.
+  return false;
 #elif defined(__sun)
   // statvfs::f_basetype contains a null-terminated FSType name of the mounted
   // target
diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
index 0708df1eed0a3a8493e57b45ef4b7e55e68f9c4e..a6103e357593062a5fc9e1119cbe228ed5095ad5 100644
--- a/llvm/lib/Support/Unix/Program.inc
+++ b/llvm/lib/Support/Unix/Program.inc
@@ -342,7 +342,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
 namespace llvm {
 namespace sys {
 
-#if defined(_AIX)
+#if defined(_AIX) || defined(__minerva__)
 static pid_t(wait4)(pid_t pid, int *status, int options, struct rusage *usage);
 #elif !defined(__Fuchsia__)
 using ::wait4;
@@ -385,6 +385,13 @@ pid_t(llvm::sys::wait4)(pid_t pid, int *status, int options,
 }
 #endif
 
+#ifdef __minerva__
+pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
+                         struct rusage*) {
+  return ::waitpid(pid, status, options);
+}
+#endif
+
 ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
                             std::optional<unsigned> SecondsToWait,
                             std::string *ErrMsg,
