]> granicus.if.org Git - postgresql/blob - src/backend/jit/llvm/llvmjit.c
LLVMJIT: Free created module in LLVM < 5.
[postgresql] / src / backend / jit / llvm / llvmjit.c
1 /*-------------------------------------------------------------------------
2  *
3  * llvmjit.c
4  *        Core part of the LLVM JIT provider.
5  *
6  * Copyright (c) 2016-2018, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *        src/backend/jit/llvm/llvmjit.c
10  *
11  *-------------------------------------------------------------------------
12  */
13
14 #include "postgres.h"
15
16 #include "jit/llvmjit.h"
17 #include "jit/llvmjit_emit.h"
18
19 #include "miscadmin.h"
20
21 #include "utils/memutils.h"
22 #include "utils/resowner_private.h"
23 #include "portability/instr_time.h"
24 #include "storage/ipc.h"
25
26
27 #include <llvm-c/Analysis.h>
28 #include <llvm-c/BitReader.h>
29 #include <llvm-c/BitWriter.h>
30 #include <llvm-c/Core.h>
31 #include <llvm-c/OrcBindings.h>
32 #include <llvm-c/Support.h>
33 #include <llvm-c/Target.h>
34 #include <llvm-c/Transforms/IPO.h>
35 #include <llvm-c/Transforms/PassManagerBuilder.h>
36 #include <llvm-c/Transforms/Scalar.h>
37
38
39 /* Handle of a module emitted via ORC JIT */
40 typedef struct LLVMJitHandle
41 {
42         LLVMOrcJITStackRef stack;
43         LLVMOrcModuleHandle orc_handle;
44 } LLVMJitHandle;
45
46
47 /* types & functions commonly needed for JITing */
48 LLVMTypeRef TypeSizeT;
49 LLVMTypeRef TypeParamBool;
50 LLVMTypeRef TypeStorageBool;
51 LLVMTypeRef TypePGFunction;
52 LLVMTypeRef StructHeapTupleFieldsField3;
53 LLVMTypeRef StructHeapTupleFields;
54 LLVMTypeRef StructHeapTupleHeaderData;
55 LLVMTypeRef StructHeapTupleDataChoice;
56 LLVMTypeRef StructHeapTupleData;
57 LLVMTypeRef StructMinimalTupleData;
58 LLVMTypeRef StructItemPointerData;
59 LLVMTypeRef StructBlockId;
60 LLVMTypeRef StructFormPgAttribute;
61 LLVMTypeRef StructTupleConstr;
62 LLVMTypeRef StructtupleDesc;
63 LLVMTypeRef StructTupleTableSlot;
64 LLVMTypeRef StructMemoryContextData;
65 LLVMTypeRef StructPGFinfoRecord;
66 LLVMTypeRef StructFmgrInfo;
67 LLVMTypeRef StructFunctionCallInfoData;
68 LLVMTypeRef StructExprContext;
69 LLVMTypeRef StructExprEvalStep;
70 LLVMTypeRef StructExprState;
71 LLVMTypeRef StructAggState;
72 LLVMTypeRef StructAggStatePerGroupData;
73 LLVMTypeRef StructAggStatePerTransData;
74
75 LLVMValueRef AttributeTemplate;
76 LLVMValueRef FuncStrlen;
77 LLVMValueRef FuncVarsizeAny;
78 LLVMValueRef FuncSlotGetsomeattrs;
79 LLVMValueRef FuncHeapGetsysattr;
80 LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
81 LLVMValueRef FuncExecEvalArrayRefSubscript;
82 LLVMValueRef FuncExecAggTransReparent;
83 LLVMValueRef FuncExecAggInitGroup;
84
85
86 static bool llvm_session_initialized = false;
87 static size_t llvm_generation = 0;
88 static const char *llvm_triple = NULL;
89 static const char *llvm_layout = NULL;
90
91
92 static LLVMTargetMachineRef llvm_opt0_targetmachine;
93 static LLVMTargetMachineRef llvm_opt3_targetmachine;
94
95 static LLVMTargetRef llvm_targetref;
96 static LLVMOrcJITStackRef llvm_opt0_orc;
97 static LLVMOrcJITStackRef llvm_opt3_orc;
98
99
100 static void llvm_release_context(JitContext *context);
101 static void llvm_session_initialize(void);
102 static void llvm_shutdown(int code, Datum arg);
103 static void llvm_compile_module(LLVMJitContext *context);
104 static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module);
105
106 static void llvm_create_types(void);
107 static uint64_t llvm_resolve_symbol(const char *name, void *ctx);
108
109
110 PG_MODULE_MAGIC;
111
112
113 /*
114  * Initialize LLVM JIT provider.
115  */
116 void
117 _PG_jit_provider_init(JitProviderCallbacks *cb)
118 {
119         cb->reset_after_error = llvm_reset_after_error;
120         cb->release_context = llvm_release_context;
121         cb->compile_expr = llvm_compile_expr;
122 }
123
124 /*
125  * Create a context for JITing work.
126  *
127  * The context, including subsidiary resources, will be cleaned up either when
128  * the context is explicitly released, or when the lifetime of
129  * CurrentResourceOwner ends (usually the end of the current [sub]xact).
130  */
131 LLVMJitContext *
132 llvm_create_context(int jitFlags)
133 {
134         LLVMJitContext *context;
135
136         llvm_assert_in_fatal_section();
137
138         llvm_session_initialize();
139
140         ResourceOwnerEnlargeJIT(CurrentResourceOwner);
141
142         context = MemoryContextAllocZero(TopMemoryContext,
143                                                                          sizeof(LLVMJitContext));
144         context->base.flags = jitFlags;
145
146         /* ensure cleanup */
147         context->base.resowner = CurrentResourceOwner;
148         ResourceOwnerRememberJIT(CurrentResourceOwner, PointerGetDatum(context));
149
150         return context;
151 }
152
153 /*
154  * Release resources required by one llvm context.
155  */
156 static void
157 llvm_release_context(JitContext *context)
158 {
159         LLVMJitContext *llvm_context = (LLVMJitContext *) context;
160
161         llvm_enter_fatal_on_oom();
162
163         /*
164          * When this backend is exiting, don't clean up LLVM. As an error might
165          * have occurred from within LLVM, we do not want to risk reentering. All
166          * resource cleanup is going to happen through process exit.
167          */
168         if (!proc_exit_inprogress)
169         {
170                 if (llvm_context->module)
171                 {
172                         LLVMDisposeModule(llvm_context->module);
173                         llvm_context->module = NULL;
174                 }
175
176                 while (llvm_context->handles != NIL)
177                 {
178                         LLVMJitHandle *jit_handle;
179
180                         jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
181                         llvm_context->handles = list_delete_first(llvm_context->handles);
182
183                         LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle);
184                         pfree(jit_handle);
185                 }
186         }
187 }
188
189 /*
190  * Return module which may be modified, e.g. by creating new functions.
191  */
192 LLVMModuleRef
193 llvm_mutable_module(LLVMJitContext *context)
194 {
195         llvm_assert_in_fatal_section();
196
197         /*
198          * If there's no in-progress module, create a new one.
199          */
200         if (!context->module)
201         {
202                 context->compiled = false;
203                 context->module_generation = llvm_generation++;
204                 context->module = LLVMModuleCreateWithName("pg");
205                 LLVMSetTarget(context->module, llvm_triple);
206                 LLVMSetDataLayout(context->module, llvm_layout);
207         }
208
209         return context->module;
210 }
211
212 /*
213  * Expand function name to be non-conflicting. This should be used by code
214  * generating code, when adding new externally visible function definitions to
215  * a Module.
216  */
217 char *
218 llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
219 {
220         Assert(context->module != NULL);
221
222         context->base.created_functions++;
223
224         /*
225          * Previously we used dots to separate, but turns out some tools, e.g.
226          * GDB, don't like that and truncate name.
227          */
228         return psprintf("%s_%zu_%d",
229                                         basename,
230                                         context->module_generation,
231                                         context->counter++);
232 }
233
234 /*
235  * Return pointer to function funcname, which has to exist. If there's pending
236  * code to be optimized and emitted, do so first.
237  */
238 void *
239 llvm_get_function(LLVMJitContext *context, const char *funcname)
240 {
241         LLVMOrcTargetAddress addr = 0;
242 #if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
243         ListCell   *lc;
244 #endif
245
246         llvm_assert_in_fatal_section();
247
248         /*
249          * If there is a pending / not emitted module, compile and emit now.
250          * Otherwise we might not find the [correct] function.
251          */
252         if (!context->compiled)
253         {
254                 llvm_compile_module(context);
255         }
256
257         /*
258          * ORC's symbol table is of *unmangled* symbols. Therefore we don't need
259          * to mangle here.
260          */
261
262 #if defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
263         foreach(lc, context->handles)
264         {
265                 LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
266
267                 addr = 0;
268                 if (LLVMOrcGetSymbolAddressIn(handle->stack, &addr, handle->orc_handle, funcname))
269                         elog(ERROR, "failed to look up symbol \"%s\"", funcname);
270                 if (addr)
271                         return (void *) (uintptr_t) addr;
272         }
273
274 #else
275
276 #if LLVM_VERSION_MAJOR < 5
277         if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
278                 return (void *) (uintptr_t) addr;
279         if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
280                 return (void *) (uintptr_t) addr;
281 #else
282         if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
283                 elog(ERROR, "failed to look up symbol \"%s\"", funcname);
284         if (addr)
285                 return (void *) (uintptr_t) addr;
286         if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
287                 elog(ERROR, "failed to look up symbol \"%s\"", funcname);
288         if (addr)
289                 return (void *) (uintptr_t) addr;
290 #endif                                                  /* LLVM_VERSION_MAJOR */
291
292 #endif                                                  /* HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */
293
294         elog(ERROR, "failed to JIT: %s", funcname);
295
296         return NULL;
297 }
298
299 /*
300  * Return declaration for passed function, adding it to the module if
301  * necessary.
302  *
303  * This is used to make functions imported by llvm_create_types() known to the
304  * module that's currently being worked on.
305  */
306 LLVMValueRef
307 llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src)
308 {
309         LLVMValueRef v_fn;
310
311         /* don't repeatedly add function */
312         v_fn = LLVMGetNamedFunction(mod, LLVMGetValueName(v_src));
313         if (v_fn)
314                 return v_fn;
315
316         v_fn = LLVMAddFunction(mod,
317                                                    LLVMGetValueName(v_src),
318                                                    LLVMGetElementType(LLVMTypeOf(v_src)));
319         llvm_copy_attributes(v_src, v_fn);
320
321         return v_fn;
322 }
323
324 /*
325  * Copy attributes from one function to another.
326  */
327 void
328 llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
329 {
330         int                     num_attributes;
331         int                     attno;
332         LLVMAttributeRef *attrs;
333
334         num_attributes =
335                 LLVMGetAttributeCountAtIndex(v_from, LLVMAttributeFunctionIndex);
336
337         attrs = palloc(sizeof(LLVMAttributeRef) * num_attributes);
338         LLVMGetAttributesAtIndex(v_from, LLVMAttributeFunctionIndex, attrs);
339
340         for (attno = 0; attno < num_attributes; attno++)
341         {
342                 LLVMAddAttributeAtIndex(v_to, LLVMAttributeFunctionIndex,
343                                                                 attrs[attno]);
344         }
345 }
346
347 /*
348  * Return a callable LLVMValueRef for fcinfo.
349  */
350 LLVMValueRef
351 llvm_function_reference(LLVMJitContext *context,
352                                                 LLVMBuilderRef builder,
353                                                 LLVMModuleRef mod,
354                                                 FunctionCallInfo fcinfo)
355 {
356         char       *modname;
357         char       *basename;
358         char       *funcname;
359
360         LLVMValueRef v_fn;
361
362         fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename);
363
364         if (modname != NULL && basename != NULL)
365         {
366                 /* external function in loadable library */
367                 funcname = psprintf("pgextern.%s.%s", modname, basename);
368         }
369         else if (basename != NULL)
370         {
371                 /* internal function */
372                 funcname = psprintf("%s", basename);
373         }
374         else
375         {
376                 /*
377                  * Function we don't know to handle, return pointer. We do so by
378                  * creating a global constant containing a pointer to the function.
379                  * Makes IR more readable.
380                  */
381                 LLVMValueRef v_fn_addr;
382
383                 funcname = psprintf("pgoidextern.%u",
384                                                         fcinfo->flinfo->fn_oid);
385                 v_fn = LLVMGetNamedGlobal(mod, funcname);
386                 if (v_fn != 0)
387                         return LLVMBuildLoad(builder, v_fn, "");
388
389                 v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
390
391                 v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
392                 LLVMSetInitializer(v_fn, v_fn_addr);
393                 LLVMSetGlobalConstant(v_fn, true);
394
395                 return LLVMBuildLoad(builder, v_fn, "");
396                 return v_fn;
397         }
398
399         /* check if function already has been added */
400         v_fn = LLVMGetNamedFunction(mod, funcname);
401         if (v_fn != 0)
402                 return v_fn;
403
404         v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction));
405
406         return v_fn;
407 }
408
409 /*
410  * Optimize code in module using the flags set in context.
411  */
412 static void
413 llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
414 {
415         LLVMPassManagerBuilderRef llvm_pmb;
416         LLVMPassManagerRef llvm_mpm;
417         LLVMPassManagerRef llvm_fpm;
418         LLVMValueRef func;
419         int                     compile_optlevel;
420
421         if (context->base.flags & PGJIT_OPT3)
422                 compile_optlevel = 3;
423         else
424                 compile_optlevel = 0;
425
426         /*
427          * Have to create a new pass manager builder every pass through, as the
428          * inliner has some per-builder state. Otherwise one ends up only inlining
429          * a function the first time though.
430          */
431         llvm_pmb = LLVMPassManagerBuilderCreate();
432         LLVMPassManagerBuilderSetOptLevel(llvm_pmb, compile_optlevel);
433         llvm_fpm = LLVMCreateFunctionPassManagerForModule(module);
434
435         if (context->base.flags & PGJIT_OPT3)
436         {
437                 /* TODO: Unscientifically determined threshhold */
438                 LLVMPassManagerBuilderUseInlinerWithThreshold(llvm_pmb, 512);
439         }
440         else
441         {
442                 /* we rely on mem2reg heavily, so emit even in the O0 case */
443                 LLVMAddPromoteMemoryToRegisterPass(llvm_fpm);
444         }
445
446         LLVMPassManagerBuilderPopulateFunctionPassManager(llvm_pmb, llvm_fpm);
447
448         /*
449          * Do function level optimization. This could be moved to the point where
450          * functions are emitted, to reduce memory usage a bit.
451          */
452         LLVMInitializeFunctionPassManager(llvm_fpm);
453         for (func = LLVMGetFirstFunction(context->module);
454                  func != NULL;
455                  func = LLVMGetNextFunction(func))
456                 LLVMRunFunctionPassManager(llvm_fpm, func);
457         LLVMFinalizeFunctionPassManager(llvm_fpm);
458         LLVMDisposePassManager(llvm_fpm);
459
460         /*
461          * Perform module level optimization. We do so even in the non-optimized
462          * case, so always-inline functions etc get inlined. It's cheap enough.
463          */
464         llvm_mpm = LLVMCreatePassManager();
465         LLVMPassManagerBuilderPopulateModulePassManager(llvm_pmb,
466                                                                                                         llvm_mpm);
467         /* always use always-inliner pass */
468         if (!(context->base.flags & PGJIT_OPT3))
469                 LLVMAddAlwaysInlinerPass(llvm_mpm);
470         LLVMRunPassManager(llvm_mpm, context->module);
471         LLVMDisposePassManager(llvm_mpm);
472
473         LLVMPassManagerBuilderDispose(llvm_pmb);
474 }
475
476 /*
477  * Emit code for the currently pending module.
478  */
479 static void
480 llvm_compile_module(LLVMJitContext *context)
481 {
482         LLVMOrcModuleHandle orc_handle;
483         MemoryContext oldcontext;
484         static LLVMOrcJITStackRef compile_orc;
485         instr_time      starttime;
486         instr_time      endtime;
487
488         if (context->base.flags & PGJIT_OPT3)
489                 compile_orc = llvm_opt3_orc;
490         else
491                 compile_orc = llvm_opt0_orc;
492
493         if (jit_dump_bitcode)
494         {
495                 char       *filename;
496
497                 filename = psprintf("%u.%zu.bc",
498                                                         MyProcPid,
499                                                         context->module_generation);
500                 LLVMWriteBitcodeToFile(context->module, filename);
501                 pfree(filename);
502         }
503
504
505         /* optimize according to the chosen optimization settings */
506         INSTR_TIME_SET_CURRENT(starttime);
507         llvm_optimize_module(context, context->module);
508         INSTR_TIME_SET_CURRENT(endtime);
509         INSTR_TIME_ACCUM_DIFF(context->base.optimization_counter,
510                                                   endtime, starttime);
511
512         if (jit_dump_bitcode)
513         {
514                 char       *filename;
515
516                 filename = psprintf("%u.%zu.optimized.bc",
517                                                         MyProcPid,
518                                                         context->module_generation);
519                 LLVMWriteBitcodeToFile(context->module, filename);
520                 pfree(filename);
521         }
522
523         /*
524          * Emit the code. Note that this can, depending on the optimization
525          * settings, take noticeable resources as code emission executes low-level
526          * instruction combining/selection passes etc. Without optimization a
527          * faster instruction selection mechanism is used.
528          */
529         INSTR_TIME_SET_CURRENT(starttime);
530 #if LLVM_VERSION_MAJOR < 5
531         {
532                 orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
533                                                                                                  llvm_resolve_symbol, NULL);
534                 LLVMDisposeModule(context->module);
535         }
536 #else
537         {
538                 LLVMSharedModuleRef smod;
539
540                 smod = LLVMOrcMakeSharedModule(context->module);
541                 if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &orc_handle, smod,
542                                                                                 llvm_resolve_symbol, NULL))
543                 {
544                         elog(ERROR, "failed to JIT module");
545                 }
546                 LLVMOrcDisposeSharedModuleRef(smod);
547         }
548 #endif
549         INSTR_TIME_SET_CURRENT(endtime);
550         INSTR_TIME_ACCUM_DIFF(context->base.emission_counter,
551                                                   endtime, starttime);
552
553         context->module = NULL;
554         context->compiled = true;
555
556         /* remember emitted code for cleanup and lookups */
557         oldcontext = MemoryContextSwitchTo(TopMemoryContext);
558         {
559                 LLVMJitHandle *handle;
560
561                 handle = (LLVMJitHandle *) palloc(sizeof(LLVMJitHandle));
562                 handle->stack = compile_orc;
563                 handle->orc_handle = orc_handle;
564
565                 context->handles = lappend(context->handles, handle);
566         }
567         MemoryContextSwitchTo(oldcontext);
568
569         ereport(DEBUG1,
570                         (errmsg("time to opt: %.3fs, emit: %.3fs",
571                                         INSTR_TIME_GET_DOUBLE(context->base.optimization_counter),
572                                         INSTR_TIME_GET_DOUBLE(context->base.emission_counter)),
573                          errhidestmt(true),
574                          errhidecontext(true)));
575 }
576
577 /*
578  * Per session initialization.
579  */
580 static void
581 llvm_session_initialize(void)
582 {
583         MemoryContext oldcontext;
584         char       *error = NULL;
585         char       *cpu = NULL;
586         char       *features = NULL;
587
588         if (llvm_session_initialized)
589                 return;
590
591         oldcontext = MemoryContextSwitchTo(TopMemoryContext);
592
593         LLVMInitializeNativeTarget();
594         LLVMInitializeNativeAsmPrinter();
595         LLVMInitializeNativeAsmParser();
596
597         /*
598          * Synchronize types early, as that also includes inferring the target
599          * triple.
600          */
601         llvm_create_types();
602
603         if (LLVMGetTargetFromTriple(llvm_triple, &llvm_targetref, &error) != 0)
604         {
605                 elog(FATAL, "failed to query triple %s\n", error);
606         }
607
608         /*
609          * We want the generated code to use all available features. Therefore
610          * grab the host CPU string and detect features of the current CPU. The
611          * latter is needed because some CPU architectures default to enabling
612          * features not all CPUs have (weird, huh).
613          */
614         cpu = LLVMGetHostCPUName();
615         features = LLVMGetHostCPUFeatures();
616         elog(DEBUG2, "LLVMJIT detected CPU \"%s\", with features \"%s\"",
617                  cpu, features);
618
619         llvm_opt0_targetmachine =
620                 LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
621                                                                 LLVMCodeGenLevelNone,
622                                                                 LLVMRelocDefault,
623                                                                 LLVMCodeModelJITDefault);
624         llvm_opt3_targetmachine =
625                 LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
626                                                                 LLVMCodeGenLevelAggressive,
627                                                                 LLVMRelocDefault,
628                                                                 LLVMCodeModelJITDefault);
629
630         LLVMDisposeMessage(cpu);
631         cpu = NULL;
632         LLVMDisposeMessage(features);
633         features = NULL;
634
635         /* force symbols in main binary to be loaded */
636         LLVMLoadLibraryPermanently(NULL);
637
638         llvm_opt0_orc = LLVMOrcCreateInstance(llvm_opt0_targetmachine);
639         llvm_opt3_orc = LLVMOrcCreateInstance(llvm_opt3_targetmachine);
640
641 #if defined(HAVE_DECL_LLVMORCREGISTERGDB) && HAVE_DECL_LLVMORCREGISTERGDB
642         if (jit_debugging_support)
643         {
644                 LLVMOrcRegisterGDB(llvm_opt0_orc);
645                 LLVMOrcRegisterGDB(llvm_opt3_orc);
646         }
647 #endif
648 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
649         if (jit_profiling_support)
650         {
651                 LLVMOrcRegisterPerf(llvm_opt0_orc);
652                 LLVMOrcRegisterPerf(llvm_opt3_orc);
653         }
654 #endif
655
656         before_shmem_exit(llvm_shutdown, 0);
657
658         llvm_session_initialized = true;
659
660         MemoryContextSwitchTo(oldcontext);
661 }
662
663 static void
664 llvm_shutdown(int code, Datum arg)
665 {
666         /* unregister profiling support, needs to be flushed to be useful */
667
668         if (llvm_opt3_orc)
669         {
670 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
671                 if (jit_profiling_support)
672                         LLVMOrcUnregisterPerf(llvm_opt3_orc);
673 #endif
674                 LLVMOrcDisposeInstance(llvm_opt3_orc);
675                 llvm_opt3_orc = NULL;
676         }
677
678         if (llvm_opt0_orc)
679         {
680 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
681                 if (jit_profiling_support)
682                         LLVMOrcUnregisterPerf(llvm_opt0_orc);
683 #endif
684                 LLVMOrcDisposeInstance(llvm_opt0_orc);
685                 llvm_opt0_orc = NULL;
686         }
687 }
688
689 /* helper for llvm_create_types, returning a global var's type */
690 static LLVMTypeRef
691 load_type(LLVMModuleRef mod, const char *name)
692 {
693         LLVMValueRef value;
694         LLVMTypeRef typ;
695
696         /* this'll return a *pointer* to the global */
697         value = LLVMGetNamedGlobal(mod, name);
698         if (!value)
699                 elog(ERROR, "type %s is unknown", name);
700
701         /* therefore look at the contained type and return that */
702         typ = LLVMTypeOf(value);
703         Assert(typ != NULL);
704         typ = LLVMGetElementType(typ);
705         Assert(typ != NULL);
706         return typ;
707 }
708
709 /* helper for llvm_create_types, returning a function's return type */
710 static LLVMTypeRef
711 load_return_type(LLVMModuleRef mod, const char *name)
712 {
713         LLVMValueRef value;
714         LLVMTypeRef typ;
715
716         /* this'll return a *pointer* to the function */
717         value = LLVMGetNamedFunction(mod, name);
718         if (!value)
719                 elog(ERROR, "function %s is unknown", name);
720
721         /* get type of function pointer */
722         typ = LLVMTypeOf(value);
723         Assert(typ != NULL);
724         /* dereference pointer */
725         typ = LLVMGetElementType(typ);
726         Assert(typ != NULL);
727         /* and look at return type */
728         typ = LLVMGetReturnType(typ);
729         Assert(typ != NULL);
730
731         return typ;
732 }
733
734 /*
735  * Load required information, types, function signatures from llvmjit_types.c
736  * and make them available in global variables.
737  *
738  * Those global variables are then used while emitting code.
739  */
740 static void
741 llvm_create_types(void)
742 {
743         char            path[MAXPGPATH];
744         LLVMMemoryBufferRef buf;
745         char       *msg;
746         LLVMModuleRef mod = NULL;
747
748         snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
749
750         /* open file */
751         if (LLVMCreateMemoryBufferWithContentsOfFile(path, &buf, &msg))
752         {
753                 elog(ERROR, "LLVMCreateMemoryBufferWithContentsOfFile(%s) failed: %s",
754                          path, msg);
755         }
756
757         /* eagerly load contents, going to need it all */
758         if (LLVMParseBitcode2(buf, &mod))
759         {
760                 elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
761         }
762         LLVMDisposeMemoryBuffer(buf);
763
764         /*
765          * Load triple & layout from clang emitted file so we're guaranteed to be
766          * compatible.
767          */
768         llvm_triple = pstrdup(LLVMGetTarget(mod));
769         llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod));
770
771         TypeSizeT = load_type(mod, "TypeSizeT");
772         TypeParamBool = load_return_type(mod, "FunctionReturningBool");
773         TypeStorageBool = load_type(mod, "TypeStorageBool");
774         TypePGFunction = load_type(mod, "TypePGFunction");
775         StructExprContext = load_type(mod, "StructExprContext");
776         StructExprEvalStep = load_type(mod, "StructExprEvalStep");
777         StructExprState = load_type(mod, "StructExprState");
778         StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData");
779         StructMemoryContextData = load_type(mod, "StructMemoryContextData");
780         StructTupleTableSlot = load_type(mod, "StructTupleTableSlot");
781         StructHeapTupleData = load_type(mod, "StructHeapTupleData");
782         StructtupleDesc = load_type(mod, "StructtupleDesc");
783         StructAggState = load_type(mod, "StructAggState");
784         StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData");
785         StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData");
786
787         AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate");
788         FuncStrlen = LLVMGetNamedFunction(mod, "strlen");
789         FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
790         FuncSlotGetsomeattrs = LLVMGetNamedFunction(mod, "slot_getsomeattrs");
791         FuncHeapGetsysattr = LLVMGetNamedFunction(mod, "heap_getsysattr");
792         FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
793         FuncExecEvalArrayRefSubscript = LLVMGetNamedFunction(mod, "ExecEvalArrayRefSubscript");
794         FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent");
795         FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup");
796
797         /*
798          * Leave the module alive, otherwise references to function would be
799          * dangling.
800          */
801
802         return;
803 }
804
805 /*
806  * Split a symbol into module / function parts.  If the function is in the
807  * main binary (or an external library) *modname will be NULL.
808  */
809 void
810 llvm_split_symbol_name(const char *name, char **modname, char **funcname)
811 {
812         *modname = NULL;
813         *funcname = NULL;
814
815         /*
816          * Module function names are pgextern.$module.$funcname
817          */
818         if (strncmp(name, "pgextern.", strlen("pgextern.")) == 0)
819         {
820                 /*
821                  * Symbol names cannot contain a ., therefore we can split based on
822                  * first and last occurance of one.
823                  */
824                 *funcname = rindex(name, '.');
825                 (*funcname)++;                  /* jump over . */
826
827                 *modname = pnstrdup(name + strlen("pgextern."),
828                                                         *funcname - name - strlen("pgextern.") - 1);
829                 Assert(funcname);
830
831                 *funcname = pstrdup(*funcname);
832         }
833         else
834         {
835                 *modname = NULL;
836                 *funcname = pstrdup(name);
837         }
838 }
839
840 /*
841  * Attempt to resolve symbol, so LLVM can emit a reference to it.
842  */
843 static uint64_t
844 llvm_resolve_symbol(const char *symname, void *ctx)
845 {
846         uintptr_t       addr;
847         char       *funcname;
848         char       *modname;
849
850         /*
851          * macOS prefixes all object level symbols with an underscore. But neither
852          * dlsym() nor PG's inliner expect that. So undo.
853          */
854 #if defined(__darwin__)
855         if (symname[0] != '_')
856                 elog(ERROR, "expected prefixed symbol name, but got \"%s\"", symname);
857         symname++;
858 #endif
859
860         llvm_split_symbol_name(symname, &modname, &funcname);
861
862         /* functions that aren't resolved to names shouldn't ever get here */
863         Assert(funcname);
864
865         if (modname)
866                 addr = (uintptr_t) load_external_function(modname, funcname,
867                                                                                                   true, NULL);
868         else
869                 addr = (uintptr_t) LLVMSearchForAddressOfSymbol(symname);
870
871         pfree(funcname);
872         if (modname)
873                 pfree(modname);
874
875         /* let LLVM will error out - should never happen */
876         if (!addr)
877                 elog(WARNING, "failed to resolve name %s", symname);
878
879         return (uint64_t) addr;
880 }