[packages/postgresql/POSTGRESQL_11] upstream patch to fix build with llvm 12; rel 12

atler atler at pld-linux.org
Tue May 25 13:36:29 CEST 2021


commit 48b0b56d626bb862dd702af3aba7c8f6cc2ede85
Author: Jan Palus <atler at pld-linux.org>
Date:   Tue May 25 13:33:04 2021 +0200

    upstream patch to fix build with llvm 12; rel 12

 llvm12.patch    | 673 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 postgresql.spec |   4 +-
 2 files changed, 676 insertions(+), 1 deletion(-)
---
diff --git a/postgresql.spec b/postgresql.spec
index 2d01098..c5fee07 100644
--- a/postgresql.spec
+++ b/postgresql.spec
@@ -36,7 +36,7 @@ Summary(uk.UTF-8):	PostgreSQL - система керування базами 
 Summary(zh_CN.UTF-8):	PostgreSQL 客户端程序和库文件
 Name:		postgresql
 Version:	%{mver}.5
-Release:	11
+Release:	12
 License:	BSD
 Group:		Applications/Databases
 Source0:	http://ftp.postgresql.org/pub/source/v%{version}/%{name}-%{version}.tar.bz2
@@ -58,6 +58,7 @@ Patch6:		%{name}-link.patch
 Patch7:		llvm10.patch
 Patch8:		llvm11.patch
 Patch9:		ac.patch
+Patch10:	llvm12.patch
 URL:		http://www.postgresql.org/
 BuildRequires:	autoconf >= 2.69
 BuildRequires:	automake
@@ -797,6 +798,7 @@ Różne moduły dołączone do PostgreSQL-a.
 %patch7 -p1
 %patch8 -p1
 %patch9 -p1
+%patch10 -p1
 
 # force rebuild of bison/flex files
 find src -name \*.l -o -name \*.y | xargs touch
diff --git a/llvm12.patch b/llvm12.patch
new file mode 100644
index 0000000..d337b34
--- /dev/null
+++ b/llvm12.patch
@@ -0,0 +1,673 @@
+From 90eb343ef3929a0cce5b6940781680cd4f7801f2 Mon Sep 17 00:00:00 2001
+From: Andres Freund <andres at anarazel.de>
+Date: Mon, 9 Nov 2020 20:01:33 -0800
+Subject: [PATCH] backpatch "jit: Add support for LLVM 12."
+
+As there haven't been problem on the buildfarm due to this change,
+backpatch 6c57f2ed16e now.
+
+Author: Andres Freund
+Discussion: https://postgr.es/m/20201016011244.pmyvr3ee2gbzplq4@alap3.anarazel.de
+Backpatch: 11-, where jit support was added
+---
+ src/backend/jit/llvm/llvmjit.c   | 458 +++++++++++++++++++++++++------
+ src/tools/pgindent/typedefs.list |   1 +
+ 2 files changed, 374 insertions(+), 85 deletions(-)
+
+diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
+index 929873cb49..78c0b9385c 100644
+--- a/src/backend/jit/llvm/llvmjit.c
++++ b/src/backend/jit/llvm/llvmjit.c
+@@ -29,7 +29,13 @@
+ #include <llvm-c/BitWriter.h>
+ #include <llvm-c/Core.h>
+ #include <llvm-c/ExecutionEngine.h>
++#if LLVM_VERSION_MAJOR > 11
++#include <llvm-c/Orc.h>
++#include <llvm-c/OrcEE.h>
++#include <llvm-c/LLJIT.h>
++#else
+ #include <llvm-c/OrcBindings.h>
++#endif
+ #include <llvm-c/Support.h>
+ #include <llvm-c/Target.h>
+ #include <llvm-c/Transforms/IPO.h>
+@@ -43,8 +49,13 @@
+ /* Handle of a module emitted via ORC JIT */
+ typedef struct LLVMJitHandle
+ {
++#if LLVM_VERSION_MAJOR > 11
++	LLVMOrcLLJITRef lljit;
++	LLVMOrcResourceTrackerRef resource_tracker;
++#else
+ 	LLVMOrcJITStackRef stack;
+ 	LLVMOrcModuleHandle orc_handle;
++#endif
+ } LLVMJitHandle;
+ 
+ 
+@@ -94,12 +105,15 @@ static const char *llvm_triple = NULL;
+ static const char *llvm_layout = NULL;
+ 
+ 
+-static LLVMTargetMachineRef llvm_opt0_targetmachine;
+-static LLVMTargetMachineRef llvm_opt3_targetmachine;
+-
+ static LLVMTargetRef llvm_targetref;
++#if LLVM_VERSION_MAJOR > 11
++static LLVMOrcThreadSafeContextRef llvm_ts_context;
++static LLVMOrcLLJITRef llvm_opt0_orc;
++static LLVMOrcLLJITRef llvm_opt3_orc;
++#else							/* LLVM_VERSION_MAJOR > 11 */
+ static LLVMOrcJITStackRef llvm_opt0_orc;
+ static LLVMOrcJITStackRef llvm_opt3_orc;
++#endif							/* LLVM_VERSION_MAJOR > 11 */
+ 
+ 
+ static void llvm_release_context(JitContext *context);
+@@ -111,6 +125,10 @@ static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module);
+ static void llvm_create_types(void);
+ static uint64_t llvm_resolve_symbol(const char *name, void *ctx);
+ 
++#if LLVM_VERSION_MAJOR > 11
++static LLVMOrcLLJITRef llvm_create_jit_instance(LLVMTargetMachineRef tm);
++static char *llvm_error_message(LLVMErrorRef error);
++#endif							/* LLVM_VERSION_MAJOR > 11 */
+ 
+ PG_MODULE_MAGIC;
+ 
+@@ -170,24 +188,47 @@ llvm_release_context(JitContext *context)
+ 	 * have occurred from within LLVM, we do not want to risk reentering. All
+ 	 * resource cleanup is going to happen through process exit.
+ 	 */
+-	if (!proc_exit_inprogress)
++	if (proc_exit_inprogress)
++		return;
++
++	if (llvm_context->module)
+ 	{
+-		if (llvm_context->module)
+-		{
+-			LLVMDisposeModule(llvm_context->module);
+-			llvm_context->module = NULL;
+-		}
++		LLVMDisposeModule(llvm_context->module);
++		llvm_context->module = NULL;
++	}
+ 
+-		while (llvm_context->handles != NIL)
+-		{
+-			LLVMJitHandle *jit_handle;
++	while (llvm_context->handles != NIL)
++	{
++		LLVMJitHandle *jit_handle;
+ 
+-			jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
+-			llvm_context->handles = list_delete_first(llvm_context->handles);
++		jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
++		llvm_context->handles = list_delete_first(llvm_context->handles);
+ 
++#if LLVM_VERSION_MAJOR > 11
++		{
++			LLVMOrcExecutionSessionRef ee;
++			LLVMOrcSymbolStringPoolRef sp;
++
++			LLVMOrcResourceTrackerRemove(jit_handle->resource_tracker);
++			LLVMOrcReleaseResourceTracker(jit_handle->resource_tracker);
++
++			/*
++			 * Without triggering cleanup of the string pool, we'd leak
++			 * memory. It'd be sufficient to do this far less often, but in
++			 * experiments the required time was small enough to just always
++			 * do it.
++			 */
++			ee = LLVMOrcLLJITGetExecutionSession(jit_handle->lljit);
++			sp = LLVMOrcExecutionSessionGetSymbolStringPool(ee);
++			LLVMOrcSymbolStringPoolClearDeadEntries(sp);
++		}
++#else							/* LLVM_VERSION_MAJOR > 11 */
++		{
+ 			LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle);
+-			pfree(jit_handle);
+ 		}
++#endif							/* LLVM_VERSION_MAJOR > 11 */
++
++		pfree(jit_handle);
+ 	}
+ }
+ 
+@@ -243,8 +284,8 @@ llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
+ void *
+ llvm_get_function(LLVMJitContext *context, const char *funcname)
+ {
+-	LLVMOrcTargetAddress addr = 0;
+-#if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
++#if LLVM_VERSION_MAJOR > 11 || \
++	defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
+ 	ListCell   *lc;
+ #endif
+ 
+@@ -264,9 +305,40 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
+ 	 * to mangle here.
+ 	 */
+ 
+-#if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
++#if LLVM_VERSION_MAJOR > 11
++	foreach(lc, context->handles)
++	{
++		LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
++		instr_time	starttime;
++		instr_time	endtime;
++		LLVMErrorRef error;
++		LLVMOrcJITTargetAddress addr;
++
++		INSTR_TIME_SET_CURRENT(starttime);
++
++		addr = 0;
++		error = LLVMOrcLLJITLookup(handle->lljit, &addr, funcname);
++		if (error)
++			elog(ERROR, "failed to look up symbol \"%s\": %s",
++				 funcname, llvm_error_message(error));
++
++		/*
++		 * LLJIT only actually emits code the first time a symbol is
++		 * referenced. Thus add lookup time to emission time. That's counting
++		 * a bit more than with older LLVM versions, but unlikely to ever
++		 * matter.
++		 */
++		INSTR_TIME_SET_CURRENT(endtime);
++		INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
++							  endtime, starttime);
++
++		if (addr)
++			return (void *) (uintptr_t) addr;
++	}
++#elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
+ 	foreach(lc, context->handles)
+ 	{
++		LLVMOrcTargetAddress addr;
+ 		LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
+ 
+ 		addr = 0;
+@@ -275,26 +347,29 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
+ 		if (addr)
+ 			return (void *) (uintptr_t) addr;
+ 	}
++#elif LLVM_VERSION_MAJOR < 5
++	{
++		LLVMOrcTargetAddress addr;
+ 
++		if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
++			return (void *) (uintptr_t) addr;
++		if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
++			return (void *) (uintptr_t) addr;
++	}
+ #else
++	{
++		LLVMOrcTargetAddress addr;
+ 
+-#if LLVM_VERSION_MAJOR < 5
+-	if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
+-		return (void *) (uintptr_t) addr;
+-	if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
+-		return (void *) (uintptr_t) addr;
+-#else
+-	if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
+-		elog(ERROR, "failed to look up symbol \"%s\"", funcname);
+-	if (addr)
+-		return (void *) (uintptr_t) addr;
+-	if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
+-		elog(ERROR, "failed to look up symbol \"%s\"", funcname);
+-	if (addr)
+-		return (void *) (uintptr_t) addr;
+-#endif							/* LLVM_VERSION_MAJOR */
+-
+-#endif							/* HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */
++		if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
++			elog(ERROR, "failed to look up symbol \"%s\"", funcname);
++		if (addr)
++			return (void *) (uintptr_t) addr;
++		if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
++			elog(ERROR, "failed to look up symbol \"%s\"", funcname);
++		if (addr)
++			return (void *) (uintptr_t) addr;
++	}
++#endif
+ 
+ 	elog(ERROR, "failed to JIT: %s", funcname);
+ 
+@@ -425,6 +500,8 @@ llvm_function_reference(LLVMJitContext *context,
+ 		v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
+ 		LLVMSetInitializer(v_fn, v_fn_addr);
+ 		LLVMSetGlobalConstant(v_fn, true);
++		LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
++		LLVMSetUnnamedAddr(v_fn, true);
+ 
+ 		return LLVMBuildLoad(builder, v_fn, "");
+ 	}
+@@ -516,11 +593,15 @@ llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
+ static void
+ llvm_compile_module(LLVMJitContext *context)
+ {
+-	LLVMOrcModuleHandle orc_handle;
++	LLVMJitHandle *handle;
+ 	MemoryContext oldcontext;
+-	static LLVMOrcJITStackRef compile_orc;
+ 	instr_time	starttime;
+ 	instr_time	endtime;
++#if LLVM_VERSION_MAJOR > 11
++	LLVMOrcLLJITRef compile_orc;
++#else
++	LLVMOrcJITStackRef compile_orc;
++#endif
+ 
+ 	if (context->base.flags & PGJIT_OPT3)
+ 		compile_orc = llvm_opt3_orc;
+@@ -567,6 +648,9 @@ llvm_compile_module(LLVMJitContext *context)
+ 		pfree(filename);
+ 	}
+ 
++	handle = (LLVMJitHandle *)
++		MemoryContextAlloc(TopMemoryContext, sizeof(LLVMJitHandle));
++
+ 	/*
+ 	 * Emit the code. Note that this can, depending on the optimization
+ 	 * settings, take noticeable resources as code emission executes low-level
+@@ -574,13 +658,42 @@ llvm_compile_module(LLVMJitContext *context)
+ 	 * faster instruction selection mechanism is used.
+ 	 */
+ 	INSTR_TIME_SET_CURRENT(starttime);
+-#if LLVM_VERSION_MAJOR > 6
++#if LLVM_VERSION_MAJOR > 11
++	{
++		LLVMOrcThreadSafeModuleRef ts_module;
++		LLVMErrorRef error;
++		LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(compile_orc);
++
++		ts_module = LLVMOrcCreateNewThreadSafeModule(context->module, llvm_ts_context);
++
++		handle->lljit = compile_orc;
++		handle->resource_tracker = LLVMOrcJITDylibCreateResourceTracker(jd);
++
++		/*
++		 * NB: This doesn't actually emit code. That happens lazily the first
++		 * time a symbol defined in the module is requested. Due to that
++		 * llvm_get_function() also accounts for emission time.
++		 */
++
++		context->module = NULL; /* will be owned by LLJIT */
++		error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc,
++												  handle->resource_tracker,
++												  ts_module);
++
++		if (error)
++			elog(ERROR, "failed to JIT module: %s",
++				 llvm_error_message(error));
++
++		handle->lljit = compile_orc;
++
++		/* LLVMOrcLLJITAddLLVMIRModuleWithRT takes ownership of the module */
++	}
++#elif LLVM_VERSION_MAJOR > 6
+ 	{
+-		if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, context->module,
++		handle->stack = compile_orc;
++		if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, context->module,
+ 										llvm_resolve_symbol, NULL))
+-		{
+ 			elog(ERROR, "failed to JIT module");
+-		}
+ 
+ 		/* LLVMOrcAddEagerlyCompiledIR takes ownership of the module */
+ 	}
+@@ -589,20 +702,23 @@ llvm_compile_module(LLVMJitContext *context)
+ 		LLVMSharedModuleRef smod;
+ 
+ 		smod = LLVMOrcMakeSharedModule(context->module);
+-		if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, smod,
++		handle->stack = compile_orc;
++		if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, smod,
+ 										llvm_resolve_symbol, NULL))
+-		{
+ 			elog(ERROR, "failed to JIT module");
+-		}
++
+ 		LLVMOrcDisposeSharedModuleRef(smod);
+ 	}
+ #else							/* LLVM 4.0 and 3.9 */
+ 	{
+-		orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
+-												 llvm_resolve_symbol, NULL);
++		handle->stack = compile_orc;
++		handle->orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
++														 llvm_resolve_symbol, NULL);
++
+ 		LLVMDisposeModule(context->module);
+ 	}
+ #endif
++
+ 	INSTR_TIME_SET_CURRENT(endtime);
+ 	INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
+ 						  endtime, starttime);
+@@ -612,15 +728,7 @@ llvm_compile_module(LLVMJitContext *context)
+ 
+ 	/* remember emitted code for cleanup and lookups */
+ 	oldcontext = MemoryContextSwitchTo(TopMemoryContext);
+-	{
+-		LLVMJitHandle *handle;
+-
+-		handle = (LLVMJitHandle *) palloc(sizeof(LLVMJitHandle));
+-		handle->stack = compile_orc;
+-		handle->orc_handle = orc_handle;
+-
+-		context->handles = lappend(context->handles, handle);
+-	}
++	context->handles = lappend(context->handles, handle);
+ 	MemoryContextSwitchTo(oldcontext);
+ 
+ 	ereport(DEBUG1,
+@@ -642,6 +750,8 @@ llvm_session_initialize(void)
+ 	char	   *error = NULL;
+ 	char	   *cpu = NULL;
+ 	char	   *features = NULL;
++	LLVMTargetMachineRef opt0_tm;
++	LLVMTargetMachineRef opt3_tm;
+ 
+ 	if (llvm_session_initialized)
+ 		return;
+@@ -674,12 +784,12 @@ llvm_session_initialize(void)
+ 	elog(DEBUG2, "LLVMJIT detected CPU \"%s\", with features \"%s\"",
+ 		 cpu, features);
+ 
+-	llvm_opt0_targetmachine =
++	opt0_tm =
+ 		LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
+ 								LLVMCodeGenLevelNone,
+ 								LLVMRelocDefault,
+ 								LLVMCodeModelJITDefault);
+-	llvm_opt3_targetmachine =
++	opt3_tm =
+ 		LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
+ 								LLVMCodeGenLevelAggressive,
+ 								LLVMRelocDefault,
+@@ -693,27 +803,41 @@ llvm_session_initialize(void)
+ 	/* force symbols in main binary to be loaded */
+ 	LLVMLoadLibraryPermanently(NULL);
+ 
+-	llvm_opt0_orc = LLVMOrcCreateInstance(llvm_opt0_targetmachine);
+-	llvm_opt3_orc = LLVMOrcCreateInstance(llvm_opt3_targetmachine);
+-
+-#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
+-	if (jit_debugging_support)
++#if LLVM_VERSION_MAJOR > 11
+ 	{
+-		LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
++		llvm_ts_context = LLVMOrcCreateNewThreadSafeContext();
++
++		llvm_opt0_orc = llvm_create_jit_instance(opt0_tm);
++		opt0_tm = 0;
+ 
+-		LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
+-		LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
++		llvm_opt3_orc = llvm_create_jit_instance(opt3_tm);
++		opt3_tm = 0;
+ 	}
++#else							/* LLVM_VERSION_MAJOR > 11 */
++	{
++		llvm_opt0_orc = LLVMOrcCreateInstance(opt0_tm);
++		llvm_opt3_orc = LLVMOrcCreateInstance(opt3_tm);
++
++#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
++		if (jit_debugging_support)
++		{
++			LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
++
++			LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
++			LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
++		}
+ #endif
+ #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
+-	if (jit_profiling_support)
+-	{
+-		LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
++		if (jit_profiling_support)
++		{
++			LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
+ 
+-		LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
+-		LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
+-	}
++			LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
++			LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
++		}
+ #endif
++	}
++#endif							/* LLVM_VERSION_MAJOR > 11 */
+ 
+ 	before_shmem_exit(llvm_shutdown, 0);
+ 
+@@ -725,27 +849,49 @@ llvm_session_initialize(void)
+ static void
+ llvm_shutdown(int code, Datum arg)
+ {
+-	/* unregister profiling support, needs to be flushed to be useful */
+-
+-	if (llvm_opt3_orc)
++#if LLVM_VERSION_MAJOR > 11
++	{
++		if (llvm_opt3_orc)
++		{
++			LLVMOrcDisposeLLJIT(llvm_opt3_orc);
++			llvm_opt3_orc = NULL;
++		}
++		if (llvm_opt0_orc)
++		{
++			LLVMOrcDisposeLLJIT(llvm_opt0_orc);
++			llvm_opt0_orc = NULL;
++		}
++		if (llvm_ts_context)
++		{
++			LLVMOrcDisposeThreadSafeContext(llvm_ts_context);
++			llvm_ts_context = NULL;
++		}
++	}
++#else							/* LLVM_VERSION_MAJOR > 11 */
+ 	{
++		/* unregister profiling support, needs to be flushed to be useful */
++
++		if (llvm_opt3_orc)
++		{
+ #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
+-		if (jit_profiling_support)
+-			LLVMOrcUnregisterPerf(llvm_opt3_orc);
++			if (jit_profiling_support)
++				LLVMOrcUnregisterPerf(llvm_opt3_orc);
+ #endif
+-		LLVMOrcDisposeInstance(llvm_opt3_orc);
+-		llvm_opt3_orc = NULL;
+-	}
++			LLVMOrcDisposeInstance(llvm_opt3_orc);
++			llvm_opt3_orc = NULL;
++		}
+ 
+-	if (llvm_opt0_orc)
+-	{
++		if (llvm_opt0_orc)
++		{
+ #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
+-		if (jit_profiling_support)
+-			LLVMOrcUnregisterPerf(llvm_opt0_orc);
++			if (jit_profiling_support)
++				LLVMOrcUnregisterPerf(llvm_opt0_orc);
+ #endif
+-		LLVMOrcDisposeInstance(llvm_opt0_orc);
+-		llvm_opt0_orc = NULL;
++			LLVMOrcDisposeInstance(llvm_opt0_orc);
++			llvm_opt0_orc = NULL;
++		}
+ 	}
++#endif							/* LLVM_VERSION_MAJOR > 11 */
+ }
+ 
+ /* helper for llvm_create_types, returning a global var's type */
+@@ -941,3 +1087,145 @@ llvm_resolve_symbol(const char *symname, void *ctx)
+ 
+ 	return (uint64_t) addr;
+ }
++
++#if LLVM_VERSION_MAJOR > 11
++
++static LLVMErrorRef
++llvm_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx,
++					 LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind,
++					 LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags,
++					 LLVMOrcCLookupSet LookupSet, size_t LookupSetSize)
++{
++	LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMJITCSymbolMapPair) * LookupSetSize);
++	LLVMErrorRef error;
++	LLVMOrcMaterializationUnitRef mu;
++
++	for (int i = 0; i < LookupSetSize; i++)
++	{
++		const char *name = LLVMOrcSymbolStringPoolEntryStr(LookupSet[i].Name);
++
++		symbols[i].Name = LookupSet[i].Name;
++		symbols[i].Sym.Address = llvm_resolve_symbol(name, NULL);
++		symbols[i].Sym.Flags.GenericFlags = LLVMJITSymbolGenericFlagsExported;
++	}
++
++	mu = LLVMOrcAbsoluteSymbols(symbols, LookupSetSize);
++	error = LLVMOrcJITDylibDefine(JD, mu);
++	if (error != LLVMErrorSuccess)
++		LLVMOrcDisposeMaterializationUnit(mu);
++
++	pfree(symbols);
++
++	return error;
++}
++
++/*
++ * We cannot throw errors through LLVM (without causing a FATAL at least), so
++ * just use WARNING here. That's OK anyway, as the error is also reported at
++ * the top level action (with less detail) and there might be multiple
++ * invocations of errors with details.
++ *
++ * This doesn't really happen during normal operation, but in cases like
++ * symbol resolution breakage. So just using elog(WARNING) is fine.
++ */
++static void
++llvm_log_jit_error(void *ctx, LLVMErrorRef error)
++{
++	elog(WARNING, "error during JITing: %s",
++		 llvm_error_message(error));
++}
++
++/*
++ * Create our own object layer, so we can add event listeners.
++ */
++static LLVMOrcObjectLayerRef
++llvm_create_object_layer(void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple)
++{
++	LLVMOrcObjectLayerRef objlayer =
++	LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(ES);
++
++#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
++	if (jit_debugging_support)
++	{
++		LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
++
++		LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
++	}
++#endif
++
++#if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
++	if (jit_profiling_support)
++	{
++		LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
++
++		LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
++	}
++#endif
++
++	return objlayer;
++}
++
++/*
++ * Create LLJIT instance, using the passed in target machine. Note that the
++ * target machine afterwards is owned by the LLJIT instance.
++ */
++static LLVMOrcLLJITRef
++llvm_create_jit_instance(LLVMTargetMachineRef tm)
++{
++	LLVMOrcLLJITRef lljit;
++	LLVMOrcJITTargetMachineBuilderRef tm_builder;
++	LLVMOrcLLJITBuilderRef lljit_builder;
++	LLVMErrorRef error;
++	LLVMOrcDefinitionGeneratorRef main_gen;
++	LLVMOrcDefinitionGeneratorRef ref_gen;
++
++	lljit_builder = LLVMOrcCreateLLJITBuilder();
++	tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(tm);
++	LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(lljit_builder, tm_builder);
++
++	LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(lljit_builder,
++													llvm_create_object_layer,
++													NULL);
++
++	error = LLVMOrcCreateLLJIT(&lljit, lljit_builder);
++	if (error)
++		elog(ERROR, "failed to create lljit instance: %s",
++			 llvm_error_message(error));
++
++	LLVMOrcExecutionSessionSetErrorReporter(LLVMOrcLLJITGetExecutionSession(lljit),
++											llvm_log_jit_error, NULL);
++
++	/*
++	 * Symbol resolution support for symbols in the postgres binary /
++	 * libraries already loaded.
++	 */
++	error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(&main_gen,
++																 LLVMOrcLLJITGetGlobalPrefix(lljit),
++																 0, NULL);
++	if (error)
++		elog(ERROR, "failed to create generator: %s",
++			 llvm_error_message(error));
++	LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), main_gen);
++
++	/*
++	 * Symbol resolution support for "special" functions, e.g. a call into an
++	 * SQL callable function.
++	 */
++	ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL);
++	LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), ref_gen);
++
++	return lljit;
++}
++
++static char *
++llvm_error_message(LLVMErrorRef error)
++{
++	char	   *orig = LLVMGetErrorMessage(error);
++	char	   *msg = pstrdup(orig);
++
++	LLVMDisposeErrorMessage(orig);
++
++	return msg;
++}
++
++#endif							/* LLVM_VERSION_MAJOR > 11 */
+diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
+index bbe62ab90b..a49e779fcf 100644
+--- a/src/tools/pgindent/typedefs.list
++++ b/src/tools/pgindent/typedefs.list
+@@ -1133,6 +1133,7 @@ LLVMJitHandle
+ LLVMMemoryBufferRef
+ LLVMModuleRef
+ LLVMOrcJITStackRef
++LLVMOrcLookupStateRef
+ LLVMOrcModuleHandle
+ LLVMOrcTargetAddress
+ LLVMPassManagerBuilderRef
+-- 
+2.29.2
+
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/postgresql.git/commitdiff/48b0b56d626bb862dd702af3aba7c8f6cc2ede85



More information about the pld-cvs-commit mailing list