From a8f17ed927acd9b1c98441a4e43ae1fd5b90c5af Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov <9erthalion6@gmail.com> Date: Sat, 5 Oct 2024 18:31:36 +0200 Subject: [PATCH v8 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 | 24 ++++++++++++++++++++++++ src/backend/jit/llvm/llvmjit.c | 17 +++++++++++++++++ src/backend/tcop/postgres.c | 7 +++++++ src/backend/utils/misc/system_version.c | 7 +++++++ src/include/jit/jit.h | 9 +++++++++ src/include/jit/llvmjit.h | 2 ++ 6 files changed, 66 insertions(+) diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c index 3dc82b7b268..1714f310125 100644 --- a/src/backend/jit/jit.c +++ b/src/backend/jit/jit.c @@ -189,3 +189,27 @@ 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()) + { + version = provider.get_version(); + + if (version) + { + *available = true; + return version; + } + } + + *available = false; + return ""; +} diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 957ab4751b5..8165898dd29 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; } @@ -1287,3 +1288,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 eec5b035a2e..c75e217fe81 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -5419,4 +5419,11 @@ register_system_versions(void) { /* 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 3bfd1318320..207b8d87703 100644 --- a/src/backend/utils/misc/system_version.c +++ b/src/backend/utils/misc/system_version.c @@ -34,6 +34,7 @@ #endif #include "funcapi.h" +#include "jit/jit.h" #include "utils/builtins.h" #include "utils/hsearch.h" #include "utils/system_version.h" @@ -118,6 +119,12 @@ glibc_get_version(bool *available) } #endif +void +jit_register_version(void) +{ + add_system_version("LLVM", jit_get_version, RunTime); +} + /* * Register versions that describe core components and do not correspond to any * individual component. diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h index e2baa4c2ed0..6e0e5114247 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 a647dd65ba2..632d7e2f142 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.55.0