PostgreSQL Source Code: src/include/jit/llvmjit_emit.h Source File

PostgreSQL Source Code git master
llvmjit_emit.h
Go to the documentation of this file.
1/*
2 * llvmjit_emit.h
3 * Helpers to make emitting LLVM IR a bit more concise and pgindent proof.
4 *
5 * Copyright (c) 2018-2025, PostgreSQL Global Development Group
6 *
7 * src/include/jit/llvmjit_emit.h
8 */
9#ifndef LLVMJIT_EMIT_H
10#define LLVMJIT_EMIT_H
11
12/*
13 * To avoid breaking cpluspluscheck, allow including the file even when LLVM
14 * is not available.
15 */
16#ifdef USE_LLVM
17
18#include <llvm-c/Core.h>
19#include <llvm-c/Target.h>
20
21#include "jit/llvmjit.h"
22
23
24/*
25 * Emit a non-LLVM pointer as an LLVM constant.
26 */
27static inline LLVMValueRef
28l_ptr_const(void *ptr, LLVMTypeRef type)
29{
30 LLVMValueRef c = LLVMConstInt(TypeSizeT, (uintptr_t) ptr, false);
31
32 return LLVMConstIntToPtr(c, type);
33}
34
35/*
36 * Emit pointer.
37 */
38static inline LLVMTypeRef
39l_ptr(LLVMTypeRef t)
40{
41 return LLVMPointerType(t, 0);
42}
43
44/*
45 * Emit constant integer.
46 */
47static inline LLVMValueRef
48l_int8_const(LLVMContextRef lc, int8 i)
49{
50 return LLVMConstInt(LLVMInt8TypeInContext(lc), i, false);
51}
52
53/*
54 * Emit constant integer.
55 */
56static inline LLVMValueRef
57l_int16_const(LLVMContextRef lc, int16 i)
58{
59 return LLVMConstInt(LLVMInt16TypeInContext(lc), i, false);
60}
61
62/*
63 * Emit constant integer.
64 */
65static inline LLVMValueRef
66l_int32_const(LLVMContextRef lc, int32 i)
67{
68 return LLVMConstInt(LLVMInt32TypeInContext(lc), i, false);
69}
70
71/*
72 * Emit constant integer.
73 */
74static inline LLVMValueRef
75l_int64_const(LLVMContextRef lc, int64 i)
76{
77 return LLVMConstInt(LLVMInt64TypeInContext(lc), i, false);
78}
79
80/*
81 * Emit constant integer.
82 */
83static inline LLVMValueRef
84l_sizet_const(size_t i)
85{
86 return LLVMConstInt(TypeSizeT, i, false);
87}
88
89/*
90 * Emit constant integer.
91 */
92static inline LLVMValueRef
93l_datum_const(Datum i)
94{
95 return LLVMConstInt(TypeDatum, i, false);
96}
97
98/*
99 * Emit constant boolean, as used for storage (e.g. global vars, structs).
100 */
101static inline LLVMValueRef
102l_sbool_const(bool i)
103{
104 return LLVMConstInt(TypeStorageBool, (int) i, false);
105}
106
107/*
108 * Emit constant boolean, as used for parameters (e.g. function parameters).
109 */
110static inline LLVMValueRef
111l_pbool_const(bool i)
112{
113 return LLVMConstInt(TypeParamBool, (int) i, false);
114}
115
116static inline LLVMValueRef
117l_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name)
118{
119 return LLVMBuildStructGEP2(b, t, v, idx, "");
120}
121
122static inline LLVMValueRef
123l_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef *indices, int32 nindices, const char *name)
124{
125 return LLVMBuildGEP2(b, t, v, indices, nindices, name);
126}
127
128static inline LLVMValueRef
129l_load(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, const char *name)
130{
131 return LLVMBuildLoad2(b, t, v, name);
132}
133
134static inline LLVMValueRef
135l_call(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef fn, LLVMValueRef *args, int32 nargs, const char *name)
136{
137 return LLVMBuildCall2(b, t, fn, args, nargs, name);
138}
139
140/*
141 * Load a pointer member idx from a struct.
142 */
143static inline LLVMValueRef
144l_load_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name)
145{
146 return l_load(b,
147 LLVMStructGetTypeAtIndex(t, idx),
148 l_struct_gep(b, t, v, idx, ""),
149 name);
150}
151
152/*
153 * Load value of a pointer, after applying one index operation.
154 */
155static inline LLVMValueRef
156l_load_gep1(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef idx, const char *name)
157{
158 return l_load(b, t, l_gep(b, t, v, &idx, 1, ""), name);
159}
160
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);
163
164/*
165 * Insert a new basic block, just before r, the name being determined by fmt
166 * and arguments.
167 */
168static inline LLVMBasicBlockRef
169l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...)
170{
171 char buf[512];
172 va_list args;
173 LLVMContextRef lc;
174
175 va_start(args, fmt);
176 vsnprintf(buf, sizeof(buf), fmt, args);
177 va_end(args);
178
179 lc = LLVMGetTypeContext(LLVMTypeOf(LLVMGetBasicBlockParent(r)));
180
181 return LLVMInsertBasicBlockInContext(lc, r, buf);
182}
183
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);
186
187/*
188 * Insert a new basic block after previous basic blocks, the name being
189 * determined by fmt and arguments.
190 */
191static inline LLVMBasicBlockRef
192l_bb_append_v(LLVMValueRef f, const char *fmt,...)
193{
194 char buf[512];
195 va_list args;
196 LLVMContextRef lc;
197
198 va_start(args, fmt);
199 vsnprintf(buf, sizeof(buf), fmt, args);
200 va_end(args);
201
202 lc = LLVMGetTypeContext(LLVMTypeOf(f));
203
204 return LLVMAppendBasicBlockInContext(lc, f, buf);
205}
206
207/*
208 * Mark a callsite as readonly.
209 */
210static inline void
211l_callsite_ro(LLVMValueRef f)
212{
213 const char argname[] = "readonly";
214 LLVMAttributeRef ref;
215
216 ref = LLVMCreateStringAttribute(LLVMGetTypeContext(LLVMTypeOf(f)),
217 argname,
218 sizeof(argname) - 1,
219 NULL, 0);
220
221 LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, ref);
222}
223
224/*
225 * Mark a callsite as alwaysinline.
226 */
227static inline void
228l_callsite_alwaysinline(LLVMValueRef f)
229{
230 const char argname[] = "alwaysinline";
231 int id;
232 LLVMAttributeRef attr;
233
234 id = LLVMGetEnumAttributeKindForName(argname,
235 sizeof(argname) - 1);
236 attr = LLVMCreateEnumAttribute(LLVMGetTypeContext(LLVMTypeOf(f)), id, 0);
237 LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr);
238}
239
240/*
241 * Emit code to switch memory context.
242 */
243static inline LLVMValueRef
244l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
245{
246 const char *cmc = "CurrentMemoryContext";
247 LLVMValueRef cur;
248 LLVMValueRef ret;
249
250 if (!(cur = LLVMGetNamedGlobal(mod, cmc)))
251 cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc);
252 ret = l_load(b, l_ptr(StructMemoryContextData), cur, cmc);
253 LLVMBuildStore(b, nc, cur);
254
255 return ret;
256}
257
258/*
259 * Return pointer to the argno'th argument nullness.
260 */
261static inline LLVMValueRef
262l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
263{
264 LLVMValueRef v_args;
265 LLVMValueRef v_argn;
266
267 v_args = l_struct_gep(b,
268 StructFunctionCallInfoData,
269 v_fcinfo,
270 FIELDNO_FUNCTIONCALLINFODATA_ARGS,
271 "");
272 v_argn = l_struct_gep(b,
273 LLVMArrayType(StructNullableDatum, 0),
274 v_args,
275 argno,
276 "");
277 return l_struct_gep(b,
278 StructNullableDatum,
279 v_argn,
280 FIELDNO_NULLABLE_DATUM_ISNULL,
281 "");
282}
283
284/*
285 * Return pointer to the argno'th argument datum.
286 */
287static inline LLVMValueRef
288l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
289{
290 LLVMValueRef v_args;
291 LLVMValueRef v_argn;
292
293 v_args = l_struct_gep(b,
294 StructFunctionCallInfoData,
295 v_fcinfo,
296 FIELDNO_FUNCTIONCALLINFODATA_ARGS,
297 "");
298 v_argn = l_struct_gep(b,
299 LLVMArrayType(StructNullableDatum, 0),
300 v_args,
301 argno,
302 "");
303 return l_struct_gep(b,
304 StructNullableDatum,
305 v_argn,
306 FIELDNO_NULLABLE_DATUM_DATUM,
307 "");
308}
309
310/*
311 * Return argno'th argument nullness.
312 */
313static inline LLVMValueRef
314l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
315{
316 return l_load(b, TypeStorageBool, l_funcnullp(b, v_fcinfo, argno), "");
317}
318
319/*
320 * Return argno'th argument datum.
321 */
322static inline LLVMValueRef
323l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
324{
325 return l_load(b, TypeDatum, l_funcvaluep(b, v_fcinfo, argno), "");
326}
327
328#endif /* USE_LLVM */
329#endif
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
int64_t int64
Definition: c.h:535
#define pg_attribute_printf(f, a)
Definition: c.h:232
int16_t int16
Definition: c.h:533
int8_t int8
Definition: c.h:532
int32_t int32
Definition: c.h:534
struct cursor * cur
Definition: ecpg.c:29
#define FIELDNO_FUNCTIONCALLINFODATA_ARGS
Definition: fmgr.h:94
b
int b
Definition: isn.c:74
i
int i
Definition: isn.c:77
LLVMTypeRef StructFunctionCallInfoData
Definition: llvmjit.c:70
LLVMTypeRef TypeParamBool
Definition: llvmjit.c:58
LLVMTypeRef StructMemoryContextData
Definition: llvmjit.c:69
LLVMTypeRef TypeSizeT
Definition: llvmjit.c:56
LLVMTypeRef TypeStorageBool
Definition: llvmjit.c:59
LLVMTypeRef TypeDatum
Definition: llvmjit.c:57
LLVMTypeRef StructNullableDatum
Definition: llvmjit.c:61
static char * buf
Definition: pg_test_fsync.c:72
#define vsnprintf
Definition: port.h:238
#define FIELDNO_NULLABLE_DATUM_ISNULL
Definition: postgres.h:88
#define FIELDNO_NULLABLE_DATUM_DATUM
Definition: postgres.h:86
uint64_t Datum
Definition: postgres.h:70
c
char * c
Definition: preproc-cursor.c:31
static void * fn(void *arg)
Definition: thread-alloc.c:119
const char * type
const char * name

AltStyle によって変換されたページ (->オリジナル) /