From 1b48f779790d722c46ddb0f2d495ef39ec911275 Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov <9erthalion6@gmail.com> Date: Sat, 5 Oct 2024 18:31:36 +0200 Subject: [PATCH v5 3/3] Add JIT provider version to pg_system_versions Populate pg_system_versions with the JIT provider version. To actually fetch the version, extend the JIT provider callbacks with the get_version method. For LLVM provider llvm_version will be used, which utilizes C-API LLVMGetVersion, available since LLVM 16. The JIT provider will be initialized, when a first expression will be compiled. For reporting purposes it's too late, thus register the version at the backend startup, right after the core versions. --- src/backend/jit/jit.c | 27 +++++++++++++++++++++++++ src/backend/jit/llvm/llvmjit.c | 17 ++++++++++++++++ src/backend/tcop/postgres.c | 7 +++++++ src/backend/utils/misc/system_version.c | 1 + src/include/jit/jit.h | 9 +++++++++ src/include/jit/llvmjit.h | 2 ++ 6 files changed, 63 insertions(+) diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c index d2ccef9de85..f4bd0b768ad 100644 --- a/src/backend/jit/jit.c +++ b/src/backend/jit/jit.c @@ -188,3 +188,30 @@ InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add) INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter); INSTR_TIME_ADD(dst->emission_counter, add->emission_counter); } + +/* + * Callback for add_system_version, returns JIT provider's version string and + * reports if it's not available. + */ +const char * +jit_get_version(bool *available) +{ + const char *version; + + if (!provider_init()) + { + *available = false; + return ""; + } + + version = provider.get_version(); + + if (version == NULL) + { + *available = false; + return ""; + } + + *available = true; + return version; +} diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index e978b996bae..b2f445963ab 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -154,6 +154,7 @@ _PG_jit_provider_init(JitProviderCallbacks *cb) cb->reset_after_error = llvm_reset_after_error; cb->release_context = llvm_release_context; cb->compile_expr = llvm_compile_expr; + cb->get_version = llvm_version; } @@ -1280,3 +1281,19 @@ ResOwnerReleaseJitContext(Datum res) context->resowner = NULL; jit_release_context(&context->base); } + +const char * +llvm_version() +{ +#if LLVM_VERSION_MAJOR > 15 + unsigned int major, + minor, + patch; + + LLVMGetVersion(&major, &minor, &patch); + + return (const char *) psprintf("%d.%d.%d", major, minor, patch); +#else + return NULL; +#endif +} diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3a8ff419425..a23a858f2c9 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -5248,4 +5248,11 @@ register_system_versions() { /* Set up reporting of core versions. */ register_core_versions(); + + /* + * Set up reporting for JIT provider version. JIT provider initialization + * happens when the first expression is getting compiled, which is too + * late. Thus register the callback here instead. + */ + jit_register_version(); } diff --git a/src/backend/utils/misc/system_version.c b/src/backend/utils/misc/system_version.c index 752546b8e7a..145ec36182d 100644 --- a/src/backend/utils/misc/system_version.c +++ b/src/backend/utils/misc/system_version.c @@ -32,6 +32,7 @@ #endif #include "funcapi.h" +#include "jit/jit.h" #include "utils/builtins.h" #include "utils/system_version.h" diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h index 33cb36c5d2e..5342a282fb4 100644 --- a/src/include/jit/jit.h +++ b/src/include/jit/jit.h @@ -70,12 +70,14 @@ typedef void (*JitProviderResetAfterErrorCB) (void); typedef void (*JitProviderReleaseContextCB) (JitContext *context); struct ExprState; typedef bool (*JitProviderCompileExprCB) (struct ExprState *state); +typedef const char *(*JitProviderVersion) (void); struct JitProviderCallbacks { JitProviderResetAfterErrorCB reset_after_error; JitProviderReleaseContextCB release_context; JitProviderCompileExprCB compile_expr; + JitProviderVersion get_version; }; @@ -102,5 +104,12 @@ extern void jit_release_context(JitContext *context); extern bool jit_compile_expr(struct ExprState *state); extern void InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add); +/* + * Callback for add_system_version, get the provider's version string. The flag + * indicating availability is passed as an argument. + */ +extern const char *jit_get_version(bool *available); + +extern void jit_register_version(void); #endif /* JIT_H */ diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h index b3c75022f55..1c903a4dc52 100644 --- a/src/include/jit/llvmjit.h +++ b/src/include/jit/llvmjit.h @@ -145,6 +145,8 @@ extern LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r); extern LLVMOrcObjectLayerRef LLVMOrcCreateRTDyldObjectLinkingLayerWithSafeSectionMemoryManager(LLVMOrcExecutionSessionRef ES); #endif +extern const char* llvm_version(void); + #ifdef __cplusplus } /* extern "C" */ #endif -- 2.49.0