]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
backpatch "jit: Add support for LLVM 12."
authorAndres Freund <andres@anarazel.de>
Tue, 10 Nov 2020 04:01:33 +0000 (20:01 -0800)
committerAndres Freund <andres@anarazel.de>
Tue, 8 Dec 2020 02:39:32 +0000 (18:39 -0800)
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
src/tools/pgindent/typedefs.list

index 352aeab8210e0aaf730926c33863100b1b02fd91..3b8bc291fcc2c02de806f2b1a66137e65994c993 100644 (file)
 #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>
 /* 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;
 
 
@@ -97,12 +108,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);
@@ -114,6 +128,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;
 
@@ -173,24 +191,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);
        }
 }
 
@@ -246,8 +287,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
 
@@ -267,9 +308,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;
@@ -278,26 +350,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);
 
@@ -426,6 +501,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, "");
        }
@@ -517,11 +594,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;
@@ -568,6 +649,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
@@ -575,13 +659,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 */
        }
@@ -590,20 +703,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);
@@ -613,15 +729,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,
@@ -643,6 +751,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;
@@ -675,12 +785,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,
@@ -694,27 +804,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);
 
@@ -726,27 +850,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 */
@@ -945,3 +1091,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 */
index 2f23dc3ecd575a637c421c96f52d812993759f7f..dddf484d684a521ba7ae50f45ba239c60d6e0e7b 100644 (file)
@@ -1178,6 +1178,7 @@ LLVMJitHandle
 LLVMMemoryBufferRef
 LLVMModuleRef
 LLVMOrcJITStackRef
+LLVMOrcLookupStateRef
 LLVMOrcModuleHandle
 LLVMOrcTargetAddress
 LLVMPassManagerBuilderRef