> On Sun, Sep 22, 2024 at 01:15:54PM GMT, Dmitry Dolgov wrote:
> > On Sat, Sep 21, 2024 at 05:25:30PM GMT, Tom Lane wrote:
> >
> > Is there a way to get the llvm library's version at run time?  If so
> > we could consider building a new function to return that.
>
> Yes, there is a C api LLVMGetVersion to get the major, minor and patch
> numbers. The jit provider could be extended to return this information.
>
> About a new function, I think that the llvm runtime version has to be
> shown in some form by pgsql_version. The idea is to skip an emails
> exchange like "here is the bug report" -> "can you attach the llvm
> version?". If it's going to be a new separate function, I guess it won't
> make much difference to ask either to call the new function or the
> llvm-config, right?

Here is what I had in mind. It turns out the LLVMGetVersion API is
available only starting from LLVM 16, so there is need to indicate if
the version string is available (otherwise llvmjit would have to fully
format the version string).
>From dca9347c39cfca45de969ee49536962836ccbba4 Mon Sep 17 00:00:00 2001
From: Dmitrii Dolgov <9erthali...@gmail.com>
Date: Mon, 23 Sep 2024 19:08:52 +0200
Subject: [PATCH v2] Add jit provider's version into the pgsql_version

If jit provider is available and initialized, add its version string
into the pgsql_version output. This should help to get more relevant
information in bug reports about JIT.
---
 src/backend/jit/jit.c           | 13 +++++++++++++
 src/backend/jit/llvm/llvmjit.c  | 17 +++++++++++++++++
 src/backend/utils/adt/version.c | 15 ++++++++++++++-
 src/include/jit/jit.h           |  8 ++++++++
 src/include/jit/llvmjit.h       |  2 ++
 5 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c
index 815b58f..b62422c 100644
--- a/src/backend/jit/jit.c
+++ b/src/backend/jit/jit.c
@@ -188,3 +188,16 @@ 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 "";
+}
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 0f6cec5..3ab1080 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("llvm: %d.%d.%d", major, minor, patch);
+#else
+       *available = false;
+       return "";
+#endif
+}
diff --git a/src/backend/utils/adt/version.c b/src/backend/utils/adt/version.c
index 28db1f6..fabaf73 100644
--- a/src/backend/utils/adt/version.c
+++ b/src/backend/utils/adt/version.c
@@ -15,10 +15,23 @@
 #include "postgres.h"
 
 #include "utils/builtins.h"
+#include "jit/jit.h"
 
 
 Datum
 pgsql_version(PG_FUNCTION_ARGS)
 {
-       PG_RETURN_TEXT_P(cstring_to_text(PG_VERSION_STR));
+       bool jit_available = false;
+       const char *jit_version = jit_get_version(&jit_available);
+
+       /* Add jit provides's version string if available. */
+       if (jit_available)
+       {
+               PG_RETURN_TEXT_P(cstring_to_text(psprintf("%s, %s", 
PG_VERSION_STR,
+                                                                               
                  jit_version)));
+       }
+       else
+       {
+               PG_RETURN_TEXT_P(cstring_to_text(PG_VERSION_STR));
+       }
 }
diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h
index d9a080c..35d5a62 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) (bool *available);
 
 struct JitProviderCallbacks
 {
        JitProviderResetAfterErrorCB reset_after_error;
        JitProviderReleaseContextCB release_context;
        JitProviderCompileExprCB compile_expr;
+       JitProviderVersion get_version;
 };
 
 
@@ -102,5 +104,11 @@ 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);
 
 #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

base-commit: 6aa44060a3c94ee10273bb8a89e98a5bb2fbbacb
-- 
2.45.1

Reply via email to