PostgreSQL Source Code  git master
llvmjit.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * llvmjit.c
4  * Core part of the LLVM JIT provider.
5  *
6  * Copyright (c) 2016-2020, 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 <llvm-c/Analysis.h>
17 #include <llvm-c/BitReader.h>
18 #include <llvm-c/BitWriter.h>
19 #include <llvm-c/Core.h>
20 #include <llvm-c/ExecutionEngine.h>
21 #if LLVM_VERSION_MAJOR > 11
22 #include <llvm-c/Orc.h>
23 #include <llvm-c/OrcEE.h>
24 #include <llvm-c/LLJIT.h>
25 #else
26 #include <llvm-c/OrcBindings.h>
27 #endif
28 #include <llvm-c/Support.h>
29 #include <llvm-c/Target.h>
30 #include <llvm-c/Transforms/IPO.h>
31 #include <llvm-c/Transforms/PassManagerBuilder.h>
32 #include <llvm-c/Transforms/Scalar.h>
33 #if LLVM_VERSION_MAJOR > 6
34 #include <llvm-c/Transforms/Utils.h>
35 #endif
36 
37 #include "jit/llvmjit.h"
38 #include "jit/llvmjit_emit.h"
39 #include "miscadmin.h"
40 #include "portability/instr_time.h"
41 #include "storage/ipc.h"
42 #include "utils/memutils.h"
43 #include "utils/resowner_private.h"
44 
45 /* Handle of a module emitted via ORC JIT */
46 typedef struct LLVMJitHandle
47 {
48 #if LLVM_VERSION_MAJOR > 11
49  LLVMOrcLLJITRef lljit;
50  LLVMOrcResourceTrackerRef resource_tracker;
51 #else
52  LLVMOrcJITStackRef stack;
53  LLVMOrcModuleHandle orc_handle;
54 #endif
56 
57 
58 /* types & functions commonly needed for JITing */
59 LLVMTypeRef TypeSizeT;
60 LLVMTypeRef TypeParamBool;
61 LLVMTypeRef TypeStorageBool;
62 LLVMTypeRef TypePGFunction;
63 LLVMTypeRef StructNullableDatum;
68 LLVMTypeRef StructHeapTupleData;
71 LLVMTypeRef StructBlockId;
73 LLVMTypeRef StructTupleConstr;
74 LLVMTypeRef StructTupleDescData;
79 LLVMTypeRef StructPGFinfoRecord;
80 LLVMTypeRef StructFmgrInfo;
82 LLVMTypeRef StructExprContext;
83 LLVMTypeRef StructExprEvalStep;
84 LLVMTypeRef StructExprState;
85 LLVMTypeRef StructAggState;
88 
89 LLVMValueRef AttributeTemplate;
90 
91 LLVMModuleRef llvm_types_module = NULL;
92 
93 static bool llvm_session_initialized = false;
94 static size_t llvm_generation = 0;
95 static const char *llvm_triple = NULL;
96 static const char *llvm_layout = NULL;
97 
98 
99 static LLVMTargetRef llvm_targetref;
100 #if LLVM_VERSION_MAJOR > 11
101 static LLVMOrcThreadSafeContextRef llvm_ts_context;
102 static LLVMOrcLLJITRef llvm_opt0_orc;
103 static LLVMOrcLLJITRef llvm_opt3_orc;
104 #else /* LLVM_VERSION_MAJOR > 11 */
105 static LLVMOrcJITStackRef llvm_opt0_orc;
106 static LLVMOrcJITStackRef llvm_opt3_orc;
107 #endif /* LLVM_VERSION_MAJOR > 11 */
108 
109 
110 static void llvm_release_context(JitContext *context);
111 static void llvm_session_initialize(void);
112 static void llvm_shutdown(int code, Datum arg);
113 static void llvm_compile_module(LLVMJitContext *context);
114 static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module);
115 
116 static void llvm_create_types(void);
117 static uint64_t llvm_resolve_symbol(const char *name, void *ctx);
118 
119 #if LLVM_VERSION_MAJOR > 11
120 static LLVMOrcLLJITRef llvm_create_jit_instance(LLVMTargetMachineRef tm);
121 static char *llvm_error_message(LLVMErrorRef error);
122 #endif /* LLVM_VERSION_MAJOR > 11 */
123 
125 
126 
127 /*
128  * Initialize LLVM JIT provider.
129  */
130 void
132 {
136 }
137 
138 /*
139  * Create a context for JITing work.
140  *
141  * The context, including subsidiary resources, will be cleaned up either when
142  * the context is explicitly released, or when the lifetime of
143  * CurrentResourceOwner ends (usually the end of the current [sub]xact).
144  */
145 LLVMJitContext *
146 llvm_create_context(int jitFlags)
147 {
148  LLVMJitContext *context;
149 
151 
153 
155 
157  sizeof(LLVMJitContext));
158  context->base.flags = jitFlags;
159 
160  /* ensure cleanup */
161  context->base.resowner = CurrentResourceOwner;
163 
164  return context;
165 }
166 
167 /*
168  * Release resources required by one llvm context.
169  */
170 static void
172 {
173  LLVMJitContext *llvm_context = (LLVMJitContext *) context;
174 
176 
177  /*
178  * When this backend is exiting, don't clean up LLVM. As an error might
179  * have occurred from within LLVM, we do not want to risk reentering. All
180  * resource cleanup is going to happen through process exit.
181  */
183  return;
184 
185  if (llvm_context->module)
186  {
187  LLVMDisposeModule(llvm_context->module);
188  llvm_context->module = NULL;
189  }
190 
191  while (llvm_context->handles != NIL)
192  {
193  LLVMJitHandle *jit_handle;
194 
195  jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
196  llvm_context->handles = list_delete_first(llvm_context->handles);
197 
198 #if LLVM_VERSION_MAJOR > 11
199  {
200  LLVMOrcExecutionSessionRef ee;
201  LLVMOrcSymbolStringPoolRef sp;
202 
203  LLVMOrcResourceTrackerRemove(jit_handle->resource_tracker);
204  LLVMOrcReleaseResourceTracker(jit_handle->resource_tracker);
205 
206  /*
207  * Without triggering cleanup of the string pool, we'd leak
208  * memory. It'd be sufficient to do this far less often, but in
209  * experiments the required time was small enough to just always
210  * do it.
211  */
212  ee = LLVMOrcLLJITGetExecutionSession(jit_handle->lljit);
213  sp = LLVMOrcExecutionSessionGetSymbolStringPool(ee);
214  LLVMOrcSymbolStringPoolClearDeadEntries(sp);
215  }
216 #else /* LLVM_VERSION_MAJOR > 11 */
217  {
218  LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle);
219  }
220 #endif /* LLVM_VERSION_MAJOR > 11 */
221 
222  pfree(jit_handle);
223  }
224 }
225 
226 /*
227  * Return module which may be modified, e.g. by creating new functions.
228  */
229 LLVMModuleRef
230 llvm_mutable_module(LLVMJitContext *context)
231 {
233 
234  /*
235  * If there's no in-progress module, create a new one.
236  */
237  if (!context->module)
238  {
239  context->compiled = false;
240  context->module_generation = llvm_generation++;
241  context->module = LLVMModuleCreateWithName("pg");
242  LLVMSetTarget(context->module, llvm_triple);
243  LLVMSetDataLayout(context->module, llvm_layout);
244  }
245 
246  return context->module;
247 }
248 
249 /*
250  * Expand function name to be non-conflicting. This should be used by code
251  * generating code, when adding new externally visible function definitions to
252  * a Module.
253  */
254 char *
255 llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
256 {
257  Assert(context->module != NULL);
258 
259  context->base.instr.created_functions++;
260 
261  /*
262  * Previously we used dots to separate, but turns out some tools, e.g.
263  * GDB, don't like that and truncate name.
264  */
265  return psprintf("%s_%zu_%d",
266  basename,
267  context->module_generation,
268  context->counter++);
269 }
270 
271 /*
272  * Return pointer to function funcname, which has to exist. If there's pending
273  * code to be optimized and emitted, do so first.
274  */
275 void *
276 llvm_get_function(LLVMJitContext *context, const char *funcname)
277 {
278 #if LLVM_VERSION_MAJOR > 11 || \
279  defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
280  ListCell *lc;
281 #endif
282 
284 
285  /*
286  * If there is a pending / not emitted module, compile and emit now.
287  * Otherwise we might not find the [correct] function.
288  */
289  if (!context->compiled)
290  {
291  llvm_compile_module(context);
292  }
293 
294  /*
295  * ORC's symbol table is of *unmangled* symbols. Therefore we don't need
296  * to mangle here.
297  */
298 
299 #if LLVM_VERSION_MAJOR > 11
300  foreach(lc, context->handles)
301  {
302  LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
303  instr_time starttime;
304  instr_time endtime;
305  LLVMErrorRef error;
306  LLVMOrcJITTargetAddress addr;
307 
308  INSTR_TIME_SET_CURRENT(starttime);
309 
310  addr = 0;
311  error = LLVMOrcLLJITLookup(handle->lljit, &addr, funcname);
312  if (error)
313  elog(ERROR, "failed to look up symbol \"%s\": %s",
314  funcname, llvm_error_message(error));
315 
316  /*
317  * LLJIT only actually emits code the first time a symbol is
318  * referenced. Thus add lookup time to emission time. That's counting
319  * a bit more than with older LLVM versions, but unlikely to ever
320  * matter.
321  */
322  INSTR_TIME_SET_CURRENT(endtime);
323  INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
324  endtime, starttime);
325 
326  if (addr)
327  return (void *) (uintptr_t) addr;
328  }
329 #elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
330  foreach(lc, context->handles)
331  {
332  LLVMOrcTargetAddress addr;
333  LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
334 
335  addr = 0;
336  if (LLVMOrcGetSymbolAddressIn(handle->stack, &addr, handle->orc_handle, funcname))
337  elog(ERROR, "failed to look up symbol \"%s\"", funcname);
338  if (addr)
339  return (void *) (uintptr_t) addr;
340  }
341 #elif LLVM_VERSION_MAJOR < 5
342  {
343  LLVMOrcTargetAddress addr;
344 
345  if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
346  return (void *) (uintptr_t) addr;
347  if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
348  return (void *) (uintptr_t) addr;
349  }
350 #else
351  {
352  LLVMOrcTargetAddress addr;
353 
354  if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
355  elog(ERROR, "failed to look up symbol \"%s\"", funcname);
356  if (addr)
357  return (void *) (uintptr_t) addr;
358  if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
359  elog(ERROR, "failed to look up symbol \"%s\"", funcname);
360  if (addr)
361  return (void *) (uintptr_t) addr;
362  }
363 #endif
364 
365  elog(ERROR, "failed to JIT: %s", funcname);
366 
367  return NULL;
368 }
369 
370 /*
371  * Return declaration for a function referenced in llvmjit_types.c, adding it
372  * to the module if necessary.
373  *
374  * This is used to make functions discovered via llvm_create_types() known to
375  * the module that's currently being worked on.
376  */
377 LLVMValueRef
378 llvm_pg_func(LLVMModuleRef mod, const char *funcname)
379 {
380  LLVMValueRef v_srcfn;
381  LLVMValueRef v_fn;
382 
383  /* don't repeatedly add function */
384  v_fn = LLVMGetNamedFunction(mod, funcname);
385  if (v_fn)
386  return v_fn;
387 
388  v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname);
389 
390  if (!v_srcfn)
391  elog(ERROR, "function %s not in llvmjit_types.c", funcname);
392 
393  v_fn = LLVMAddFunction(mod,
394  funcname,
395  LLVMGetElementType(LLVMTypeOf(v_srcfn)));
396  llvm_copy_attributes(v_srcfn, v_fn);
397 
398  return v_fn;
399 }
400 
401 /*
402  * Copy attributes from one function to another, for a specific index (an
403  * index can reference return value, function and parameter attributes).
404  */
405 static void
406 llvm_copy_attributes_at_index(LLVMValueRef v_from, LLVMValueRef v_to, uint32 index)
407 {
408  int num_attributes;
409  LLVMAttributeRef *attrs;
410 
411  num_attributes = LLVMGetAttributeCountAtIndexPG(v_from, index);
412 
413  /*
414  * Not just for efficiency: LLVM <= 3.9 crashes when
415  * LLVMGetAttributesAtIndex() is called for an index with 0 attributes.
416  */
417  if (num_attributes == 0)
418  return;
419 
420  attrs = palloc(sizeof(LLVMAttributeRef) * num_attributes);
421  LLVMGetAttributesAtIndex(v_from, index, attrs);
422 
423  for (int attno = 0; attno < num_attributes; attno++)
424  LLVMAddAttributeAtIndex(v_to, index, attrs[attno]);
425 
426  pfree(attrs);
427 }
428 
429 /*
430  * Copy all attributes from one function to another. I.e. function, return and
431  * parameters will be copied.
432  */
433 void
434 llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
435 {
436  uint32 param_count;
437 
438  /* copy function attributes */
439  llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeFunctionIndex);
440 
441  /* and the return value attributes */
442  llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeReturnIndex);
443 
444  /* and each function parameter's attribute */
445  param_count = LLVMCountParams(v_from);
446 
447  for (int paramidx = 1; paramidx <= param_count; paramidx++)
448  llvm_copy_attributes_at_index(v_from, v_to, paramidx);
449 }
450 
451 /*
452  * Return a callable LLVMValueRef for fcinfo.
453  */
454 LLVMValueRef
455 llvm_function_reference(LLVMJitContext *context,
456  LLVMBuilderRef builder,
457  LLVMModuleRef mod,
458  FunctionCallInfo fcinfo)
459 {
460  char *modname;
461  char *basename;
462  char *funcname;
463 
464  LLVMValueRef v_fn;
465 
466  fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename);
467 
468  if (modname != NULL && basename != NULL)
469  {
470  /* external function in loadable library */
471  funcname = psprintf("pgextern.%s.%s", modname, basename);
472  }
473  else if (basename != NULL)
474  {
475  /* internal function */
476  funcname = psprintf("%s", basename);
477  }
478  else
479  {
480  /*
481  * Function we don't know to handle, return pointer. We do so by
482  * creating a global constant containing a pointer to the function.
483  * Makes IR more readable.
484  */
485  LLVMValueRef v_fn_addr;
486 
487  funcname = psprintf("pgoidextern.%u",
488  fcinfo->flinfo->fn_oid);
489  v_fn = LLVMGetNamedGlobal(mod, funcname);
490  if (v_fn != 0)
491  return LLVMBuildLoad(builder, v_fn, "");
492 
493  v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
494 
495  v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
496  LLVMSetInitializer(v_fn, v_fn_addr);
497  LLVMSetGlobalConstant(v_fn, true);
498  LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
499  LLVMSetUnnamedAddr(v_fn, true);
500 
501  return LLVMBuildLoad(builder, v_fn, "");
502  }
503 
504  /* check if function already has been added */
505  v_fn = LLVMGetNamedFunction(mod, funcname);
506  if (v_fn != 0)
507  return v_fn;
508 
509  v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction));
510 
511  return v_fn;
512 }
513 
514 /*
515  * Optimize code in module using the flags set in context.
516  */
517 static void
518 llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
519 {
520  LLVMPassManagerBuilderRef llvm_pmb;
521  LLVMPassManagerRef llvm_mpm;
522  LLVMPassManagerRef llvm_fpm;
523  LLVMValueRef func;
524  int compile_optlevel;
525 
526  if (context->base.flags & PGJIT_OPT3)
527  compile_optlevel = 3;
528  else
529  compile_optlevel = 0;
530 
531  /*
532  * Have to create a new pass manager builder every pass through, as the
533  * inliner has some per-builder state. Otherwise one ends up only inlining
534  * a function the first time though.
535  */
536  llvm_pmb = LLVMPassManagerBuilderCreate();
537  LLVMPassManagerBuilderSetOptLevel(llvm_pmb, compile_optlevel);
538  llvm_fpm = LLVMCreateFunctionPassManagerForModule(module);
539 
540  if (context->base.flags & PGJIT_OPT3)
541  {
542  /* TODO: Unscientifically determined threshold */
543  LLVMPassManagerBuilderUseInlinerWithThreshold(llvm_pmb, 512);
544  }
545  else
546  {
547  /* we rely on mem2reg heavily, so emit even in the O0 case */
548  LLVMAddPromoteMemoryToRegisterPass(llvm_fpm);
549  }
550 
551  LLVMPassManagerBuilderPopulateFunctionPassManager(llvm_pmb, llvm_fpm);
552 
553  /*
554  * Do function level optimization. This could be moved to the point where
555  * functions are emitted, to reduce memory usage a bit.
556  */
557  LLVMInitializeFunctionPassManager(llvm_fpm);
558  for (func = LLVMGetFirstFunction(context->module);
559  func != NULL;
560  func = LLVMGetNextFunction(func))
561  LLVMRunFunctionPassManager(llvm_fpm, func);
562  LLVMFinalizeFunctionPassManager(llvm_fpm);
563  LLVMDisposePassManager(llvm_fpm);
564 
565  /*
566  * Perform module level optimization. We do so even in the non-optimized
567  * case, so always-inline functions etc get inlined. It's cheap enough.
568  */
569  llvm_mpm = LLVMCreatePassManager();
570  LLVMPassManagerBuilderPopulateModulePassManager(llvm_pmb,
571  llvm_mpm);
572  /* always use always-inliner pass */
573  if (!(context->base.flags & PGJIT_OPT3))
574  LLVMAddAlwaysInlinerPass(llvm_mpm);
575  /* if doing inlining, but no expensive optimization, add inlining pass */
576  if (context->base.flags & PGJIT_INLINE
577  && !(context->base.flags & PGJIT_OPT3))
578  LLVMAddFunctionInliningPass(llvm_mpm);
579  LLVMRunPassManager(llvm_mpm, context->module);
580  LLVMDisposePassManager(llvm_mpm);
581 
582  LLVMPassManagerBuilderDispose(llvm_pmb);
583 }
584 
585 /*
586  * Emit code for the currently pending module.
587  */
588 static void
589 llvm_compile_module(LLVMJitContext *context)
590 {
591  LLVMJitHandle *handle;
592  MemoryContext oldcontext;
593  instr_time starttime;
594  instr_time endtime;
595 #if LLVM_VERSION_MAJOR > 11
596  LLVMOrcLLJITRef compile_orc;
597 #else
598  LLVMOrcJITStackRef compile_orc;
599 #endif
600 
601  if (context->base.flags & PGJIT_OPT3)
602  compile_orc = llvm_opt3_orc;
603  else
604  compile_orc = llvm_opt0_orc;
605 
606  /* perform inlining */
607  if (context->base.flags & PGJIT_INLINE)
608  {
609  INSTR_TIME_SET_CURRENT(starttime);
610  llvm_inline(context->module);
611  INSTR_TIME_SET_CURRENT(endtime);
612  INSTR_TIME_ACCUM_DIFF(context->base.instr.inlining_counter,
613  endtime, starttime);
614  }
615 
616  if (jit_dump_bitcode)
617  {
618  char *filename;
619 
620  filename = psprintf("%u.%zu.bc",
621  MyProcPid,
622  context->module_generation);
623  LLVMWriteBitcodeToFile(context->module, filename);
624  pfree(filename);
625  }
626 
627 
628  /* optimize according to the chosen optimization settings */
629  INSTR_TIME_SET_CURRENT(starttime);
630  llvm_optimize_module(context, context->module);
631  INSTR_TIME_SET_CURRENT(endtime);
632  INSTR_TIME_ACCUM_DIFF(context->base.instr.optimization_counter,
633  endtime, starttime);
634 
635  if (jit_dump_bitcode)
636  {
637  char *filename;
638 
639  filename = psprintf("%u.%zu.optimized.bc",
640  MyProcPid,
641  context->module_generation);
642  LLVMWriteBitcodeToFile(context->module, filename);
643  pfree(filename);
644  }
645 
646  handle = (LLVMJitHandle *)
648 
649  /*
650  * Emit the code. Note that this can, depending on the optimization
651  * settings, take noticeable resources as code emission executes low-level
652  * instruction combining/selection passes etc. Without optimization a
653  * faster instruction selection mechanism is used.
654  */
655  INSTR_TIME_SET_CURRENT(starttime);
656 #if LLVM_VERSION_MAJOR > 11
657  {
658  LLVMOrcThreadSafeModuleRef ts_module;
659  LLVMErrorRef error;
660  LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(compile_orc);
661 
662  ts_module = LLVMOrcCreateNewThreadSafeModule(context->module, llvm_ts_context);
663 
664  handle->lljit = compile_orc;
665  handle->resource_tracker = LLVMOrcJITDylibCreateResourceTracker(jd);
666 
667  /*
668  * NB: This doesn't actually emit code. That happens lazily the first
669  * time a symbol defined in the module is requested. Due to that
670  * llvm_get_function() also accounts for emission time.
671  */
672 
673  context->module = NULL; /* will be owned by LLJIT */
674  error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc,
675  handle->resource_tracker,
676  ts_module);
677 
678  if (error)
679  elog(ERROR, "failed to JIT module: %s",
680  llvm_error_message(error));
681 
682  handle->lljit = compile_orc;
683 
684  /* LLVMOrcLLJITAddLLVMIRModuleWithRT takes ownership of the module */
685  }
686 #elif LLVM_VERSION_MAJOR > 6
687  {
688  handle->stack = compile_orc;
689  if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, context->module,
690  llvm_resolve_symbol, NULL))
691  elog(ERROR, "failed to JIT module");
692 
693  /* LLVMOrcAddEagerlyCompiledIR takes ownership of the module */
694  }
695 #elif LLVM_VERSION_MAJOR > 4
696  {
697  LLVMSharedModuleRef smod;
698 
699  smod = LLVMOrcMakeSharedModule(context->module);
700  handle->stack = compile_orc;
701  if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, smod,
702  llvm_resolve_symbol, NULL))
703  elog(ERROR, "failed to JIT module");
704 
705  LLVMOrcDisposeSharedModuleRef(smod);
706  }
707 #else /* LLVM 4.0 and 3.9 */
708  {
709  handle->stack = compile_orc;
710  handle->orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
711  llvm_resolve_symbol, NULL);
712 
713  LLVMDisposeModule(context->module);
714  }
715 #endif
716 
717  INSTR_TIME_SET_CURRENT(endtime);
718  INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
719  endtime, starttime);
720 
721  context->module = NULL;
722  context->compiled = true;
723 
724  /* remember emitted code for cleanup and lookups */
726  context->handles = lappend(context->handles, handle);
727  MemoryContextSwitchTo(oldcontext);
728 
729  ereport(DEBUG1,
730  (errmsg("time to inline: %.3fs, opt: %.3fs, emit: %.3fs",
731  INSTR_TIME_GET_DOUBLE(context->base.instr.inlining_counter),
732  INSTR_TIME_GET_DOUBLE(context->base.instr.optimization_counter),
733  INSTR_TIME_GET_DOUBLE(context->base.instr.emission_counter)),
734  errhidestmt(true),
735  errhidecontext(true)));
736 }
737 
738 /*
739  * Per session initialization.
740  */
741 static void
743 {
744  MemoryContext oldcontext;
745  char *error = NULL;
746  char *cpu = NULL;
747  char *features = NULL;
748  LLVMTargetMachineRef opt0_tm;
749  LLVMTargetMachineRef opt3_tm;
750 
752  return;
753 
755 
756  LLVMInitializeNativeTarget();
757  LLVMInitializeNativeAsmPrinter();
758  LLVMInitializeNativeAsmParser();
759 
760  /*
761  * Synchronize types early, as that also includes inferring the target
762  * triple.
763  */
765 
766  if (LLVMGetTargetFromTriple(llvm_triple, &llvm_targetref, &error) != 0)
767  {
768  elog(FATAL, "failed to query triple %s\n", error);
769  }
770 
771  /*
772  * We want the generated code to use all available features. Therefore
773  * grab the host CPU string and detect features of the current CPU. The
774  * latter is needed because some CPU architectures default to enabling
775  * features not all CPUs have (weird, huh).
776  */
777  cpu = LLVMGetHostCPUName();
778  features = LLVMGetHostCPUFeatures();
779  elog(DEBUG2, "LLVMJIT detected CPU \"%s\", with features \"%s\"",
780  cpu, features);
781 
782  opt0_tm =
783  LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
784  LLVMCodeGenLevelNone,
785  LLVMRelocDefault,
786  LLVMCodeModelJITDefault);
787  opt3_tm =
788  LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
789  LLVMCodeGenLevelAggressive,
790  LLVMRelocDefault,
791  LLVMCodeModelJITDefault);
792 
793  LLVMDisposeMessage(cpu);
794  cpu = NULL;
795  LLVMDisposeMessage(features);
796  features = NULL;
797 
798  /* force symbols in main binary to be loaded */
799  LLVMLoadLibraryPermanently(NULL);
800 
801 #if LLVM_VERSION_MAJOR > 11
802  {
803  llvm_ts_context = LLVMOrcCreateNewThreadSafeContext();
804 
805  llvm_opt0_orc = llvm_create_jit_instance(opt0_tm);
806  opt0_tm = 0;
807 
808  llvm_opt3_orc = llvm_create_jit_instance(opt3_tm);
809  opt3_tm = 0;
810  }
811 #else /* LLVM_VERSION_MAJOR > 11 */
812  {
813  llvm_opt0_orc = LLVMOrcCreateInstance(opt0_tm);
814  llvm_opt3_orc = LLVMOrcCreateInstance(opt3_tm);
815 
816 #if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
818  {
819  LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
820 
821  LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
822  LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
823  }
824 #endif
825 #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
827  {
828  LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
829 
830  LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
831  LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
832  }
833 #endif
834  }
835 #endif /* LLVM_VERSION_MAJOR > 11 */
836 
838 
840 
841  MemoryContextSwitchTo(oldcontext);
842 }
843 
844 static void
846 {
847 #if LLVM_VERSION_MAJOR > 11
848  {
849  if (llvm_opt3_orc)
850  {
851  LLVMOrcDisposeLLJIT(llvm_opt3_orc);
852  llvm_opt3_orc = NULL;
853  }
854  if (llvm_opt0_orc)
855  {
856  LLVMOrcDisposeLLJIT(llvm_opt0_orc);
857  llvm_opt0_orc = NULL;
858  }
859  if (llvm_ts_context)
860  {
861  LLVMOrcDisposeThreadSafeContext(llvm_ts_context);
862  llvm_ts_context = NULL;
863  }
864  }
865 #else /* LLVM_VERSION_MAJOR > 11 */
866  {
867  /* unregister profiling support, needs to be flushed to be useful */
868 
869  if (llvm_opt3_orc)
870  {
871 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
873  LLVMOrcUnregisterPerf(llvm_opt3_orc);
874 #endif
875  LLVMOrcDisposeInstance(llvm_opt3_orc);
876  llvm_opt3_orc = NULL;
877  }
878 
879  if (llvm_opt0_orc)
880  {
881 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
883  LLVMOrcUnregisterPerf(llvm_opt0_orc);
884 #endif
885  LLVMOrcDisposeInstance(llvm_opt0_orc);
886  llvm_opt0_orc = NULL;
887  }
888  }
889 #endif /* LLVM_VERSION_MAJOR > 11 */
890 }
891 
892 /* helper for llvm_create_types, returning a global var's type */
893 static LLVMTypeRef
894 load_type(LLVMModuleRef mod, const char *name)
895 {
896  LLVMValueRef value;
897  LLVMTypeRef typ;
898 
899  /* this'll return a *pointer* to the global */
900  value = LLVMGetNamedGlobal(mod, name);
901  if (!value)
902  elog(ERROR, "type %s is unknown", name);
903 
904  /* therefore look at the contained type and return that */
905  typ = LLVMTypeOf(value);
906  Assert(typ != NULL);
907  typ = LLVMGetElementType(typ);
908  Assert(typ != NULL);
909  return typ;
910 }
911 
912 /* helper for llvm_create_types, returning a function's return type */
913 static LLVMTypeRef
914 load_return_type(LLVMModuleRef mod, const char *name)
915 {
916  LLVMValueRef value;
917  LLVMTypeRef typ;
918 
919  /* this'll return a *pointer* to the function */
920  value = LLVMGetNamedFunction(mod, name);
921  if (!value)
922  elog(ERROR, "function %s is unknown", name);
923 
924  /* get type of function pointer */
925  typ = LLVMTypeOf(value);
926  Assert(typ != NULL);
927  /* dereference pointer */
928  typ = LLVMGetElementType(typ);
929  Assert(typ != NULL);
930  /* and look at return type */
931  typ = LLVMGetReturnType(typ);
932  Assert(typ != NULL);
933 
934  return typ;
935 }
936 
937 /*
938  * Load required information, types, function signatures from llvmjit_types.c
939  * and make them available in global variables.
940  *
941  * Those global variables are then used while emitting code.
942  */
943 static void
945 {
946  char path[MAXPGPATH];
947  LLVMMemoryBufferRef buf;
948  char *msg;
949 
950  snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
951 
952  /* open file */
953  if (LLVMCreateMemoryBufferWithContentsOfFile(path, &buf, &msg))
954  {
955  elog(ERROR, "LLVMCreateMemoryBufferWithContentsOfFile(%s) failed: %s",
956  path, msg);
957  }
958 
959  /* eagerly load contents, going to need it all */
960  if (LLVMParseBitcode2(buf, &llvm_types_module))
961  {
962  elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
963  }
964  LLVMDisposeMemoryBuffer(buf);
965 
966  /*
967  * Load triple & layout from clang emitted file so we're guaranteed to be
968  * compatible.
969  */
970  llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
971  llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
972 
973  TypeSizeT = load_type(llvm_types_module, "TypeSizeT");
974  TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
975  TypeStorageBool = load_type(llvm_types_module, "TypeStorageBool");
976  TypePGFunction = load_type(llvm_types_module, "TypePGFunction");
977  StructNullableDatum = load_type(llvm_types_module, "StructNullableDatum");
978  StructExprContext = load_type(llvm_types_module, "StructExprContext");
979  StructExprEvalStep = load_type(llvm_types_module, "StructExprEvalStep");
980  StructExprState = load_type(llvm_types_module, "StructExprState");
981  StructFunctionCallInfoData = load_type(llvm_types_module, "StructFunctionCallInfoData");
982  StructMemoryContextData = load_type(llvm_types_module, "StructMemoryContextData");
983  StructTupleTableSlot = load_type(llvm_types_module, "StructTupleTableSlot");
984  StructHeapTupleTableSlot = load_type(llvm_types_module, "StructHeapTupleTableSlot");
985  StructMinimalTupleTableSlot = load_type(llvm_types_module, "StructMinimalTupleTableSlot");
986  StructHeapTupleData = load_type(llvm_types_module, "StructHeapTupleData");
987  StructTupleDescData = load_type(llvm_types_module, "StructTupleDescData");
988  StructAggState = load_type(llvm_types_module, "StructAggState");
989  StructAggStatePerGroupData = load_type(llvm_types_module, "StructAggStatePerGroupData");
990  StructAggStatePerTransData = load_type(llvm_types_module, "StructAggStatePerTransData");
991 
992  AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
993 }
994 
995 /*
996  * Split a symbol into module / function parts. If the function is in the
997  * main binary (or an external library) *modname will be NULL.
998  */
999 void
1000 llvm_split_symbol_name(const char *name, char **modname, char **funcname)
1001 {
1002  *modname = NULL;
1003  *funcname = NULL;
1004 
1005  /*
1006  * Module function names are pgextern.$module.$funcname
1007  */
1008  if (strncmp(name, "pgextern.", strlen("pgextern.")) == 0)
1009  {
1010  /*
1011  * Symbol names cannot contain a ., therefore we can split based on
1012  * first and last occurrence of one.
1013  */
1014  *funcname = rindex(name, '.');
1015  (*funcname)++; /* jump over . */
1016 
1017  *modname = pnstrdup(name + strlen("pgextern."),
1018  *funcname - name - strlen("pgextern.") - 1);
1019  Assert(funcname);
1020 
1021  *funcname = pstrdup(*funcname);
1022  }
1023  else
1024  {
1025  *modname = NULL;
1026  *funcname = pstrdup(name);
1027  }
1028 }
1029 
1030 /*
1031  * Attempt to resolve symbol, so LLVM can emit a reference to it.
1032  */
1033 static uint64_t
1034 llvm_resolve_symbol(const char *symname, void *ctx)
1035 {
1036  uintptr_t addr;
1037  char *funcname;
1038  char *modname;
1039 
1040  /*
1041  * macOS prefixes all object level symbols with an underscore. But neither
1042  * dlsym() nor PG's inliner expect that. So undo.
1043  */
1044 #if defined(__darwin__)
1045  if (symname[0] != '_')
1046  elog(ERROR, "expected prefixed symbol name, but got \"%s\"", symname);
1047  symname++;
1048 #endif
1049 
1050  llvm_split_symbol_name(symname, &modname, &funcname);
1051 
1052  /* functions that aren't resolved to names shouldn't ever get here */
1053  Assert(funcname);
1054 
1055  if (modname)
1056  addr = (uintptr_t) load_external_function(modname, funcname,
1057  true, NULL);
1058  else
1059  addr = (uintptr_t) LLVMSearchForAddressOfSymbol(symname);
1060 
1061  pfree(funcname);
1062  if (modname)
1063  pfree(modname);
1064 
1065  /* let LLVM will error out - should never happen */
1066  if (!addr)
1067  elog(WARNING, "failed to resolve name %s", symname);
1068 
1069  return (uint64_t) addr;
1070 }
1071 
1072 #if LLVM_VERSION_MAJOR > 11
1073 
1074 static LLVMErrorRef
1075 llvm_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx,
1076  LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind,
1077  LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags,
1078  LLVMOrcCLookupSet LookupSet, size_t LookupSetSize)
1079 {
1080  LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMJITCSymbolMapPair) * LookupSetSize);
1081  LLVMErrorRef error;
1082  LLVMOrcMaterializationUnitRef mu;
1083 
1084  for (int i = 0; i < LookupSetSize; i++)
1085  {
1086  const char *name = LLVMOrcSymbolStringPoolEntryStr(LookupSet[i].Name);
1087 
1088  symbols[i].Name = LookupSet[i].Name;
1089  symbols[i].Sym.Address = llvm_resolve_symbol(name, NULL);
1090  symbols[i].Sym.Flags.GenericFlags = LLVMJITSymbolGenericFlagsExported;
1091  }
1092 
1093  mu = LLVMOrcAbsoluteSymbols(symbols, LookupSetSize);
1094  error = LLVMOrcJITDylibDefine(JD, mu);
1095  if (error != LLVMErrorSuccess)
1096  LLVMOrcDisposeMaterializationUnit(mu);
1097 
1098  pfree(symbols);
1099 
1100  return error;
1101 }
1102 
1103 /*
1104  * We cannot throw errors through LLVM (without causing a FATAL at least), so
1105  * just use WARNING here. That's OK anyway, as the error is also reported at
1106  * the top level action (with less detail) and there might be multiple
1107  * invocations of errors with details.
1108  *
1109  * This doesn't really happen during normal operation, but in cases like
1110  * symbol resolution breakage. So just using elog(WARNING) is fine.
1111  */
1112 static void
1113 llvm_log_jit_error(void *ctx, LLVMErrorRef error)
1114 {
1115  elog(WARNING, "error during JITing: %s",
1116  llvm_error_message(error));
1117 }
1118 
1119 /*
1120  * Create our own object layer, so we can add event listeners.
1121  */
1122 static LLVMOrcObjectLayerRef
1123 llvm_create_object_layer(void *Ctx, LLVMOrcExecutionSessionRef ES, const char *Triple)
1124 {
1125  LLVMOrcObjectLayerRef objlayer =
1126  LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(ES);
1127 
1128 #if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
1130  {
1131  LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
1132 
1133  LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
1134  }
1135 #endif
1136 
1137 #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
1139  {
1140  LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
1141 
1142  LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(objlayer, l);
1143  }
1144 #endif
1145 
1146  return objlayer;
1147 }
1148 
1149 /*
1150  * Create LLJIT instance, using the passed in target machine. Note that the
1151  * target machine afterwards is owned by the LLJIT instance.
1152  */
1153 static LLVMOrcLLJITRef
1154 llvm_create_jit_instance(LLVMTargetMachineRef tm)
1155 {
1156  LLVMOrcLLJITRef lljit;
1157  LLVMOrcJITTargetMachineBuilderRef tm_builder;
1158  LLVMOrcLLJITBuilderRef lljit_builder;
1159  LLVMErrorRef error;
1160  LLVMOrcDefinitionGeneratorRef main_gen;
1161  LLVMOrcDefinitionGeneratorRef ref_gen;
1162 
1163  lljit_builder = LLVMOrcCreateLLJITBuilder();
1164  tm_builder = LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(tm);
1165  LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(lljit_builder, tm_builder);
1166 
1167  LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(lljit_builder,
1168  llvm_create_object_layer,
1169  NULL);
1170 
1171  error = LLVMOrcCreateLLJIT(&lljit, lljit_builder);
1172  if (error)
1173  elog(ERROR, "failed to create lljit instance: %s",
1174  llvm_error_message(error));
1175 
1176  LLVMOrcExecutionSessionSetErrorReporter(LLVMOrcLLJITGetExecutionSession(lljit),
1177  llvm_log_jit_error, NULL);
1178 
1179  /*
1180  * Symbol resolution support for symbols in the postgres binary /
1181  * libraries already loaded.
1182  */
1183  error = LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(&main_gen,
1184  LLVMOrcLLJITGetGlobalPrefix(lljit),
1185  0, NULL);
1186  if (error)
1187  elog(ERROR, "failed to create generator: %s",
1188  llvm_error_message(error));
1189  LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), main_gen);
1190 
1191  /*
1192  * Symbol resolution support for "special" functions, e.g. a call into an
1193  * SQL callable function.
1194  */
1195  ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL);
1196  LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), ref_gen);
1197 
1198  return lljit;
1199 }
1200 
1201 static char *
1202 llvm_error_message(LLVMErrorRef error)
1203 {
1204  char *orig = LLVMGetErrorMessage(error);
1205  char *msg = pstrdup(orig);
1206 
1207  LLVMDisposeErrorMessage(orig);
1208 
1209  return msg;
1210 }
1211 
1212 #endif /* LLVM_VERSION_MAJOR > 11 */
LLVMTypeRef StructPGFinfoRecord
Definition: llvmjit.c:79
#define NIL
Definition: pg_list.h:65
JitProviderResetAfterErrorCB reset_after_error
Definition: jit.h:75
LLVMTypeRef StructTupleConstr
Definition: llvmjit.c:73
#define DEBUG1
Definition: elog.h:25
LLVMTypeRef StructFunctionCallInfoData
Definition: llvmjit.c:81
int MyProcPid
Definition: globals.c:40
static void llvm_compile_module(LLVMJitContext *context)
Definition: llvmjit.c:589
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1198
PG_MODULE_MAGIC
Definition: llvmjit.c:124
static LLVMTypeRef load_type(LLVMModuleRef mod, const char *name)
Definition: llvmjit.c:894
static void error(void)
Definition: sql-dyntest.c:147
LLVMTypeRef StructHeapTupleFieldsField3
Definition: llvmjit.c:64
LLVMTypeRef StructMinimalTupleData
Definition: llvmjit.c:69
LLVMOrcJITStackRef stack
Definition: llvmjit.c:52
PGFunction fn_addr
Definition: fmgr.h:58
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
LLVMTypeRef StructExprEvalStep
Definition: llvmjit.c:83
#define PointerGetDatum(X)
Definition: postgres.h:556
LLVMTypeRef TypeSizeT
Definition: llvmjit.c:59
LLVMTypeRef StructBlockId
Definition: llvmjit.c:71
LLVMTypeRef StructExprState
Definition: llvmjit.c:84
LLVMTypeRef StructHeapTupleFields
Definition: llvmjit.c:65
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
char * pstrdup(const char *in)
Definition: mcxt.c:1187
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool jit_debugging_support
Definition: jit.c:34
struct timeval instr_time
Definition: instr_time.h:150
static void llvm_shutdown(int code, Datum arg)
Definition: llvmjit.c:845
LLVMTypeRef StructNullableDatum
Definition: llvmjit.c:63
LLVMTypeRef StructItemPointerData
Definition: llvmjit.c:70
Definition: jit.h:54
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void _PG_jit_provider_init(JitProviderCallbacks *cb)
Definition: llvmjit.c:131
LLVMValueRef llvm_function_reference(LLVMJitContext *context, LLVMBuilderRef builder, LLVMModuleRef mod, FunctionCallInfo fcinfo)
Definition: llvmjit.c:455
int errhidestmt(bool hide_stmt)
Definition: elog.c:1220
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition: instr_time.h:182
static const char * llvm_layout
Definition: llvmjit.c:96
LLVMJitContext * llvm_create_context(int jitFlags)
Definition: llvmjit.c:146
LLVMTypeRef StructFmgrInfo
Definition: llvmjit.c:80
#define INSTR_TIME_GET_DOUBLE(t)
Definition: instr_time.h:199
LLVMTypeRef StructHeapTupleTableSlot
Definition: llvmjit.c:76
LLVMTypeRef StructAggState
Definition: llvmjit.c:85
static LLVMTypeRef load_return_type(LLVMModuleRef mod, const char *name)
Definition: llvmjit.c:914
void fmgr_symbol(Oid functionId, char **mod, char **fn)
Definition: fmgr.c:283
static struct pg_tm tm
Definition: localtime.c:102
static const char * llvm_triple
Definition: llvmjit.c:95
Definition: type.h:89
LLVMTypeRef StructHeapTupleData
Definition: llvmjit.c:68
LLVMTypeRef StructHeapTupleDataChoice
Definition: llvmjit.c:67
#define PGJIT_OPT3
Definition: jit.h:21
void llvm_split_symbol_name(const char *name, char **modname, char **funcname)
Definition: llvmjit.c:1000
void pfree(void *pointer)
Definition: mcxt.c:1057
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:43
struct LLVMJitHandle LLVMJitHandle
#define FATAL
Definition: elog.h:52
static uint64_t llvm_resolve_symbol(const char *name, void *ctx)
Definition: llvmjit.c:1034
#define MAXPGPATH
unsigned LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx)
LLVMOrcModuleHandle orc_handle
Definition: llvmjit.c:53
char * llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
Definition: llvmjit.c:255
Definition: c.h:671
#define DEBUG2
Definition: elog.h:24
void llvm_assert_in_fatal_section(void)
static char * buf
Definition: pg_test_fsync.c:68
LLVMTypeRef TypeStorageBool
Definition: llvmjit.c:61
unsigned int uint32
Definition: c.h:429
LLVMTypeRef StructMemoryContextData
Definition: llvmjit.c:78
LLVMTypeRef StructExprContext
Definition: llvmjit.c:82
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static LLVMOrcJITStackRef llvm_opt3_orc
Definition: llvmjit.c:106
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
Definition: dfmgr.c:107
List * lappend(List *list, void *datum)
Definition: list.c:321
LLVMTypeRef TypePGFunction
Definition: llvmjit.c:62
#define WARNING
Definition: elog.h:40
LLVMTypeRef StructAggStatePerTransData
Definition: llvmjit.c:87
JitProviderCompileExprCB compile_expr
Definition: jit.h:77
void ResourceOwnerRememberJIT(ResourceOwner owner, Datum handle)
Definition: resowner.c:1358
void * palloc0(Size size)
Definition: mcxt.c:981
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * flinfo
Definition: fmgr.h:87
#define PGJIT_INLINE
Definition: jit.h:22
static bool llvm_session_initialized
Definition: llvmjit.c:93
void llvm_reset_after_error(void)
LLVMTypeRef StructMinimalTupleTableSlot
Definition: llvmjit.c:77
static size_t llvm_generation
Definition: llvmjit.c:94
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:840
LLVMTypeRef StructTupleTableSlot
Definition: llvmjit.c:75
static struct @143 value
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:155
LLVMModuleRef llvm_mutable_module(LLVMJitContext *context)
Definition: llvmjit.c:230
static LLVMTargetRef llvm_targetref
Definition: llvmjit.c:99
static void llvm_session_initialize(void)
Definition: llvmjit.c:742
static void llvm_release_context(JitContext *context)
Definition: llvmjit.c:171
#define Assert(condition)
Definition: c.h:800
#define lfirst(lc)
Definition: pg_list.h:169
bool proc_exit_inprogress
Definition: ipc.c:40
bool llvm_compile_expr(ExprState *state)
Definition: llvmjit_expr.c:78
LLVMTypeRef StructTupleDescData
Definition: llvmjit.c:74
LLVMTypeRef TypeParamBool
Definition: llvmjit.c:60
bool jit_profiling_support
Definition: jit.c:37
void * llvm_get_function(LLVMJitContext *context, const char *funcname)
Definition: llvmjit.c:276
bool jit_dump_bitcode
Definition: jit.c:35
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:156
const char * name
Definition: encode.c:561
static char * filename
Definition: pg_dumpall.c:91
void llvm_inline(LLVMModuleRef M)
static void llvm_create_types(void)
Definition: llvmjit.c:944
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:797
LLVMModuleRef llvm_types_module
Definition: llvmjit.c:91
void llvm_enter_fatal_on_oom(void)
#define elog(elevel,...)
Definition: elog.h:228
int i
LLVMValueRef AttributeTemplate
Definition: llvmjit.c:89
void * arg
static void llvm_copy_attributes_at_index(LLVMValueRef v_from, LLVMValueRef v_to, uint32 index)
Definition: llvmjit.c:406
LLVMTypeRef StructHeapTupleHeaderData
Definition: llvmjit.c:66
void ResourceOwnerEnlargeJIT(ResourceOwner owner)
Definition: resowner.c:1347
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
Definition: llvmjit.c:434
static LLVMOrcJITStackRef llvm_opt0_orc
Definition: llvmjit.c:105
JitProviderReleaseContextCB release_context
Definition: jit.h:76
#define snprintf
Definition: port.h:215
static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
Definition: llvmjit.c:518
char pkglib_path[MAXPGPATH]
Definition: globals.c:73
int errhidecontext(bool hide_ctx)
Definition: elog.c:1239
List * list_delete_first(List *list)
Definition: list.c:860
LLVMTypeRef StructFormPgAttribute
Definition: llvmjit.c:72
LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname)
Definition: llvmjit.c:378
LLVMTypeRef StructAggStatePerGroupData
Definition: llvmjit.c:86