]> git.pld-linux.org Git - packages/postgresql.git/blame - llvm12.patch
UP to 11.15.
[packages/postgresql.git] / llvm12.patch
CommitLineData
48b0b56d
JP
1From 90eb343ef3929a0cce5b6940781680cd4f7801f2 Mon Sep 17 00:00:00 2001
2From: Andres Freund <andres@anarazel.de>
3Date: Mon, 9 Nov 2020 20:01:33 -0800
4Subject: [PATCH] backpatch "jit: Add support for LLVM 12."
5
6As there haven't been problem on the buildfarm due to this change,
7backpatch 6c57f2ed16e now.
8
9Author: Andres Freund
10Discussion: https://postgr.es/m/20201016011244.pmyvr3ee2gbzplq4@alap3.anarazel.de
11Backpatch: 11-, where jit support was added
12---
13 src/backend/jit/llvm/llvmjit.c | 458 +++++++++++++++++++++++++------
14 src/tools/pgindent/typedefs.list | 1 +
15 2 files changed, 374 insertions(+), 85 deletions(-)
16
17diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
18index 929873cb49..78c0b9385c 100644
19--- a/src/backend/jit/llvm/llvmjit.c
20+++ b/src/backend/jit/llvm/llvmjit.c
21@@ -29,7 +29,13 @@
22 #include <llvm-c/BitWriter.h>
23 #include <llvm-c/Core.h>
24 #include <llvm-c/ExecutionEngine.h>
25+#if LLVM_VERSION_MAJOR > 11
26+#include <llvm-c/Orc.h>
27+#include <llvm-c/OrcEE.h>
28+#include <llvm-c/LLJIT.h>
29+#else
30 #include <llvm-c/OrcBindings.h>
31+#endif
32 #include <llvm-c/Support.h>
33 #include <llvm-c/Target.h>
34 #include <llvm-c/Transforms/IPO.h>
35@@ -43,8 +49,13 @@
36 /* Handle of a module emitted via ORC JIT */
37 typedef struct LLVMJitHandle
38 {
39+#if LLVM_VERSION_MAJOR > 11
40+ LLVMOrcLLJITRef lljit;
41+ LLVMOrcResourceTrackerRef resource_tracker;
42+#else
43 LLVMOrcJITStackRef stack;
44 LLVMOrcModuleHandle orc_handle;
45+#endif
46 } LLVMJitHandle;
47
48
49@@ -94,12 +105,15 @@ static const char *llvm_triple = NULL;
50 static const char *llvm_layout = NULL;
51
52
53-static LLVMTargetMachineRef llvm_opt0_targetmachine;
54-static LLVMTargetMachineRef llvm_opt3_targetmachine;
55-
56 static LLVMTargetRef llvm_targetref;
57+#if LLVM_VERSION_MAJOR > 11
58+static LLVMOrcThreadSafeContextRef llvm_ts_context;
59+static LLVMOrcLLJITRef llvm_opt0_orc;
60+static LLVMOrcLLJITRef llvm_opt3_orc;
61+#else /* LLVM_VERSION_MAJOR > 11 */
62 static LLVMOrcJITStackRef llvm_opt0_orc;
63 static LLVMOrcJITStackRef llvm_opt3_orc;
64+#endif /* LLVM_VERSION_MAJOR > 11 */
65
66
67 static void llvm_release_context(JitContext *context);
68@@ -111,6 +125,10 @@ static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module);
69 static void llvm_create_types(void);
70 static uint64_t llvm_resolve_symbol(const char *name, void *ctx);
71
72+#if LLVM_VERSION_MAJOR > 11
73+static LLVMOrcLLJITRef llvm_create_jit_instance(LLVMTargetMachineRef tm);
74+static char *llvm_error_message(LLVMErrorRef error);
75+#endif /* LLVM_VERSION_MAJOR > 11 */
76
77 PG_MODULE_MAGIC;
78
79@@ -170,24 +188,47 @@ llvm_release_context(JitContext *context)
80 * have occurred from within LLVM, we do not want to risk reentering. All
81 * resource cleanup is going to happen through process exit.
82 */
83- if (!proc_exit_inprogress)
84+ if (proc_exit_inprogress)
85+ return;
86+
87+ if (llvm_context->module)
88 {
89- if (llvm_context->module)
90- {
91- LLVMDisposeModule(llvm_context->module);
92- llvm_context->module = NULL;
93- }
94+ LLVMDisposeModule(llvm_context->module);
95+ llvm_context->module = NULL;
96+ }
97
98- while (llvm_context->handles != NIL)
99- {
100- LLVMJitHandle *jit_handle;
101+ while (llvm_context->handles != NIL)
102+ {
103+ LLVMJitHandle *jit_handle;
104
105- jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
106- llvm_context->handles = list_delete_first(llvm_context->handles);
107+ jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
108+ llvm_context->handles = list_delete_first(llvm_context->handles);
109
110+#if LLVM_VERSION_MAJOR > 11
111+ {
112+ LLVMOrcExecutionSessionRef ee;
113+ LLVMOrcSymbolStringPoolRef sp;
114+
115+ LLVMOrcResourceTrackerRemove(jit_handle->resource_tracker);
116+ LLVMOrcReleaseResourceTracker(jit_handle->resource_tracker);
117+
118+ /*
119+ * Without triggering cleanup of the string pool, we'd leak
120+ * memory. It'd be sufficient to do this far less often, but in
121+ * experiments the required time was small enough to just always
122+ * do it.
123+ */
124+ ee = LLVMOrcLLJITGetExecutionSession(jit_handle->lljit);
125+ sp = LLVMOrcExecutionSessionGetSymbolStringPool(ee);
126+ LLVMOrcSymbolStringPoolClearDeadEntries(sp);
127+ }
128+#else /* LLVM_VERSION_MAJOR > 11 */
129+ {
130 LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle);
131- pfree(jit_handle);
132 }
133+#endif /* LLVM_VERSION_MAJOR > 11 */
134+
135+ pfree(jit_handle);
136 }
137 }
138
139@@ -243,8 +284,8 @@ llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
140 void *
141 llvm_get_function(LLVMJitContext *context, const char *funcname)
142 {
143- LLVMOrcTargetAddress addr = 0;
144-#if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
145+#if LLVM_VERSION_MAJOR > 11 || \
146+ defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
147 ListCell *lc;
148 #endif
149
150@@ -264,9 +305,40 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
151 * to mangle here.
152 */
153
154-#if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
155+#if LLVM_VERSION_MAJOR > 11
156+ foreach(lc, context->handles)
157+ {
158+ LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
159+ instr_time starttime;
160+ instr_time endtime;
161+ LLVMErrorRef error;
162+ LLVMOrcJITTargetAddress addr;
163+
164+ INSTR_TIME_SET_CURRENT(starttime);
165+
166+ addr = 0;
167+ error = LLVMOrcLLJITLookup(handle->lljit, &addr, funcname);
168+ if (error)
169+ elog(ERROR, "failed to look up symbol \"%s\": %s",
170+ funcname, llvm_error_message(error));
171+
172+ /*
173+ * LLJIT only actually emits code the first time a symbol is
174+ * referenced. Thus add lookup time to emission time. That's counting
175+ * a bit more than with older LLVM versions, but unlikely to ever
176+ * matter.
177+ */
178+ INSTR_TIME_SET_CURRENT(endtime);
179+ INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
180+ endtime, starttime);
181+
182+ if (addr)
183+ return (void *) (uintptr_t) addr;
184+ }
185+#elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
186 foreach(lc, context->handles)
187 {
188+ LLVMOrcTargetAddress addr;
189 LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
190
191 addr = 0;
192@@ -275,26 +347,29 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
193 if (addr)
194 return (void *) (uintptr_t) addr;
195 }
196+#elif LLVM_VERSION_MAJOR < 5
197+ {
198+ LLVMOrcTargetAddress addr;
199
200+ if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
201+ return (void *) (uintptr_t) addr;
202+ if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
203+ return (void *) (uintptr_t) addr;
204+ }
205 #else
206+ {
207+ LLVMOrcTargetAddress addr;
208
209-#if LLVM_VERSION_MAJOR < 5
210- if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
211- return (void *) (uintptr_t) addr;
212- if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
213- return (void *) (uintptr_t) addr;
214-#else
215- if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
216- elog(ERROR, "failed to look up symbol \"%s\"", funcname);
217- if (addr)
218- return (void *) (uintptr_t) addr;
219- if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
220- elog(ERROR, "failed to look up symbol \"%s\"", funcname);
221- if (addr)
222- return (void *) (uintptr_t) addr;
223-#endif /* LLVM_VERSION_MAJOR */
224-
225-#endif /* HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */
226+ if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
227+ elog(ERROR, "failed to look up symbol \"%s\"", funcname);
228+ if (addr)
229+ return (void *) (uintptr_t) addr;
230+ if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
231+ elog(ERROR, "failed to look up symbol \"%s\"", funcname);
232+ if (addr)
233+ return (void *) (uintptr_t) addr;
234+ }
235+#endif
236
237 elog(ERROR, "failed to JIT: %s", funcname);
238
239@@ -425,6 +500,8 @@ llvm_function_reference(LLVMJitContext *context,
240 v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
241 LLVMSetInitializer(v_fn, v_fn_addr);
242 LLVMSetGlobalConstant(v_fn, true);
243+ LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
244+ LLVMSetUnnamedAddr(v_fn, true);
245
246 return LLVMBuildLoad(builder, v_fn, "");
247 }
248@@ -516,11 +593,15 @@ llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
249 static void
250 llvm_compile_module(LLVMJitContext *context)
251 {
252- LLVMOrcModuleHandle orc_handle;
253+ LLVMJitHandle *handle;
254 MemoryContext oldcontext;
255- static LLVMOrcJITStackRef compile_orc;
256 instr_time starttime;
257 instr_time endtime;
258+#if LLVM_VERSION_MAJOR > 11
259+ LLVMOrcLLJITRef compile_orc;
260+#else
261+ LLVMOrcJITStackRef compile_orc;
262+#endif
263
264 if (context->base.flags & PGJIT_OPT3)
265 compile_orc = llvm_opt3_orc;
266@@ -567,6 +648,9 @@ llvm_compile_module(LLVMJitContext *context)
267 pfree(filename);
268 }
269
270+ handle = (LLVMJitHandle *)
271+ MemoryContextAlloc(TopMemoryContext, sizeof(LLVMJitHandle));
272+
273 /*
274 * Emit the code. Note that this can, depending on the optimization
275 * settings, take noticeable resources as code emission executes low-level
276@@ -574,13 +658,42 @@ llvm_compile_module(LLVMJitContext *context)
277 * faster instruction selection mechanism is used.
278 */
279 INSTR_TIME_SET_CURRENT(starttime);
280-#if LLVM_VERSION_MAJOR > 6
281+#if LLVM_VERSION_MAJOR > 11
282+ {
283+ LLVMOrcThreadSafeModuleRef ts_module;
284+ LLVMErrorRef error;
285+ LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(compile_orc);
286+
287+ ts_module = LLVMOrcCreateNewThreadSafeModule(context->module, llvm_ts_context);
288+
289+ handle->lljit = compile_orc;
290+ handle->resource_tracker = LLVMOrcJITDylibCreateResourceTracker(jd);
291+
292+ /*
293+ * NB: This doesn't actually emit code. That happens lazily the first
294+ * time a symbol defined in the module is requested. Due to that
295+ * llvm_get_function() also accounts for emission time.
296+ */
297+
298+ context->module = NULL; /* will be owned by LLJIT */
299+ error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc,
300+ handle->resource_tracker,
301+ ts_module);
302+
303+ if (error)
304+ elog(ERROR, "failed to JIT module: %s",
305+ llvm_error_message(error));
306+
307+ handle->lljit = compile_orc;
308+
309+ /* LLVMOrcLLJITAddLLVMIRModuleWithRT takes ownership of the module */
310+ }
311+#elif LLVM_VERSION_MAJOR > 6
312 {
313- if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, context->module,
314+ handle->stack = compile_orc;
315+ if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, context->module,
316 llvm_resolve_symbol, NULL))
317- {
318 elog(ERROR, "failed to JIT module");
319- }
320
321 /* LLVMOrcAddEagerlyCompiledIR takes ownership of the module */
322 }
323@@ -589,20 +702,23 @@ llvm_compile_module(LLVMJitContext *context)
324 LLVMSharedModuleRef smod;
325
326 smod = LLVMOrcMakeSharedModule(context->module);
327- if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, smod,
328+ handle->stack = compile_orc;
329+ if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, smod,
330 llvm_resolve_symbol, NULL))
331- {
332 elog(ERROR, "failed to JIT module");
333- }
334+
335 LLVMOrcDisposeSharedModuleRef(smod);
336 }
337 #else /* LLVM 4.0 and 3.9 */
338 {
339- orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
340- llvm_resolve_symbol, NULL);
341+ handle->stack = compile_orc;
342+ handle->orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
343+ llvm_resolve_symbol, NULL);
344+
345 LLVMDisposeModule(context->module);
346 }
347 #endif
348+
349 INSTR_TIME_SET_CURRENT(endtime);
350 INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
351 endtime, starttime);
352@@ -612,15 +728,7 @@ llvm_compile_module(LLVMJitContext *context)
353
354 /* remember emitted code for cleanup and lookups */
355 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
356- {
357- LLVMJitHandle *handle;
358-
359- handle = (LLVMJitHandle *) palloc(sizeof(LLVMJitHandle));
360- handle->stack = compile_orc;
361- handle->orc_handle = orc_handle;
362-
363- context->handles = lappend(context->handles, handle);
364- }
365+ context->handles = lappend(context->handles, handle);
366 MemoryContextSwitchTo(oldcontext);
367
368 ereport(DEBUG1,
369@@ -642,6 +750,8 @@ llvm_session_initialize(void)
370 char *error = NULL;
371 char *cpu = NULL;
372 char *features = NULL;
373+ LLVMTargetMachineRef opt0_tm;
374+ LLVMTargetMachineRef opt3_tm;
375
376 if (llvm_session_initialized)
377 return;
378@@ -674,12 +784,12 @@ llvm_session_initialize(void)
379 elog(DEBUG2, "LLVMJIT detected CPU \"%s\", with features \"%s\"",
380 cpu, features);
381
382- llvm_opt0_targetmachine =
383+ opt0_tm =
384 LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
385 LLVMCodeGenLevelNone,
386 LLVMRelocDefault,
387 LLVMCodeModelJITDefault);
388- llvm_opt3_targetmachine =
389+ opt3_tm =
390 LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
391 LLVMCodeGenLevelAggressive,
392 LLVMRelocDefault,
393@@ -693,27 +803,41 @@ llvm_session_initialize(void)
394 /* force symbols in main binary to be loaded */
395 LLVMLoadLibraryPermanently(NULL);
396
397- llvm_opt0_orc = LLVMOrcCreateInstance(llvm_opt0_targetmachine);
398- llvm_opt3_orc = LLVMOrcCreateInstance(llvm_opt3_targetmachine);
399-
400-#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
401- if (jit_debugging_support)
402+#if LLVM_VERSION_MAJOR > 11
403 {
404- LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
405+ llvm_ts_context = LLVMOrcCreateNewThreadSafeContext();
406+
407+ llvm_opt0_orc = llvm_create_jit_instance(opt0_tm);
408+ opt0_tm = 0;
409
410- LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
411- LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
412+ llvm_opt3_orc = llvm_create_jit_instance(opt3_tm);
413+ opt3_tm = 0;
414 }
415+#else /* LLVM_VERSION_MAJOR > 11 */
416+ {
417+ llvm_opt0_orc = LLVMOrcCreateInstance(opt0_tm);
418+ llvm_opt3_orc = LLVMOrcCreateInstance(opt3_tm);
419+
420+#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
421+ if (jit_debugging_support)
422+ {
423+ LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
424+
425+ LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
426+ LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
427+ }
428 #endif
429 #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
430- if (jit_profiling_support)
431- {
432- LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
433+ if (jit_profiling_support)
434+ {
435+ LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
436
437- LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
438- LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
439- }
440+ LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
441+ LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
442+ }
443 #endif
444+ }
445+#endif /* LLVM_VERSION_MAJOR > 11 */
446
447 before_shmem_exit(llvm_shutdown, 0);
448
449@@ -725,27 +849,49 @@ llvm_session_initialize(void)
450 static void
451 llvm_shutdown(int code, Datum arg)
452 {
453- /* unregister profiling support, needs to be flushed to be useful */
454-
455- if (llvm_opt3_orc)
456+#if LLVM_VERSION_MAJOR > 11
457+ {
458+ if (llvm_opt3_orc)
459+ {
460+ LLVMOrcDisposeLLJIT(llvm_opt3_orc);
461+ llvm_opt3_orc = NULL;
462+ }
463+ if (llvm_opt0_orc)
464+ {
465+ LLVMOrcDisposeLLJIT(llvm_opt0_orc);
466+ llvm_opt0_orc = NULL;
467+ }
468+ if (llvm_ts_context)
469+ {
470+ LLVMOrcDisposeThreadSafeContext(llvm_ts_context);
471+ llvm_ts_context = NULL;
472+ }
473+ }
474+#else /* LLVM_VERSION_MAJOR > 11 */
475 {
476+ /* unregister profiling support, needs to be flushed to be useful */
477+
478+ if (llvm_opt3_orc)
479+ {
480 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
481- if (jit_profiling_support)
482- LLVMOrcUnregisterPerf(llvm_opt3_orc);
483+ if (jit_profiling_support)
484+ LLVMOrcUnregisterPerf(llvm_opt3_orc);
485 #endif
486- LLVMOrcDisposeInstance(llvm_opt3_orc);
487- llvm_opt3_orc = NULL;
488- }
489+ LLVMOrcDisposeInstance(llvm_opt3_orc);
490+ llvm_opt3_orc = NULL;
491+ }
492
493- if (llvm_opt0_orc)
494- {
495+ if (llvm_opt0_orc)
496+ {
497 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
498- if (jit_profiling_support)
499- LLVMOrcUnregisterPerf(llvm_opt0_orc);
500+ if (jit_profiling_support)
501+ LLVMOrcUnregisterPerf(llvm_opt0_orc);
502 #endif
503- LLVMOrcDisposeInstance(llvm_opt0_orc);
504- llvm_opt0_orc = NULL;
505+ LLVMOrcDisposeInstance(llvm_opt0_orc);
506+ llvm_opt0_orc = NULL;
507+ }
508 }
509+#endif /* LLVM_VERSION_MAJOR > 11 */
510 }
511
512 /* helper for llvm_create_types, returning a global var's type */
513@@ -941,3 +1087,145 @@ llvm_resolve_symbol(const char *symname, void *ctx)
514
515 return (uint64_t) addr;
516 }
517+
518+#if LLVM_VERSION_MAJOR > 11
519+
520+static LLVMErrorRef
521+llvm_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx,
522+ LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind,
523+ LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags,
524+ LLVMOrcCLookupSet LookupSet, size_t LookupSetSize)
525+{
526+ LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMJITCSymbolMapPair) * LookupSetSize);
527+ LLVMErrorRef error;
528+ LLVMOrcMaterializationUnitRef mu;
529+
530+ for (int i = 0; i < LookupSetSize; i++)
531+ {
532+ const char *name = LLVMOrcSymbolStringPoolEntryStr(LookupSet[i].Name);
533+
534+ symbols[i].Name = LookupSet[i].Name;
535+ symbols[i].Sym.Address = llvm_resolve_symbol(name, NULL);
536+ symbols[i].Sym.Flags.GenericFlags = LLVMJITSymbolGenericFlagsExported;
537+ }
538+
539+ mu = LLVMOrcAbsoluteSymbols(symbols, LookupSetSize);
540+ error = LLVMOrcJITDylibDefine(JD, mu);
541+ if (error != LLVMErrorSuccess)
542+ LLVMOrcDisposeMaterializationUnit(mu);
543+
544+ pfree(symbols);
545+
546+ return error;
547+}
548+
549+/*
550+ * We cannot throw errors through LLVM (without causing a FATAL at least), so
551+ * just use WARNING here. That's OK anyway, as the error is also reported at
552+ * the top level action (with less detail) and there might be multiple
553+ * invocations of errors with details.
554+ *
555+ * This doesn't really happen during normal operation, but in cases like
556+ * symbol resolution breakage. So just using elog(WARNING) is fine.
557+ */
558+static void
559+llvm_log_jit_error(void *ctx, LLVMErrorRef error)
560+{
561+ elog(WARNING, "error during JITing: %s",
562+ llvm_error_message(error));
563+}
564+
565+/*
566+ * Create our own object layer, so we can add event listeners.
567+ */
568+static LLVMOrcObjectLayerRef
569+llvm_create_object_layer(void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple)
570+{
571+ LLVMOrcObjectLayerRef objlayer =
572+ LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(ES);
573+
574+#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
575+ if (jit_debugging_support)
576+ {
577+ LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
578+
579+ LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
580+ }
581+#endif
582+
583+#if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
584+ if (jit_profiling_support)
585+ {
586+ LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
587+
588+ LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
589+ }
590+#endif
591+
592+ return objlayer;
593+}
594+
595+/*
596+ * Create LLJIT instance, using the passed in target machine. Note that the
597+ * target machine afterwards is owned by the LLJIT instance.
598+ */
599+static LLVMOrcLLJITRef
600+llvm_create_jit_instance(LLVMTargetMachineRef tm)
601+{
602+ LLVMOrcLLJITRef lljit;
603+ LLVMOrcJITTargetMachineBuilderRef tm_builder;
604+ LLVMOrcLLJITBuilderRef lljit_builder;
605+ LLVMErrorRef error;
606+ LLVMOrcDefinitionGeneratorRef main_gen;
607+ LLVMOrcDefinitionGeneratorRef ref_gen;
608+
609+ lljit_builder = LLVMOrcCreateLLJITBuilder();
610+ tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(tm);
611+ LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(lljit_builder, tm_builder);
612+
613+ LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(lljit_builder,
614+ llvm_create_object_layer,
615+ NULL);
616+
617+ error = LLVMOrcCreateLLJIT(&lljit, lljit_builder);
618+ if (error)
619+ elog(ERROR, "failed to create lljit instance: %s",
620+ llvm_error_message(error));
621+
622+ LLVMOrcExecutionSessionSetErrorReporter(LLVMOrcLLJITGetExecutionSession(lljit),
623+ llvm_log_jit_error, NULL);
624+
625+ /*
626+ * Symbol resolution support for symbols in the postgres binary /
627+ * libraries already loaded.
628+ */
629+ error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(&main_gen,
630+ LLVMOrcLLJITGetGlobalPrefix(lljit),
631+ 0, NULL);
632+ if (error)
633+ elog(ERROR, "failed to create generator: %s",
634+ llvm_error_message(error));
635+ LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), main_gen);
636+
637+ /*
638+ * Symbol resolution support for "special" functions, e.g. a call into an
639+ * SQL callable function.
640+ */
641+ ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL);
642+ LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), ref_gen);
643+
644+ return lljit;
645+}
646+
647+static char *
648+llvm_error_message(LLVMErrorRef error)
649+{
650+ char *orig = LLVMGetErrorMessage(error);
651+ char *msg = pstrdup(orig);
652+
653+ LLVMDisposeErrorMessage(orig);
654+
655+ return msg;
656+}
657+
658+#endif /* LLVM_VERSION_MAJOR > 11 */
659diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
660index bbe62ab90b..a49e779fcf 100644
661--- a/src/tools/pgindent/typedefs.list
662+++ b/src/tools/pgindent/typedefs.list
663@@ -1133,6 +1133,7 @@ LLVMJitHandle
664 LLVMMemoryBufferRef
665 LLVMModuleRef
666 LLVMOrcJITStackRef
667+LLVMOrcLookupStateRef
668 LLVMOrcModuleHandle
669 LLVMOrcTargetAddress
670 LLVMPassManagerBuilderRef
671--
6722.29.2
673
This page took 0.135077 seconds and 4 git commands to generate.