Skip to content

Commit df99ddc

Browse files
committed
jit: Reference function pointer types via llvmjit_types.c.
It is error prone (see 5da871b) and verbose to manually create function types. Add a helper that can reference a function pointer type via llvmjit_types.c and and convert existing instances of manual creation. Author: Andres Freund <andres@anarazel.de> Reviewed-By: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/20201207212142.wz5tnbk2jsaqzogb@alap3.anarazel.de
1 parent 62ee703 commit df99ddc

File tree

4 files changed

+69
-63
lines changed

4 files changed

+69
-63
lines changed

src/backend/jit/llvm/llvmjit.c

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,47 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
367367
return NULL;
368368
}
369369

370+
/*
371+
* Return type of a variable in llvmjit_types.c. This is useful to keep types
372+
* in sync between plain C and JIT related code.
373+
*/
374+
LLVMTypeRef
375+
llvm_pg_var_type(const char *varname)
376+
{
377+
LLVMValueRef v_srcvar;
378+
LLVMTypeRef typ;
379+
380+
/* this'll return a *pointer* to the global */
381+
v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname);
382+
if (!v_srcvar)
383+
elog(ERROR, "variable %s not in llvmjit_types.c", varname);
384+
385+
/* look at the contained type */
386+
typ = LLVMTypeOf(v_srcvar);
387+
Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
388+
typ = LLVMGetElementType(typ);
389+
Assert(typ != NULL);
390+
391+
return typ;
392+
}
393+
394+
/*
395+
* Return function type of a variable in llvmjit_types.c. This is useful to
396+
* keep function types in sync between C and JITed code.
397+
*/
398+
LLVMTypeRef
399+
llvm_pg_var_func_type(const char *varname)
400+
{
401+
LLVMTypeRef typ = llvm_pg_var_type(varname);
402+
403+
/* look at the contained type */
404+
Assert(LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
405+
typ = LLVMGetElementType(typ);
406+
Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMFunctionTypeKind);
407+
408+
return typ;
409+
}
410+
370411
/*
371412
* Return declaration for a function referenced in llvmjit_types.c, adding it
372413
* to the module if necessary.
@@ -889,26 +930,6 @@ llvm_shutdown(int code, Datum arg)
889930
#endif /* LLVM_VERSION_MAJOR > 11 */
890931
}
891932

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-
912933
/* helper for llvm_create_types, returning a function's return type */
913934
static LLVMTypeRef
914935
load_return_type(LLVMModuleRef mod, const char *name)
@@ -970,24 +991,24 @@ llvm_create_types(void)
970991
llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
971992
llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
972993

973-
TypeSizeT = load_type(llvm_types_module, "TypeSizeT");
994+
TypeSizeT = llvm_pg_var_type("TypeSizeT");
974995
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");
996+
TypeStorageBool = llvm_pg_var_type("TypeStorageBool");
997+
TypePGFunction = llvm_pg_var_type("TypePGFunction");
998+
StructNullableDatum = llvm_pg_var_type("StructNullableDatum");
999+
StructExprContext = llvm_pg_var_type("StructExprContext");
1000+
StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
1001+
StructExprState = llvm_pg_var_type("StructExprState");
1002+
StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
1003+
StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
1004+
StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
1005+
StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
1006+
StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot");
1007+
StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData");
1008+
StructTupleDescData = llvm_pg_var_type("StructTupleDescData");
1009+
StructAggState = llvm_pg_var_type("StructAggState");
1010+
StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
1011+
StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
9911012

9921013
AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
9931014
}

src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ llvm_compile_expr(ExprState *state)
8484

8585
LLVMBuilderRef b;
8686
LLVMModuleRef mod;
87-
LLVMTypeRef eval_sig;
8887
LLVMValueRef eval_fn;
8988
LLVMBasicBlockRef entry;
9089
LLVMBasicBlockRef *opblocks;
@@ -149,19 +148,9 @@ llvm_compile_expr(ExprState *state)
149148

150149
funcname = llvm_expand_funcname(context, "evalexpr");
151150

152-
/* Create the signature and function */
153-
{
154-
LLVMTypeRef param_types[3];
155-
156-
param_types[0] = l_ptr(StructExprState); /* state */
157-
param_types[1] = l_ptr(StructExprContext); /* econtext */
158-
param_types[2] = l_ptr(TypeStorageBool); /* isnull */
159-
160-
eval_sig = LLVMFunctionType(TypeSizeT,
161-
param_types, lengthof(param_types),
162-
false);
163-
}
164-
eval_fn = LLVMAddFunction(mod, funcname, eval_sig);
151+
/* create function */
152+
eval_fn = LLVMAddFunction(mod, funcname,
153+
llvm_pg_var_func_type("TypeExprStateEvalFunc"));
165154
LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
166155
LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
167156
llvm_copy_attributes(AttributeTemplate, eval_fn);
@@ -1086,24 +1075,16 @@ llvm_compile_expr(ExprState *state)
10861075

10871076
case EEOP_PARAM_CALLBACK:
10881077
{
1089-
LLVMTypeRef param_types[3];
1090-
LLVMValueRef v_params[3];
10911078
LLVMTypeRef v_functype;
10921079
LLVMValueRef v_func;
1080+
LLVMValueRef v_params[3];
10931081

1094-
param_types[0] = l_ptr(StructExprState);
1095-
param_types[1] = l_ptr(TypeSizeT);
1096-
param_types[2] = l_ptr(StructExprContext);
1097-
1098-
v_functype = LLVMFunctionType(LLVMVoidType(),
1099-
param_types,
1100-
lengthof(param_types),
1101-
false);
1082+
v_functype = llvm_pg_var_func_type("TypeExecEvalSubroutine");
11021083
v_func = l_ptr_const(op->d.cparam.paramfunc,
1103-
l_ptr(v_functype));
1084+
LLVMPointerType(v_functype, 0));
11041085

11051086
v_params[0] = v_state;
1106-
v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT));
1087+
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
11071088
v_params[2] = v_econtext;
11081089
LLVMBuildCall(b,
11091090
v_func,

src/backend/jit/llvm/llvmjit_types.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
PGFunction TypePGFunction;
4949
size_t TypeSizeT;
5050
bool TypeStorageBool;
51+
ExprStateEvalFunc TypeExprStateEvalFunc;
52+
ExecEvalSubroutine TypeExecEvalSubroutine;
5153

5254
NullableDatum StructNullableDatum;
5355
AggState StructAggState;

src/include/jit/llvmjit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context);
9292
extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
9393
extern void *llvm_get_function(LLVMJitContext *context, const char *funcname);
9494
extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname);
95+
extern LLVMTypeRef llvm_pg_var_type(const char *varname);
96+
extern LLVMTypeRef llvm_pg_var_func_type(const char *varname);
9597
extern LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname);
9698
extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
9799
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,

0 commit comments

Comments
 (0)