3 * Helpers to make emitting LLVM IR a bit more concise and pgindent proof.
5 * Copyright (c) 2018-2025, PostgreSQL Global Development Group
7 * src/include/jit/llvmjit_emit.h
13 * To avoid breaking cpluspluscheck, allow including the file even when LLVM
18#include <llvm-c/Core.h>
19#include <llvm-c/Target.h>
25 * Emit a non-LLVM pointer as an LLVM constant.
27static inline LLVMValueRef
28l_ptr_const(
void *ptr, LLVMTypeRef
type)
30 LLVMValueRef
c = LLVMConstInt(
TypeSizeT, (uintptr_t) ptr,
false);
32 return LLVMConstIntToPtr(
c,
type);
38static inline LLVMTypeRef
41 return LLVMPointerType(t, 0);
45 * Emit constant integer.
47static inline LLVMValueRef
48l_int8_const(LLVMContextRef lc,
int8 i)
50 return LLVMConstInt(LLVMInt8TypeInContext(lc),
i,
false);
54 * Emit constant integer.
56static inline LLVMValueRef
57l_int16_const(LLVMContextRef lc,
int16 i)
59 return LLVMConstInt(LLVMInt16TypeInContext(lc),
i,
false);
63 * Emit constant integer.
65static inline LLVMValueRef
66l_int32_const(LLVMContextRef lc,
int32 i)
68 return LLVMConstInt(LLVMInt32TypeInContext(lc),
i,
false);
72 * Emit constant integer.
74static inline LLVMValueRef
75l_int64_const(LLVMContextRef lc,
int64 i)
77 return LLVMConstInt(LLVMInt64TypeInContext(lc),
i,
false);
81 * Emit constant integer.
83static inline LLVMValueRef
84l_sizet_const(
size_t i)
90 * Emit constant integer.
92static inline LLVMValueRef
99 * Emit constant boolean, as used for storage (e.g. global vars, structs).
101static inline LLVMValueRef
108 * Emit constant boolean, as used for parameters (e.g. function parameters).
110static inline LLVMValueRef
116static inline LLVMValueRef
117l_struct_gep(LLVMBuilderRef
b, LLVMTypeRef t, LLVMValueRef v,
int32 idx,
const char *
name)
119 return LLVMBuildStructGEP2(
b, t, v,
idx,
"");
122static inline LLVMValueRef
123l_gep(LLVMBuilderRef
b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef *indices,
int32 nindices,
const char *
name)
125 return LLVMBuildGEP2(
b, t, v, indices, nindices,
name);
128static inline LLVMValueRef
129l_load(LLVMBuilderRef
b, LLVMTypeRef t, LLVMValueRef v,
const char *
name)
131 return LLVMBuildLoad2(
b, t, v,
name);
134static inline LLVMValueRef
135l_call(LLVMBuilderRef
b, LLVMTypeRef t, LLVMValueRef
fn, LLVMValueRef *
args,
int32 nargs,
const char *
name)
137 return LLVMBuildCall2(
b, t,
fn,
args, nargs,
name);
141 * Load a pointer member idx from a struct.
143static inline LLVMValueRef
144l_load_struct_gep(LLVMBuilderRef
b, LLVMTypeRef t, LLVMValueRef v,
int32 idx,
const char *
name)
147 LLVMStructGetTypeAtIndex(t,
idx),
148 l_struct_gep(
b, t, v,
idx,
""),
153 * Load value of a pointer, after applying one index operation.
155static inline LLVMValueRef
156l_load_gep1(LLVMBuilderRef
b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef
idx,
const char *
name)
158 return l_load(
b, t, l_gep(
b, t, v, &
idx, 1,
""),
name);
161/* separate, because pg_attribute_printf(2, 3) can't appear in definition */
162static inline LLVMBasicBlockRef l_bb_before_v(LLVMBasicBlockRef r,
const char *fmt,...)
pg_attribute_printf(2, 3);
165 * Insert a new basic block, just before r, the name being determined by fmt
168static inline LLVMBasicBlockRef
169l_bb_before_v(LLVMBasicBlockRef r, const
char *fmt,...)
179 lc = LLVMGetTypeContext(LLVMTypeOf(LLVMGetBasicBlockParent(r)));
181 return LLVMInsertBasicBlockInContext(lc, r,
buf);
184/* separate, because pg_attribute_printf(2, 3) can't appear in definition */
185static inline LLVMBasicBlockRef l_bb_append_v(LLVMValueRef f,
const char *fmt,...)
pg_attribute_printf(2, 3);
188 * Insert a new basic block after previous basic blocks, the name being
189 * determined by fmt and arguments.
191static inline LLVMBasicBlockRef
192l_bb_append_v(LLVMValueRef f, const
char *fmt,...)
202 lc = LLVMGetTypeContext(LLVMTypeOf(f));
204 return LLVMAppendBasicBlockInContext(lc, f,
buf);
208 * Mark a callsite as readonly.
211l_callsite_ro(LLVMValueRef f)
213 const char argname[] =
"readonly";
214 LLVMAttributeRef ref;
216 ref = LLVMCreateStringAttribute(LLVMGetTypeContext(LLVMTypeOf(f)),
221 LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, ref);
225 * Mark a callsite as alwaysinline.
228l_callsite_alwaysinline(LLVMValueRef f)
230 const char argname[] =
"alwaysinline";
232 LLVMAttributeRef attr;
234 id = LLVMGetEnumAttributeKindForName(argname,
235 sizeof(argname) - 1);
236 attr = LLVMCreateEnumAttribute(LLVMGetTypeContext(LLVMTypeOf(f)),
id, 0);
237 LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr);
241 * Emit code to switch memory context.
243static inline LLVMValueRef
244l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef
b, LLVMValueRef nc)
246 const char *cmc =
"CurrentMemoryContext";
250 if (!(
cur = LLVMGetNamedGlobal(mod, cmc)))
253 LLVMBuildStore(
b, nc,
cur);
259 * Return pointer to the argno'th argument nullness.
261static inline LLVMValueRef
262l_funcnullp(LLVMBuilderRef
b, LLVMValueRef v_fcinfo,
size_t argno)
267 v_args = l_struct_gep(
b,
272 v_argn = l_struct_gep(
b,
277 return l_struct_gep(
b,
285 * Return pointer to the argno'th argument datum.
287static inline LLVMValueRef
288l_funcvaluep(LLVMBuilderRef
b, LLVMValueRef v_fcinfo,
size_t argno)
293 v_args = l_struct_gep(
b,
298 v_argn = l_struct_gep(
b,
303 return l_struct_gep(
b,
311 * Return argno'th argument nullness.
313static inline LLVMValueRef
314l_funcnull(LLVMBuilderRef
b, LLVMValueRef v_fcinfo,
size_t argno)
320 * Return argno'th argument datum.
322static inline LLVMValueRef
323l_funcvalue(LLVMBuilderRef
b, LLVMValueRef v_fcinfo,
size_t argno)
325 return l_load(
b,
TypeDatum, l_funcvaluep(
b, v_fcinfo, argno),
"");
Datum idx(PG_FUNCTION_ARGS)
#define pg_attribute_printf(f, a)
#define FIELDNO_FUNCTIONCALLINFODATA_ARGS
LLVMTypeRef StructFunctionCallInfoData
LLVMTypeRef TypeParamBool
LLVMTypeRef StructMemoryContextData
LLVMTypeRef TypeStorageBool
LLVMTypeRef StructNullableDatum
#define FIELDNO_NULLABLE_DATUM_ISNULL
#define FIELDNO_NULLABLE_DATUM_DATUM
static void * fn(void *arg)