From 0a538553330ea5fdb1673708704bb92a854241b9 Mon Sep 17 00:00:00 2001 From: Wiseguy <68165316+Mr-Wiseguy@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:30:33 -0400 Subject: [PATCH] Add RECOMP_FUNC definition to recomp.h for disabling IPO (#59) --- librecomp/include/librecomp/recomp.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/librecomp/include/librecomp/recomp.h b/librecomp/include/librecomp/recomp.h index 2f55a04..39b0d8f 100644 --- a/librecomp/include/librecomp/recomp.h +++ b/librecomp/include/librecomp/recomp.h @@ -6,6 +6,23 @@ #include #include +// Compiler definition to disable inter-procedural optimization, allowing multiple functions to be in a single file without breaking interposition. +#if defined(_MSC_VER) && !defined(__clang__) + // MSVC's __declspec(noinline) seems to disable inter-procedural optimization entirely, so it's all that's needed. + #define RECOMP_FUNC __declspec(noinline) +#elif defined(__clang__) + // Clang has no dedicated IPO attribute, so we use a combination of other attributes to give the desired behavior. + // The inline keyword allows multiple definitions during linking, and extern forces clang to emit an externally visible definition. + // Weak forces Clang to not perform any IPO as the symbol can be interposed, which prevents actual inlining due to the inline keyword. + // Add noinline on for good measure, which doesn't conflict with the inline keyword as they have different meanings. + #define RECOMP_FUNC extern inline __attribute__((weak,noinline)) +#elif defined(__GNUC__) + // Use GCC's attribute for disabling inter-procedural optimizations. + #define RECOMP_FUNC __attribute__((noipa)) +#else + #error "No RECOMP_FUNC definition for this compiler" +#endif + typedef uint64_t gpr; #define SIGNED(val) \