From 2212c9653d556e7ccb5c5a37407a51d33318d227 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 12 Oct 2023 09:16:22 -0400
Subject: [PATCH] kernel: mark TLS accessors as noinline for non-MSVC LTO

---
 src/common/common_funcs.h      |  4 ++++
 src/core/hle/kernel/kernel.cpp | 16 ++++++++--------
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 0dad9338ac..47d028d482 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -39,8 +39,12 @@
 #define Crash() exit(1)
 #endif
 
+#define LTO_NOINLINE __attribute__((noinline))
+
 #else // _MSC_VER
 
+#define LTO_NOINLINE
+
 // Locale Cross-Compatibility
 #define locale_t _locale_t
 
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index a1134b7e26..cb025c3d6d 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -373,7 +373,7 @@ struct KernelCore::Impl {
     static inline thread_local u8 host_thread_id = UINT8_MAX;
 
     /// Sets the host thread ID for the caller.
-    u32 SetHostThreadId(std::size_t core_id) {
+    LTO_NOINLINE u32 SetHostThreadId(std::size_t core_id) {
         // This should only be called during core init.
         ASSERT(host_thread_id == UINT8_MAX);
 
@@ -384,13 +384,13 @@ struct KernelCore::Impl {
     }
 
     /// Gets the host thread ID for the caller
-    u32 GetHostThreadId() const {
+    LTO_NOINLINE u32 GetHostThreadId() const {
         return host_thread_id;
     }
 
     // Gets the dummy KThread for the caller, allocating a new one if this is the first time
-    KThread* GetHostDummyThread(KThread* existing_thread) {
-        const auto initialize{[](KThread* thread) {
+    LTO_NOINLINE KThread* GetHostDummyThread(KThread* existing_thread) {
+        const auto initialize{[](KThread* thread) LTO_NOINLINE {
             ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
             return thread;
         }};
@@ -424,11 +424,11 @@ struct KernelCore::Impl {
 
     static inline thread_local bool is_phantom_mode_for_singlecore{false};
 
-    bool IsPhantomModeForSingleCore() const {
+    LTO_NOINLINE bool IsPhantomModeForSingleCore() const {
         return is_phantom_mode_for_singlecore;
     }
 
-    void SetIsPhantomModeForSingleCore(bool value) {
+    LTO_NOINLINE void SetIsPhantomModeForSingleCore(bool value) {
         ASSERT(!is_multicore);
         is_phantom_mode_for_singlecore = value;
     }
@@ -439,14 +439,14 @@ struct KernelCore::Impl {
 
     static inline thread_local KThread* current_thread{nullptr};
 
-    KThread* GetCurrentEmuThread() {
+    LTO_NOINLINE KThread* GetCurrentEmuThread() {
         if (!current_thread) {
             current_thread = GetHostDummyThread(nullptr);
         }
         return current_thread;
     }
 
-    void SetCurrentEmuThread(KThread* thread) {
+    LTO_NOINLINE void SetCurrentEmuThread(KThread* thread) {
         current_thread = thread;
     }