PostgreSQL Source Code  git master
llvmjit.c File Reference
#include "postgres.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/BitReader.h>
#include <llvm-c/BitWriter.h>
#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/OrcBindings.h>
#include <llvm-c/Support.h>
#include <llvm-c/Target.h>
#include <llvm-c/Transforms/IPO.h>
#include <llvm-c/Transforms/PassManagerBuilder.h>
#include <llvm-c/Transforms/Scalar.h>
#include "jit/llvmjit.h"
#include "jit/llvmjit_emit.h"
#include "miscadmin.h"
#include "portability/instr_time.h"
#include "storage/ipc.h"
#include "utils/memutils.h"
#include "utils/resowner_private.h"
Include dependency graph for llvmjit.c:

Go to the source code of this file.

Data Structures

struct  LLVMJitHandle
 

Typedefs

typedef struct LLVMJitHandle LLVMJitHandle
 

Functions

static void llvm_release_context (JitContext *context)
 
static void llvm_session_initialize (void)
 
static void llvm_shutdown (int code, Datum arg)
 
static void llvm_compile_module (LLVMJitContext *context)
 
static void llvm_optimize_module (LLVMJitContext *context, LLVMModuleRef module)
 
static void llvm_create_types (void)
 
static uint64_t llvm_resolve_symbol (const char *name, void *ctx)
 
void _PG_jit_provider_init (JitProviderCallbacks *cb)
 
LLVMJitContext * llvm_create_context (int jitFlags)
 
LLVMModuleRef llvm_mutable_module (LLVMJitContext *context)
 
char * llvm_expand_funcname (struct LLVMJitContext *context, const char *basename)
 
void * llvm_get_function (LLVMJitContext *context, const char *funcname)
 
LLVMTypeRef llvm_pg_var_type (const char *varname)
 
LLVMTypeRef llvm_pg_var_func_type (const char *varname)
 
LLVMValueRef llvm_pg_func (LLVMModuleRef mod, const char *funcname)
 
static void llvm_copy_attributes_at_index (LLVMValueRef v_from, LLVMValueRef v_to, uint32 index)
 
void llvm_copy_attributes (LLVMValueRef v_from, LLVMValueRef v_to)
 
LLVMValueRef llvm_function_reference (LLVMJitContext *context, LLVMBuilderRef builder, LLVMModuleRef mod, FunctionCallInfo fcinfo)
 
static LLVMTypeRef load_return_type (LLVMModuleRef mod, const char *name)
 
void llvm_split_symbol_name (const char *name, char **modname, char **funcname)
 

Variables

LLVMTypeRef TypeSizeT
 
LLVMTypeRef TypeParamBool
 
LLVMTypeRef TypeStorageBool
 
LLVMTypeRef TypePGFunction
 
LLVMTypeRef StructNullableDatum
 
LLVMTypeRef StructHeapTupleFieldsField3
 
LLVMTypeRef StructHeapTupleFields
 
LLVMTypeRef StructHeapTupleHeaderData
 
LLVMTypeRef StructHeapTupleDataChoice
 
LLVMTypeRef StructHeapTupleData
 
LLVMTypeRef StructMinimalTupleData
 
LLVMTypeRef StructItemPointerData
 
LLVMTypeRef StructBlockId
 
LLVMTypeRef StructFormPgAttribute
 
LLVMTypeRef StructTupleConstr
 
LLVMTypeRef StructTupleDescData
 
LLVMTypeRef StructTupleTableSlot
 
LLVMTypeRef StructHeapTupleTableSlot
 
LLVMTypeRef StructMinimalTupleTableSlot
 
LLVMTypeRef StructMemoryContextData
 
LLVMTypeRef StructPGFinfoRecord
 
LLVMTypeRef StructFmgrInfo
 
LLVMTypeRef StructFunctionCallInfoData
 
LLVMTypeRef StructExprContext
 
LLVMTypeRef StructExprEvalStep
 
LLVMTypeRef StructExprState
 
LLVMTypeRef StructAggState
 
LLVMTypeRef StructAggStatePerGroupData
 
LLVMTypeRef StructAggStatePerTransData
 
LLVMValueRef AttributeTemplate
 
LLVMModuleRef llvm_types_module = NULL
 
static bool llvm_session_initialized = false
 
static size_t llvm_generation = 0
 
static const char * llvm_triple = NULL
 
static const char * llvm_layout = NULL
 
static LLVMTargetRef llvm_targetref
 
static LLVMOrcJITStackRef llvm_opt0_orc
 
static LLVMOrcJITStackRef llvm_opt3_orc
 
 PG_MODULE_MAGIC
 

Typedef Documentation

◆ LLVMJitHandle

typedef struct LLVMJitHandle LLVMJitHandle

Function Documentation

◆ _PG_jit_provider_init()

void _PG_jit_provider_init ( JitProviderCallbacks cb)

Definition at line 131 of file llvmjit.c.

132 {
136 }
static void llvm_release_context(JitContext *context)
Definition: llvmjit.c:171
void llvm_reset_after_error(void)
bool llvm_compile_expr(ExprState *state)
Definition: llvmjit_expr.c:78
JitProviderCompileExprCB compile_expr
Definition: jit.h:80
JitProviderResetAfterErrorCB reset_after_error
Definition: jit.h:78
JitProviderReleaseContextCB release_context
Definition: jit.h:79

References JitProviderCallbacks::compile_expr, llvm_compile_expr(), llvm_release_context(), llvm_reset_after_error(), JitProviderCallbacks::release_context, and JitProviderCallbacks::reset_after_error.

◆ llvm_compile_module()

static void llvm_compile_module ( LLVMJitContext *  context)
static

Definition at line 632 of file llvmjit.c.

633 {
634  LLVMJitHandle *handle;
635  MemoryContext oldcontext;
636  instr_time starttime;
637  instr_time endtime;
638 #if LLVM_VERSION_MAJOR > 11
639  LLVMOrcLLJITRef compile_orc;
640 #else
641  LLVMOrcJITStackRef compile_orc;
642 #endif
643 
644  if (context->base.flags & PGJIT_OPT3)
645  compile_orc = llvm_opt3_orc;
646  else
647  compile_orc = llvm_opt0_orc;
648 
649  /* perform inlining */
650  if (context->base.flags & PGJIT_INLINE)
651  {
652  INSTR_TIME_SET_CURRENT(starttime);
653  llvm_inline(context->module);
654  INSTR_TIME_SET_CURRENT(endtime);
655  INSTR_TIME_ACCUM_DIFF(context->base.instr.inlining_counter,
656  endtime, starttime);
657  }
658 
659  if (jit_dump_bitcode)
660  {
661  char *filename;
662 
663  filename = psprintf("%d.%zu.bc",
664  MyProcPid,
665  context->module_generation);
666  LLVMWriteBitcodeToFile(context->module, filename);
667  pfree(filename);
668  }
669 
670 
671  /* optimize according to the chosen optimization settings */
672  INSTR_TIME_SET_CURRENT(starttime);
673  llvm_optimize_module(context, context->module);
674  INSTR_TIME_SET_CURRENT(endtime);
675  INSTR_TIME_ACCUM_DIFF(context->base.instr.optimization_counter,
676  endtime, starttime);
677 
678  if (jit_dump_bitcode)
679  {
680  char *filename;
681 
682  filename = psprintf("%d.%zu.optimized.bc",
683  MyProcPid,
684  context->module_generation);
685  LLVMWriteBitcodeToFile(context->module, filename);
686  pfree(filename);
687  }
688 
689  handle = (LLVMJitHandle *)
691 
692  /*
693  * Emit the code. Note that this can, depending on the optimization
694  * settings, take noticeable resources as code emission executes low-level
695  * instruction combining/selection passes etc. Without optimization a
696  * faster instruction selection mechanism is used.
697  */
698  INSTR_TIME_SET_CURRENT(starttime);
699 #if LLVM_VERSION_MAJOR > 11
700  {
701  LLVMOrcThreadSafeModuleRef ts_module;
702  LLVMErrorRef error;
703  LLVMOrcJITDylibRef jd = LLVMOrcLLJITGetMainJITDylib(compile_orc);
704 
705  ts_module = LLVMOrcCreateNewThreadSafeModule(context->module, llvm_ts_context);
706 
707  handle->lljit = compile_orc;
708  handle->resource_tracker = LLVMOrcJITDylibCreateResourceTracker(jd);
709 
710  /*
711  * NB: This doesn't actually emit code. That happens lazily the first
712  * time a symbol defined in the module is requested. Due to that
713  * llvm_get_function() also accounts for emission time.
714  */
715 
716  context->module = NULL; /* will be owned by LLJIT */
717  error = LLVMOrcLLJITAddLLVMIRModuleWithRT(compile_orc,
718  handle->resource_tracker,
719  ts_module);
720 
721  if (error)
722  elog(ERROR, "failed to JIT module: %s",
723  llvm_error_message(error));
724 
725  /* LLVMOrcLLJITAddLLVMIRModuleWithRT takes ownership of the module */
726  }
727 #elif LLVM_VERSION_MAJOR > 6
728  {
729  handle->stack = compile_orc;
730  if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, context->module,
731  llvm_resolve_symbol, NULL))
732  elog(ERROR, "failed to JIT module");
733 
734  /* LLVMOrcAddEagerlyCompiledIR takes ownership of the module */
735  }
736 #elif LLVM_VERSION_MAJOR > 4
737  {
738  LLVMSharedModuleRef smod;
739 
740  smod = LLVMOrcMakeSharedModule(context->module);
741  handle->stack = compile_orc;
742  if (LLVMOrcAddEagerlyCompiledIR(compile_orc, &handle->orc_handle, smod,
743  llvm_resolve_symbol, NULL))
744  elog(ERROR, "failed to JIT module");
745 
746  LLVMOrcDisposeSharedModuleRef(smod);
747  }
748 #else /* LLVM 4.0 and 3.9 */
749  {
750  handle->stack = compile_orc;
751  handle->orc_handle = LLVMOrcAddEagerlyCompiledIR(compile_orc, context->module,
752  llvm_resolve_symbol, NULL);
753 
754  LLVMDisposeModule(context->module);
755  }
756 #endif
757 
758  INSTR_TIME_SET_CURRENT(endtime);
759  INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
760  endtime, starttime);
761 
762  context->module = NULL;
763  context->compiled = true;
764 
765  /* remember emitted code for cleanup and lookups */
767  context->handles = lappend(context->handles, handle);
768  MemoryContextSwitchTo(oldcontext);
769 
770  ereport(DEBUG1,
771  (errmsg_internal("time to inline: %.3fs, opt: %.3fs, emit: %.3fs",
772  INSTR_TIME_GET_DOUBLE(context->base.instr.inlining_counter),
773  INSTR_TIME_GET_DOUBLE(context->base.instr.optimization_counter),
774  INSTR_TIME_GET_DOUBLE(context->base.instr.emission_counter)),
775  errhidestmt(true),
776  errhidecontext(true)));
777 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int errhidestmt(bool hide_stmt)
Definition: elog.c:1410
int errhidecontext(bool hide_ctx)
Definition: elog.c:1429
#define DEBUG1
Definition: elog.h:30
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int MyProcPid
Definition: globals.c:44
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_GET_DOUBLE(t)
Definition: instr_time.h:188
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition: instr_time.h:184
bool jit_dump_bitcode
Definition: jit.c:35
#define PGJIT_OPT3
Definition: jit.h:21
#define PGJIT_INLINE
Definition: jit.h:22
List * lappend(List *list, void *datum)
Definition: list.c:338
static LLVMOrcJITStackRef llvm_opt3_orc
Definition: llvmjit.c:106
static LLVMOrcJITStackRef llvm_opt0_orc
Definition: llvmjit.c:105
static void llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module)
Definition: llvmjit.c:561
static uint64_t llvm_resolve_symbol(const char *name, void *ctx)
Definition: llvmjit.c:1079
void llvm_inline(LLVMModuleRef M)
void pfree(void *pointer)
Definition: mcxt.c:1456
MemoryContext TopMemoryContext
Definition: mcxt.c:141
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1021
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
static char * filename
Definition: pg_dumpall.c:119
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
static void error(void)
Definition: sql-dyntest.c:147
LLVMOrcJITStackRef stack
Definition: llvmjit.c:52
LLVMOrcModuleHandle orc_handle
Definition: llvmjit.c:53

References DEBUG1, elog(), ereport, errhidecontext(), errhidestmt(), errmsg_internal(), ERROR, error(), filename, INSTR_TIME_ACCUM_DIFF, INSTR_TIME_GET_DOUBLE, INSTR_TIME_SET_CURRENT, jit_dump_bitcode, lappend(), llvm_inline(), llvm_opt0_orc, llvm_opt3_orc, llvm_optimize_module(), llvm_resolve_symbol(), MemoryContextAlloc(), MemoryContextSwitchTo(), MyProcPid, LLVMJitHandle::orc_handle, pfree(), PGJIT_INLINE, PGJIT_OPT3, psprintf(), LLVMJitHandle::stack, and TopMemoryContext.

Referenced by llvm_get_function().

◆ llvm_copy_attributes()

void llvm_copy_attributes ( LLVMValueRef  v_from,
LLVMValueRef  v_to 
)

Definition at line 477 of file llvmjit.c.

478 {
479  uint32 param_count;
480 
481  /* copy function attributes */
482  llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeFunctionIndex);
483 
484  /* and the return value attributes */
485  llvm_copy_attributes_at_index(v_from, v_to, LLVMAttributeReturnIndex);
486 
487  /* and each function parameter's attribute */
488  param_count = LLVMCountParams(v_from);
489 
490  for (int paramidx = 1; paramidx <= param_count; paramidx++)
491  llvm_copy_attributes_at_index(v_from, v_to, paramidx);
492 }
unsigned int uint32
Definition: c.h:495
static void llvm_copy_attributes_at_index(LLVMValueRef v_from, LLVMValueRef v_to, uint32 index)
Definition: llvmjit.c:449

References llvm_copy_attributes_at_index().

Referenced by llvm_pg_func(), and slot_compile_deform().

◆ llvm_copy_attributes_at_index()

static void llvm_copy_attributes_at_index ( LLVMValueRef  v_from,
LLVMValueRef  v_to,
uint32  index 
)
static

Definition at line 449 of file llvmjit.c.

450 {
451  int num_attributes;
452  LLVMAttributeRef *attrs;
453 
454  num_attributes = LLVMGetAttributeCountAtIndexPG(v_from, index);
455 
456  /*
457  * Not just for efficiency: LLVM <= 3.9 crashes when
458  * LLVMGetAttributesAtIndex() is called for an index with 0 attributes.
459  */
460  if (num_attributes == 0)
461  return;
462 
463  attrs = palloc(sizeof(LLVMAttributeRef) * num_attributes);
464  LLVMGetAttributesAtIndex(v_from, index, attrs);
465 
466  for (int attno = 0; attno < num_attributes; attno++)
467  LLVMAddAttributeAtIndex(v_to, index, attrs[attno]);
468 
469  pfree(attrs);
470 }
unsigned LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx)
void * palloc(Size size)
Definition: mcxt.c:1226
Definition: type.h:95

References LLVMGetAttributeCountAtIndexPG(), palloc(), and pfree().

Referenced by llvm_copy_attributes().

◆ llvm_create_context()

LLVMJitContext* llvm_create_context ( int  jitFlags)

Definition at line 146 of file llvmjit.c.

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 }
static void llvm_session_initialize(void)
Definition: llvmjit.c:783
void llvm_assert_in_fatal_section(void)
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1064
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
void ResourceOwnerEnlargeJIT(ResourceOwner owner)
Definition: resowner.c:1440
ResourceOwner CurrentResourceOwner
Definition: resowner.c:147
void ResourceOwnerRememberJIT(ResourceOwner owner, Datum handle)
Definition: resowner.c:1451

References CurrentResourceOwner, llvm_assert_in_fatal_section(), llvm_session_initialize(), MemoryContextAllocZero(), PointerGetDatum(), ResourceOwnerEnlargeJIT(), ResourceOwnerRememberJIT(), and TopMemoryContext.

Referenced by llvm_compile_expr().

◆ llvm_create_types()

static void llvm_create_types ( void  )
static

Definition at line 989 of file llvmjit.c.

990 {
991  char path[MAXPGPATH];
992  LLVMMemoryBufferRef buf;
993  char *msg;
994 
995  snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
996 
997  /* open file */
998  if (LLVMCreateMemoryBufferWithContentsOfFile(path, &buf, &msg))
999  {
1000  elog(ERROR, "LLVMCreateMemoryBufferWithContentsOfFile(%s) failed: %s",
1001  path, msg);
1002  }
1003 
1004  /* eagerly load contents, going to need it all */
1005  if (LLVMParseBitcode2(buf, &llvm_types_module))
1006  {
1007  elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
1008  }
1009  LLVMDisposeMemoryBuffer(buf);
1010 
1011  /*
1012  * Load triple & layout from clang emitted file so we're guaranteed to be
1013  * compatible.
1014  */
1015  llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
1016  llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
1017 
1018  TypeSizeT = llvm_pg_var_type("TypeSizeT");
1019  TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
1020  TypeStorageBool = llvm_pg_var_type("TypeStorageBool");
1021  TypePGFunction = llvm_pg_var_type("TypePGFunction");
1022  StructNullableDatum = llvm_pg_var_type("StructNullableDatum");
1023  StructExprContext = llvm_pg_var_type("StructExprContext");
1024  StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
1025  StructExprState = llvm_pg_var_type("StructExprState");
1026  StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
1027  StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
1028  StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
1029  StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
1030  StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot");
1031  StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData");
1032  StructTupleDescData = llvm_pg_var_type("StructTupleDescData");
1033  StructAggState = llvm_pg_var_type("StructAggState");
1034  StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
1035  StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
1036 
1037  AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
1038 }
char pkglib_path[MAXPGPATH]
Definition: globals.c:77
LLVMTypeRef StructFunctionCallInfoData
Definition: llvmjit.c:81
LLVMTypeRef StructMinimalTupleTableSlot
Definition: llvmjit.c:77
LLVMTypeRef StructExprState
Definition: llvmjit.c:84
static const char * llvm_triple
Definition: llvmjit.c:95
LLVMTypeRef StructExprEvalStep
Definition: llvmjit.c:83
LLVMTypeRef TypeParamBool
Definition: llvmjit.c:60
LLVMTypeRef StructMemoryContextData
Definition: llvmjit.c:78
LLVMTypeRef StructAggStatePerGroupData
Definition: llvmjit.c:86
LLVMTypeRef llvm_pg_var_type(const char *varname)
Definition: llvmjit.c:377
LLVMTypeRef TypeSizeT
Definition: llvmjit.c:59
static const char * llvm_layout
Definition: llvmjit.c:96
LLVMTypeRef StructTupleTableSlot
Definition: llvmjit.c:75
LLVMTypeRef TypeStorageBool
Definition: llvmjit.c:61
static LLVMTypeRef load_return_type(LLVMModuleRef mod, const char *name)
Definition: llvmjit.c:959
LLVMTypeRef StructHeapTupleTableSlot
Definition: llvmjit.c:76
LLVMModuleRef llvm_types_module
Definition: llvmjit.c:91
LLVMTypeRef StructAggState
Definition: llvmjit.c:85
LLVMTypeRef TypePGFunction
Definition: llvmjit.c:62
LLVMTypeRef StructTupleDescData
Definition: llvmjit.c:74
LLVMValueRef AttributeTemplate
Definition: llvmjit.c:89
LLVMTypeRef StructExprContext
Definition: llvmjit.c:82
LLVMTypeRef StructHeapTupleData
Definition: llvmjit.c:68
LLVMTypeRef StructNullableDatum
Definition: llvmjit.c:63
LLVMTypeRef StructAggStatePerTransData
Definition: llvmjit.c:87
char * pstrdup(const char *in)
Definition: mcxt.c:1644
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:67
#define snprintf
Definition: port.h:238

References AttributeTemplate, buf, elog(), ERROR, llvm_layout, llvm_pg_var_type(), llvm_triple, llvm_types_module, load_return_type(), MAXPGPATH, pkglib_path, pstrdup(), snprintf, StructAggState, StructAggStatePerGroupData, StructAggStatePerTransData, StructExprContext, StructExprEvalStep, StructExprState, StructFunctionCallInfoData, StructHeapTupleData, StructHeapTupleTableSlot, StructMemoryContextData, StructMinimalTupleTableSlot, StructNullableDatum, StructTupleDescData, StructTupleTableSlot, TypeParamBool, TypePGFunction, TypeSizeT, and TypeStorageBool.

Referenced by llvm_session_initialize().

◆ llvm_expand_funcname()

char* llvm_expand_funcname ( struct LLVMJitContext *  context,
const char *  basename 
)

Definition at line 257 of file llvmjit.c.

258 {
259  Assert(context->module != NULL);
260 
261  context->base.instr.created_functions++;
262 
263  /*
264  * Previously we used dots to separate, but turns out some tools, e.g.
265  * GDB, don't like that and truncate name.
266  */
267  return psprintf("%s_%zu_%d",
268  basename,
269  context->module_generation,
270  context->counter++);
271 }
Assert(fmt[strlen(fmt) - 1] !='\n')

References Assert(), and psprintf().

Referenced by slot_compile_deform().

◆ llvm_function_reference()

LLVMValueRef llvm_function_reference ( LLVMJitContext *  context,
LLVMBuilderRef  builder,
LLVMModuleRef  mod,
FunctionCallInfo  fcinfo 
)

Definition at line 498 of file llvmjit.c.

502 {
503  char *modname;
504  char *basename;
505  char *funcname;
506 
507  LLVMValueRef v_fn;
508 
509  fmgr_symbol(fcinfo->flinfo->fn_oid, &modname, &basename);
510 
511  if (modname != NULL && basename != NULL)
512  {
513  /* external function in loadable library */
514  funcname = psprintf("pgextern.%s.%s", modname, basename);
515  }
516  else if (basename != NULL)
517  {
518  /* internal function */
519  funcname = pstrdup(basename);
520  }
521  else
522  {
523  /*
524  * Function we don't know to handle, return pointer. We do so by
525  * creating a global constant containing a pointer to the function.
526  * Makes IR more readable.
527  */
528  LLVMValueRef v_fn_addr;
529 
530  funcname = psprintf("pgoidextern.%u",
531  fcinfo->flinfo->fn_oid);
532  v_fn = LLVMGetNamedGlobal(mod, funcname);
533  if (v_fn != 0)
534  return LLVMBuildLoad(builder, v_fn, "");
535 
536  v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
537 
538  v_fn = LLVMAddGlobal(mod, TypePGFunction, funcname);
539  LLVMSetInitializer(v_fn, v_fn_addr);
540  LLVMSetGlobalConstant(v_fn, true);
541  LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
542  LLVMSetUnnamedAddr(v_fn, true);
543 
544  return LLVMBuildLoad(builder, v_fn, "");
545  }
546 
547  /* check if function already has been added */
548  v_fn = LLVMGetNamedFunction(mod, funcname);
549  if (v_fn != 0)
550  return v_fn;
551 
552  v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction));
553 
554  return v_fn;
555 }
void fmgr_symbol(Oid functionId, char **mod, char **fn)
Definition: fmgr.c:281
#define funcname
Definition: indent_codes.h:69
PGFunction fn_addr
Definition: fmgr.h:58
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo * flinfo
Definition: fmgr.h:87

References FunctionCallInfoBaseData::flinfo, fmgr_symbol(), FmgrInfo::fn_addr, FmgrInfo::fn_oid, funcname, psprintf(), pstrdup(), and TypePGFunction.

Referenced by BuildV1Call().

◆ llvm_get_function()

void* llvm_get_function ( LLVMJitContext *  context,
const char *  funcname 
)

Definition at line 278 of file llvmjit.c.

279 {
280 #if LLVM_VERSION_MAJOR > 11 || \
281  defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
282  ListCell *lc;
283 #endif
284 
286 
287  /*
288  * If there is a pending / not emitted module, compile and emit now.
289  * Otherwise we might not find the [correct] function.
290  */
291  if (!context->compiled)
292  {
293  llvm_compile_module(context);
294  }
295 
296  /*
297  * ORC's symbol table is of *unmangled* symbols. Therefore we don't need
298  * to mangle here.
299  */
300 
301 #if LLVM_VERSION_MAJOR > 11
302  foreach(lc, context->handles)
303  {
304  LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
305  instr_time starttime;
306  instr_time endtime;
307  LLVMErrorRef error;
308  LLVMOrcJITTargetAddress addr;
309 
310  INSTR_TIME_SET_CURRENT(starttime);
311 
312  addr = 0;
313  error = LLVMOrcLLJITLookup(handle->lljit, &addr, funcname);
314  if (error)
315  elog(ERROR, "failed to look up symbol \"%s\": %s",
316  funcname, llvm_error_message(error));
317 
318  /*
319  * LLJIT only actually emits code the first time a symbol is
320  * referenced. Thus add lookup time to emission time. That's counting
321  * a bit more than with older LLVM versions, but unlikely to ever
322  * matter.
323  */
324  INSTR_TIME_SET_CURRENT(endtime);
325  INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter,
326  endtime, starttime);
327 
328  if (addr)
329  return (void *) (uintptr_t) addr;
330  }
331 #elif defined(HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN) && HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
332  foreach(lc, context->handles)
333  {
334  LLVMOrcTargetAddress addr;
335  LLVMJitHandle *handle = (LLVMJitHandle *) lfirst(lc);
336 
337  addr = 0;
338  if (LLVMOrcGetSymbolAddressIn(handle->stack, &addr, handle->orc_handle, funcname))
339  elog(ERROR, "failed to look up symbol \"%s\"", funcname);
340  if (addr)
341  return (void *) (uintptr_t) addr;
342  }
343 #elif LLVM_VERSION_MAJOR < 5
344  {
345  LLVMOrcTargetAddress addr;
346 
347  if ((addr = LLVMOrcGetSymbolAddress(llvm_opt0_orc, funcname)))
348  return (void *) (uintptr_t) addr;
349  if ((addr = LLVMOrcGetSymbolAddress(llvm_opt3_orc, funcname)))
350  return (void *) (uintptr_t) addr;
351  }
352 #else
353  {
354  LLVMOrcTargetAddress addr;
355 
356  if (LLVMOrcGetSymbolAddress(llvm_opt0_orc, &addr, funcname))
357  elog(ERROR, "failed to look up symbol \"%s\"", funcname);
358  if (addr)
359  return (void *) (uintptr_t) addr;
360  if (LLVMOrcGetSymbolAddress(llvm_opt3_orc, &addr, funcname))
361  elog(ERROR, "failed to look up symbol \"%s\"", funcname);
362  if (addr)
363  return (void *) (uintptr_t) addr;
364  }
365 #endif
366 
367  elog(ERROR, "failed to JIT: %s", funcname);
368 
369  return NULL;
370 }
static void llvm_compile_module(LLVMJitContext *context)
Definition: llvmjit.c:632
#define lfirst(lc)
Definition: pg_list.h:172

References elog(), ERROR, error(), funcname, INSTR_TIME_ACCUM_DIFF, INSTR_TIME_SET_CURRENT, lfirst, llvm_assert_in_fatal_section(), llvm_compile_module(), llvm_opt0_orc, llvm_opt3_orc, LLVMJitHandle::orc_handle, and LLVMJitHandle::stack.

Referenced by ExecRunCompiledExpr().

◆ llvm_mutable_module()

LLVMModuleRef llvm_mutable_module ( LLVMJitContext *  context)

Definition at line 232 of file llvmjit.c.

233 {
235 
236  /*
237  * If there's no in-progress module, create a new one.
238  */
239  if (!context->module)
240  {
241  context->compiled = false;
242  context->module_generation = llvm_generation++;
243  context->module = LLVMModuleCreateWithName("pg");
244  LLVMSetTarget(context->module, llvm_triple);
245  LLVMSetDataLayout(context->module, llvm_layout);
246  }
247 
248  return context->module;
249 }
static size_t llvm_generation
Definition: llvmjit.c:94

References llvm_assert_in_fatal_section(), llvm_generation, llvm_layout, and llvm_triple.

Referenced by slot_compile_deform().

◆ llvm_optimize_module()

static void llvm_optimize_module ( LLVMJitContext *  context,
LLVMModuleRef  module 
)
static

Definition at line 561 of file llvmjit.c.

562 {
563  LLVMPassManagerBuilderRef llvm_pmb;
564  LLVMPassManagerRef llvm_mpm;
565  LLVMPassManagerRef llvm_fpm;
566  LLVMValueRef func;
567  int compile_optlevel;
568 
569  if (context->base.flags & PGJIT_OPT3)
570  compile_optlevel = 3;
571  else
572  compile_optlevel = 0;
573 
574  /*
575  * Have to create a new pass manager builder every pass through, as the
576  * inliner has some per-builder state. Otherwise one ends up only inlining
577  * a function the first time though.
578  */
579  llvm_pmb = LLVMPassManagerBuilderCreate();
580  LLVMPassManagerBuilderSetOptLevel(llvm_pmb, compile_optlevel);
581  llvm_fpm = LLVMCreateFunctionPassManagerForModule(module);
582 
583  if (context->base.flags & PGJIT_OPT3)
584  {
585  /* TODO: Unscientifically determined threshold */
586  LLVMPassManagerBuilderUseInlinerWithThreshold(llvm_pmb, 512);
587  }
588  else
589  {
590  /* we rely on mem2reg heavily, so emit even in the O0 case */
591  LLVMAddPromoteMemoryToRegisterPass(llvm_fpm);
592  }
593 
594  LLVMPassManagerBuilderPopulateFunctionPassManager(llvm_pmb, llvm_fpm);
595 
596  /*
597  * Do function level optimization. This could be moved to the point where
598  * functions are emitted, to reduce memory usage a bit.
599  */
600  LLVMInitializeFunctionPassManager(llvm_fpm);
601  for (func = LLVMGetFirstFunction(context->module);
602  func != NULL;
603  func = LLVMGetNextFunction(func))
604  LLVMRunFunctionPassManager(llvm_fpm, func);
605  LLVMFinalizeFunctionPassManager(llvm_fpm);
606  LLVMDisposePassManager(llvm_fpm);
607 
608  /*
609  * Perform module level optimization. We do so even in the non-optimized
610  * case, so always-inline functions etc get inlined. It's cheap enough.
611  */
612  llvm_mpm = LLVMCreatePassManager();
613  LLVMPassManagerBuilderPopulateModulePassManager(llvm_pmb,
614  llvm_mpm);
615  /* always use always-inliner pass */
616  if (!(context->base.flags & PGJIT_OPT3))
617  LLVMAddAlwaysInlinerPass(llvm_mpm);
618  /* if doing inlining, but no expensive optimization, add inlining pass */
619  if (context->base.flags & PGJIT_INLINE
620  && !(context->base.flags & PGJIT_OPT3))
621  LLVMAddFunctionInliningPass(llvm_mpm);
622  LLVMRunPassManager(llvm_mpm, context->module);
623  LLVMDisposePassManager(llvm_mpm);
624 
625  LLVMPassManagerBuilderDispose(llvm_pmb);
626 }

References PGJIT_INLINE, and PGJIT_OPT3.

Referenced by llvm_compile_module().

◆ llvm_pg_func()

LLVMValueRef llvm_pg_func ( LLVMModuleRef  mod,
const char *  funcname 
)

Definition at line 421 of file llvmjit.c.

422 {
423  LLVMValueRef v_srcfn;
424  LLVMValueRef v_fn;
425 
426  /* don't repeatedly add function */
427  v_fn = LLVMGetNamedFunction(mod, funcname);
428  if (v_fn)
429  return v_fn;
430 
431  v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname);
432 
433  if (!v_srcfn)
434  elog(ERROR, "function %s not in llvmjit_types.c", funcname);
435 
436  v_fn = LLVMAddFunction(mod,
437  funcname,
438  LLVMGetElementType(LLVMTypeOf(v_srcfn)));
439  llvm_copy_attributes(v_srcfn, v_fn);
440 
441  return v_fn;
442 }
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
Definition: llvmjit.c:477

References elog(), ERROR, funcname, llvm_copy_attributes(), and llvm_types_module.

Referenced by build_EvalXFuncInt(), and slot_compile_deform().

◆ llvm_pg_var_func_type()

LLVMTypeRef llvm_pg_var_func_type ( const char *  varname)

Definition at line 401 of file llvmjit.c.

402 {
403  LLVMTypeRef typ = llvm_pg_var_type(varname);
404 
405  /* look at the contained type */
406  Assert(LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
407  typ = LLVMGetElementType(typ);
408  Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMFunctionTypeKind);
409 
410  return typ;
411 }

References Assert(), and llvm_pg_var_type().

◆ llvm_pg_var_type()

LLVMTypeRef llvm_pg_var_type ( const char *  varname)

Definition at line 377 of file llvmjit.c.

378 {
379  LLVMValueRef v_srcvar;
380  LLVMTypeRef typ;
381 
382  /* this'll return a *pointer* to the global */
383  v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname);
384  if (!v_srcvar)
385  elog(ERROR, "variable %s not in llvmjit_types.c", varname);
386 
387  /* look at the contained type */
388  typ = LLVMTypeOf(v_srcvar);
389  Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
390  typ = LLVMGetElementType(typ);
391  Assert(typ != NULL);
392 
393  return typ;
394 }

References Assert(), elog(), ERROR, and llvm_types_module.

Referenced by llvm_create_types(), and llvm_pg_var_func_type().

◆ llvm_release_context()

static void llvm_release_context ( JitContext context)
static

Definition at line 171 of file llvmjit.c.

172 {
173  LLVMJitContext *llvm_context = (LLVMJitContext *) context;
174  ListCell *lc;
175 
176  /*
177  * When this backend is exiting, don't clean up LLVM. As an error might
178  * have occurred from within LLVM, we do not want to risk reentering. All
179  * resource cleanup is going to happen through process exit.
180  */
182  return;
183 
185 
186  if (llvm_context->module)
187  {
188  LLVMDisposeModule(llvm_context->module);
189  llvm_context->module = NULL;
190  }
191 
192  foreach(lc, llvm_context->handles)
193  {
194  LLVMJitHandle *jit_handle = (LLVMJitHandle *) lfirst(lc);
195 
196 #if LLVM_VERSION_MAJOR > 11
197  {
198  LLVMOrcExecutionSessionRef ee;
199  LLVMOrcSymbolStringPoolRef sp;
200 
201  LLVMOrcResourceTrackerRemove(jit_handle->resource_tracker);
202  LLVMOrcReleaseResourceTracker(jit_handle->resource_tracker);
203 
204  /*
205  * Without triggering cleanup of the string pool, we'd leak
206  * memory. It'd be sufficient to do this far less often, but in
207  * experiments the required time was small enough to just always
208  * do it.
209  */
210  ee = LLVMOrcLLJITGetExecutionSession(jit_handle->lljit);
211  sp = LLVMOrcExecutionSessionGetSymbolStringPool(ee);
212  LLVMOrcSymbolStringPoolClearDeadEntries(sp);
213  }
214 #else /* LLVM_VERSION_MAJOR > 11 */
215  {
216  LLVMOrcRemoveModule(jit_handle->stack, jit_handle->orc_handle);
217  }
218 #endif /* LLVM_VERSION_MAJOR > 11 */
219 
220  pfree(jit_handle);
221  }
222  list_free(llvm_context->handles);
223  llvm_context->handles = NIL;
224 
226 }
bool proc_exit_inprogress
Definition: ipc.c:40
void list_free(List *list)
Definition: list.c:1545
void llvm_enter_fatal_on_oom(void)
void llvm_leave_fatal_on_oom(void)
#define NIL
Definition: pg_list.h:68

References lfirst, list_free(), llvm_enter_fatal_on_oom(), llvm_leave_fatal_on_oom(), NIL, LLVMJitHandle::orc_handle, pfree(), proc_exit_inprogress, and LLVMJitHandle::stack.

Referenced by _PG_jit_provider_init().

◆ llvm_resolve_symbol()

static uint64_t llvm_resolve_symbol ( const char *  name,
void *  ctx 
)
static

Definition at line 1079 of file llvmjit.c.

1080 {
1081  uintptr_t addr;
1082  char *funcname;
1083  char *modname;
1084 
1085  /*
1086  * macOS prefixes all object level symbols with an underscore. But neither
1087  * dlsym() nor PG's inliner expect that. So undo.
1088  */
1089 #if defined(__darwin__)
1090  if (symname[0] != '_')
1091  elog(ERROR, "expected prefixed symbol name, but got \"%s\"", symname);
1092  symname++;
1093 #endif
1094 
1095  llvm_split_symbol_name(symname, &modname, &funcname);
1096 
1097  /* functions that aren't resolved to names shouldn't ever get here */
1098  Assert(funcname);
1099 
1100  if (modname)
1101  addr = (uintptr_t) load_external_function(modname, funcname,
1102  true, NULL);
1103  else
1104  addr = (uintptr_t) LLVMSearchForAddressOfSymbol(symname);
1105 
1106  pfree(funcname);
1107  if (modname)
1108  pfree(modname);
1109 
1110  /* let LLVM will error out - should never happen */
1111  if (!addr)
1112  elog(WARNING, "failed to resolve name %s", symname);
1113 
1114  return (uint64_t) addr;
1115 }
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
Definition: dfmgr.c:105
#define WARNING
Definition: elog.h:36
void llvm_split_symbol_name(const char *name, char **modname, char **funcname)
Definition: llvmjit.c:1045

References Assert(), elog(), ERROR, funcname, llvm_split_symbol_name(), load_external_function(), pfree(), and WARNING.

Referenced by llvm_compile_module().

◆ llvm_session_initialize()

static void llvm_session_initialize ( void  )
static

Definition at line 783 of file llvmjit.c.

784 {
785  MemoryContext oldcontext;
786  char *error = NULL;
787  char *cpu = NULL;
788  char *features = NULL;
789  LLVMTargetMachineRef opt0_tm;
790  LLVMTargetMachineRef opt3_tm;
791 
793  return;
794 
796 
797  LLVMInitializeNativeTarget();
798  LLVMInitializeNativeAsmPrinter();
799  LLVMInitializeNativeAsmParser();
800 
801  /*
802  * When targeting an LLVM version with opaque pointers enabled by default,
803  * turn them off for the context we build our code in. We don't need to
804  * do so for other contexts (e.g. llvm_ts_context). Once the IR is
805  * generated, it carries the necessary information.
806  */
807 #if LLVM_VERSION_MAJOR > 14
808  LLVMContextSetOpaquePointers(LLVMGetGlobalContext(), false);
809 #endif
810 
811  /*
812  * Synchronize types early, as that also includes inferring the target
813  * triple.
814  */
816 
817  if (LLVMGetTargetFromTriple(llvm_triple, &llvm_targetref, &error) != 0)
818  {
819  elog(FATAL, "failed to query triple %s", error);
820  }
821 
822  /*
823  * We want the generated code to use all available features. Therefore
824  * grab the host CPU string and detect features of the current CPU. The
825  * latter is needed because some CPU architectures default to enabling
826  * features not all CPUs have (weird, huh).
827  */
828  cpu = LLVMGetHostCPUName();
829  features = LLVMGetHostCPUFeatures();
830  elog(DEBUG2, "LLVMJIT detected CPU \"%s\", with features \"%s\"",
831  cpu, features);
832 
833  opt0_tm =
834  LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
835  LLVMCodeGenLevelNone,
836  LLVMRelocDefault,
837  LLVMCodeModelJITDefault);
838  opt3_tm =
839  LLVMCreateTargetMachine(llvm_targetref, llvm_triple, cpu, features,
840  LLVMCodeGenLevelAggressive,
841  LLVMRelocDefault,
842  LLVMCodeModelJITDefault);
843 
844  LLVMDisposeMessage(cpu);
845  cpu = NULL;
846  LLVMDisposeMessage(features);
847  features = NULL;
848 
849  /* force symbols in main binary to be loaded */
850  LLVMLoadLibraryPermanently(NULL);
851 
852 #if LLVM_VERSION_MAJOR > 11
853  {
854  llvm_ts_context = LLVMOrcCreateNewThreadSafeContext();
855 
856  llvm_opt0_orc = llvm_create_jit_instance(opt0_tm);
857  opt0_tm = 0;
858 
859  llvm_opt3_orc = llvm_create_jit_instance(opt3_tm);
860  opt3_tm = 0;
861  }
862 #else /* LLVM_VERSION_MAJOR > 11 */
863  {
864  llvm_opt0_orc = LLVMOrcCreateInstance(opt0_tm);
865  llvm_opt3_orc = LLVMOrcCreateInstance(opt3_tm);
866 
867 #if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
869  {
870  LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener();
871 
872  LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
873  LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
874  }
875 #endif
876 #if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
878  {
879  LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener();
880 
881  LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l);
882  LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l);
883  }
884 #endif
885  }
886 #endif /* LLVM_VERSION_MAJOR > 11 */
887 
889 
891 
892  MemoryContextSwitchTo(oldcontext);
893 }
#define FATAL
Definition: elog.h:41
#define DEBUG2
Definition: elog.h:29
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
bool jit_profiling_support
Definition: jit.c:37
bool jit_debugging_support
Definition: jit.c:34
static LLVMTargetRef llvm_targetref
Definition: llvmjit.c:99
static bool llvm_session_initialized
Definition: llvmjit.c:93
static void llvm_create_types(void)
Definition: llvmjit.c:989
static void llvm_shutdown(int code, Datum arg)
Definition: llvmjit.c:896

References DEBUG2, elog(), error(), FATAL, jit_debugging_support, jit_profiling_support, llvm_create_types(), llvm_opt0_orc, llvm_opt3_orc, llvm_session_initialized, llvm_shutdown(), llvm_targetref, llvm_triple, MemoryContextSwitchTo(), on_proc_exit(), and TopMemoryContext.

Referenced by llvm_create_context().

◆ llvm_shutdown()

static void llvm_shutdown ( int  code,
Datum  arg 
)
static

Definition at line 896 of file llvmjit.c.

897 {
898  /*
899  * If llvm_shutdown() is reached while in a fatal-on-oom section an error
900  * has occurred in the middle of LLVM code. It is not safe to call back
901  * into LLVM (which is why a FATAL error was thrown).
902  *
903  * We do need to shutdown LLVM in other shutdown cases, otherwise e.g.
904  * profiling data won't be written out.
905  */
906  if (llvm_in_fatal_on_oom())
907  {
909  return;
910  }
911 
912 #if LLVM_VERSION_MAJOR > 11
913  {
914  if (llvm_opt3_orc)
915  {
916  LLVMOrcDisposeLLJIT(llvm_opt3_orc);
917  llvm_opt3_orc = NULL;
918  }
919  if (llvm_opt0_orc)
920  {
921  LLVMOrcDisposeLLJIT(llvm_opt0_orc);
922  llvm_opt0_orc = NULL;
923  }
924  if (llvm_ts_context)
925  {
926  LLVMOrcDisposeThreadSafeContext(llvm_ts_context);
927  llvm_ts_context = NULL;
928  }
929  }
930 #else /* LLVM_VERSION_MAJOR > 11 */
931  {
932  /* unregister profiling support, needs to be flushed to be useful */
933 
934  if (llvm_opt3_orc)
935  {
936 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
938  LLVMOrcUnregisterPerf(llvm_opt3_orc);
939 #endif
940  LLVMOrcDisposeInstance(llvm_opt3_orc);
941  llvm_opt3_orc = NULL;
942  }
943 
944  if (llvm_opt0_orc)
945  {
946 #if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF
948  LLVMOrcUnregisterPerf(llvm_opt0_orc);
949 #endif
950  LLVMOrcDisposeInstance(llvm_opt0_orc);
951  llvm_opt0_orc = NULL;
952  }
953  }
954 #endif /* LLVM_VERSION_MAJOR > 11 */
955 }
bool llvm_in_fatal_on_oom(void)

References Assert(), jit_profiling_support, llvm_in_fatal_on_oom(), llvm_opt0_orc, llvm_opt3_orc, and proc_exit_inprogress.

Referenced by llvm_session_initialize().

◆ llvm_split_symbol_name()

void llvm_split_symbol_name ( const char *  name,
char **  modname,
char **  funcname 
)

Definition at line 1045 of file llvmjit.c.

1046 {
1047  *modname = NULL;
1048  *funcname = NULL;
1049 
1050  /*
1051  * Module function names are pgextern.$module.$funcname
1052  */
1053  if (strncmp(name, "pgextern.", strlen("pgextern.")) == 0)
1054  {
1055  /*
1056  * Symbol names cannot contain a ., therefore we can split based on
1057  * first and last occurrence of one.
1058  */
1059  *funcname = rindex(name, '.');
1060  (*funcname)++; /* jump over . */
1061 
1062  *modname = pnstrdup(name + strlen("pgextern."),
1063  *funcname - name - strlen("pgextern.") - 1);
1064  Assert(funcname);
1065 
1066  *funcname = pstrdup(*funcname);
1067  }
1068  else
1069  {
1070  *modname = NULL;
1071  *funcname = pstrdup(name);
1072  }
1073 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1655
const char * name

References Assert(), funcname, name, pnstrdup(), and pstrdup().

Referenced by llvm_build_inline_plan(), llvm_execute_inline_plan(), and llvm_resolve_symbol().

◆ load_return_type()

static LLVMTypeRef load_return_type ( LLVMModuleRef  mod,
const char *  name 
)
static

Definition at line 959 of file llvmjit.c.

960 {
961  LLVMValueRef value;
962  LLVMTypeRef typ;
963 
964  /* this'll return a *pointer* to the function */
965  value = LLVMGetNamedFunction(mod, name);
966  if (!value)
967  elog(ERROR, "function %s is unknown", name);
968 
969  /* get type of function pointer */
970  typ = LLVMTypeOf(value);
971  Assert(typ != NULL);
972  /* dereference pointer */
973  typ = LLVMGetElementType(typ);
974  Assert(typ != NULL);
975  /* and look at return type */
976  typ = LLVMGetReturnType(typ);
977  Assert(typ != NULL);
978 
979  return typ;
980 }
static struct @148 value

References Assert(), elog(), ERROR, name, and value.

Referenced by llvm_create_types().

Variable Documentation

◆ AttributeTemplate

Datum AttributeTemplate

Definition at line 89 of file llvmjit.c.

Referenced by llvm_create_types(), and slot_compile_deform().

◆ llvm_generation

size_t llvm_generation = 0
static

Definition at line 94 of file llvmjit.c.

Referenced by llvm_mutable_module().

◆ llvm_layout

const char* llvm_layout = NULL
static

Definition at line 96 of file llvmjit.c.

Referenced by llvm_create_types(), and llvm_mutable_module().

◆ llvm_opt0_orc

LLVMOrcJITStackRef llvm_opt0_orc
static

◆ llvm_opt3_orc

LLVMOrcJITStackRef llvm_opt3_orc
static

◆ llvm_session_initialized

bool llvm_session_initialized = false
static

Definition at line 93 of file llvmjit.c.

Referenced by llvm_session_initialize().

◆ llvm_targetref

LLVMTargetRef llvm_targetref
static

Definition at line 99 of file llvmjit.c.

Referenced by llvm_session_initialize().

◆ llvm_triple

const char* llvm_triple = NULL
static

Definition at line 95 of file llvmjit.c.

Referenced by llvm_create_types(), llvm_mutable_module(), and llvm_session_initialize().

◆ llvm_types_module

LLVMModuleRef llvm_types_module = NULL

Definition at line 91 of file llvmjit.c.

Referenced by llvm_create_types(), llvm_pg_func(), and llvm_pg_var_type().

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 124 of file llvmjit.c.

◆ StructAggState

LLVMTypeRef StructAggState

Definition at line 85 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructAggStatePerGroupData

LLVMTypeRef StructAggStatePerGroupData

Definition at line 86 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructAggStatePerTransData

LLVMTypeRef StructAggStatePerTransData

Definition at line 87 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructBlockId

LLVMTypeRef StructBlockId

Definition at line 71 of file llvmjit.c.

◆ StructExprContext

LLVMTypeRef StructExprContext

Definition at line 82 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructExprEvalStep

LLVMTypeRef StructExprEvalStep

Definition at line 83 of file llvmjit.c.

Referenced by build_EvalXFuncInt(), and llvm_create_types().

◆ StructExprState

LLVMTypeRef StructExprState

Definition at line 84 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructFmgrInfo

LLVMTypeRef StructFmgrInfo

Definition at line 80 of file llvmjit.c.

◆ StructFormPgAttribute

LLVMTypeRef StructFormPgAttribute

Definition at line 72 of file llvmjit.c.

◆ StructFunctionCallInfoData

LLVMTypeRef StructFunctionCallInfoData

Definition at line 81 of file llvmjit.c.

Referenced by BuildV1Call(), and llvm_create_types().

◆ StructHeapTupleData

LLVMTypeRef StructHeapTupleData

Definition at line 68 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructHeapTupleDataChoice

LLVMTypeRef StructHeapTupleDataChoice

Definition at line 67 of file llvmjit.c.

◆ StructHeapTupleFields

LLVMTypeRef StructHeapTupleFields

Definition at line 65 of file llvmjit.c.

◆ StructHeapTupleFieldsField3

LLVMTypeRef StructHeapTupleFieldsField3

Definition at line 64 of file llvmjit.c.

◆ StructHeapTupleHeaderData

LLVMTypeRef StructHeapTupleHeaderData

Definition at line 66 of file llvmjit.c.

◆ StructHeapTupleTableSlot

LLVMTypeRef StructHeapTupleTableSlot

Definition at line 76 of file llvmjit.c.

Referenced by llvm_create_types(), and slot_compile_deform().

◆ StructItemPointerData

LLVMTypeRef StructItemPointerData

Definition at line 70 of file llvmjit.c.

◆ StructMemoryContextData

LLVMTypeRef StructMemoryContextData

Definition at line 78 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructMinimalTupleData

LLVMTypeRef StructMinimalTupleData

Definition at line 69 of file llvmjit.c.

◆ StructMinimalTupleTableSlot

LLVMTypeRef StructMinimalTupleTableSlot

Definition at line 77 of file llvmjit.c.

Referenced by llvm_create_types(), and slot_compile_deform().

◆ StructNullableDatum

LLVMTypeRef StructNullableDatum

Definition at line 63 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructPGFinfoRecord

LLVMTypeRef StructPGFinfoRecord

Definition at line 79 of file llvmjit.c.

◆ StructTupleConstr

LLVMTypeRef StructTupleConstr

Definition at line 73 of file llvmjit.c.

◆ StructTupleDescData

LLVMTypeRef StructTupleDescData

Definition at line 74 of file llvmjit.c.

Referenced by llvm_create_types().

◆ StructTupleTableSlot

LLVMTypeRef StructTupleTableSlot

Definition at line 75 of file llvmjit.c.

Referenced by llvm_create_types(), and slot_compile_deform().

◆ TypeParamBool

LLVMTypeRef TypeParamBool

Definition at line 60 of file llvmjit.c.

Referenced by llvm_create_types().

◆ TypePGFunction

LLVMTypeRef TypePGFunction

Definition at line 62 of file llvmjit.c.

Referenced by llvm_create_types(), and llvm_function_reference().

◆ TypeSizeT

LLVMTypeRef TypeSizeT

Definition at line 59 of file llvmjit.c.

Referenced by llvm_create_types(), and slot_compile_deform().

◆ TypeStorageBool

LLVMTypeRef TypeStorageBool

Definition at line 61 of file llvmjit.c.

Referenced by llvm_create_types().