From b50af6045561104f9021b1da7f3e18aebbb659f1 Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov <9erthalion6@gmail.com> Date: Sat, 5 Oct 2024 18:31:36 +0200 Subject: [PATCH v1 3/4] 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 | 19 +++++++++++++++++++ src/backend/jit/llvm/llvmjit.c | 17 +++++++++++++++++ src/backend/tcop/postgres.c | 7 +++++++ src/include/jit/jit.h | 11 +++++++++++ src/include/jit/llvmjit.h | 2 ++ 5 files changed, 56 insertions(+) diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c index 815b58f..8085a43 100644 --- a/src/backend/jit/jit.c +++ b/src/backend/jit/jit.c @@ -188,3 +188,22 @@ InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add) INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter); INSTR_TIME_ADD(dst->emission_counter, add->emission_counter); } + +/* + * Return JIT provider's version string for troubleshooting purposes. + */ +const char * +jit_get_version(bool *available) +{ + if (provider_init()) + return provider.get_version(available); + + *available = false; + return ""; +} + +void +jit_register_version(void) +{ + add_system_version("LLVM", jit_get_version, RunTime); +} diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 0f6cec5..2eed882 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -165,6 +165,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; } @@ -1382,3 +1383,19 @@ ResOwnerReleaseJitContext(Datum res) context->resowner = NULL; jit_release_context(&context->base); } + +const char * +llvm_version(bool *available) +{ +#if LLVM_VERSION_MAJOR > 15 + unsigned int major, minor, patch; + + LLVMGetVersion(&major, &minor, &patch); + + *available = true; + return (const char*) psprintf("%d.%d.%d", major, minor, patch); +#else + *available = false; + return ""; +#endif +} diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3b45fdc..84a2a44 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -5293,4 +5293,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/include/jit/jit.h b/src/include/jit/jit.h index d9a080c..6b3d453 100644 --- a/src/include/jit/jit.h +++ b/src/include/jit/jit.h @@ -13,6 +13,7 @@ #include "executor/instrument.h" #include "utils/resowner.h" +#include "utils/system_version.h" /* Flags determining what kind of JIT operations to perform */ @@ -70,12 +71,14 @@ typedef void (*JitProviderResetAfterErrorCB) (void); typedef void (*JitProviderReleaseContextCB) (JitContext *context); struct ExprState; typedef bool (*JitProviderCompileExprCB) (struct ExprState *state); +typedef const char* (*JitProviderVersion) (bool *available); struct JitProviderCallbacks { JitProviderResetAfterErrorCB reset_after_error; JitProviderReleaseContextCB release_context; JitProviderCompileExprCB compile_expr; + JitProviderVersion get_version; }; @@ -102,5 +105,13 @@ extern void jit_release_context(JitContext *context); extern bool jit_compile_expr(struct ExprState *state); extern void InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add); +/* + * Get the provider's version string. The flag indicating availability is + * passed as an argument, and will be set accordingly if it's not possible to + * get the version. + */ +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 420775b..898848a 100644 --- a/src/include/jit/llvmjit.h +++ b/src/include/jit/llvmjit.h @@ -136,6 +136,8 @@ extern LLVMValueRef slot_compile_deform(struct LLVMJitContext *context, TupleDes extern LLVMTypeRef LLVMGetFunctionReturnType(LLVMValueRef r); extern LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r); +extern const char* llvm_version(bool *available); + #ifdef __cplusplus } /* extern "C" */ #endif -- 2.45.1