mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 14:01:27 +02:00
jit: Reference function pointer types via llvmjit_types.c.
It is error prone (see 5da871bfa1
) 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
This commit is contained in:
parent
62ee703313
commit
df99ddc70b
@ -367,6 +367,47 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return type of a variable in llvmjit_types.c. This is useful to keep types
|
||||||
|
* in sync between plain C and JIT related code.
|
||||||
|
*/
|
||||||
|
LLVMTypeRef
|
||||||
|
llvm_pg_var_type(const char *varname)
|
||||||
|
{
|
||||||
|
LLVMValueRef v_srcvar;
|
||||||
|
LLVMTypeRef typ;
|
||||||
|
|
||||||
|
/* this'll return a *pointer* to the global */
|
||||||
|
v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname);
|
||||||
|
if (!v_srcvar)
|
||||||
|
elog(ERROR, "variable %s not in llvmjit_types.c", varname);
|
||||||
|
|
||||||
|
/* look at the contained type */
|
||||||
|
typ = LLVMTypeOf(v_srcvar);
|
||||||
|
Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
|
||||||
|
typ = LLVMGetElementType(typ);
|
||||||
|
Assert(typ != NULL);
|
||||||
|
|
||||||
|
return typ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return function type of a variable in llvmjit_types.c. This is useful to
|
||||||
|
* keep function types in sync between C and JITed code.
|
||||||
|
*/
|
||||||
|
LLVMTypeRef
|
||||||
|
llvm_pg_var_func_type(const char *varname)
|
||||||
|
{
|
||||||
|
LLVMTypeRef typ = llvm_pg_var_type(varname);
|
||||||
|
|
||||||
|
/* look at the contained type */
|
||||||
|
Assert(LLVMGetTypeKind(typ) == LLVMPointerTypeKind);
|
||||||
|
typ = LLVMGetElementType(typ);
|
||||||
|
Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMFunctionTypeKind);
|
||||||
|
|
||||||
|
return typ;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return declaration for a function referenced in llvmjit_types.c, adding it
|
* Return declaration for a function referenced in llvmjit_types.c, adding it
|
||||||
* to the module if necessary.
|
* to the module if necessary.
|
||||||
@ -889,26 +930,6 @@ llvm_shutdown(int code, Datum arg)
|
|||||||
#endif /* LLVM_VERSION_MAJOR > 11 */
|
#endif /* LLVM_VERSION_MAJOR > 11 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helper for llvm_create_types, returning a global var's type */
|
|
||||||
static LLVMTypeRef
|
|
||||||
load_type(LLVMModuleRef mod, const char *name)
|
|
||||||
{
|
|
||||||
LLVMValueRef value;
|
|
||||||
LLVMTypeRef typ;
|
|
||||||
|
|
||||||
/* this'll return a *pointer* to the global */
|
|
||||||
value = LLVMGetNamedGlobal(mod, name);
|
|
||||||
if (!value)
|
|
||||||
elog(ERROR, "type %s is unknown", name);
|
|
||||||
|
|
||||||
/* therefore look at the contained type and return that */
|
|
||||||
typ = LLVMTypeOf(value);
|
|
||||||
Assert(typ != NULL);
|
|
||||||
typ = LLVMGetElementType(typ);
|
|
||||||
Assert(typ != NULL);
|
|
||||||
return typ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* helper for llvm_create_types, returning a function's return type */
|
/* helper for llvm_create_types, returning a function's return type */
|
||||||
static LLVMTypeRef
|
static LLVMTypeRef
|
||||||
load_return_type(LLVMModuleRef mod, const char *name)
|
load_return_type(LLVMModuleRef mod, const char *name)
|
||||||
@ -970,24 +991,24 @@ llvm_create_types(void)
|
|||||||
llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
|
llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
|
||||||
llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
|
llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
|
||||||
|
|
||||||
TypeSizeT = load_type(llvm_types_module, "TypeSizeT");
|
TypeSizeT = llvm_pg_var_type("TypeSizeT");
|
||||||
TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
|
TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
|
||||||
TypeStorageBool = load_type(llvm_types_module, "TypeStorageBool");
|
TypeStorageBool = llvm_pg_var_type("TypeStorageBool");
|
||||||
TypePGFunction = load_type(llvm_types_module, "TypePGFunction");
|
TypePGFunction = llvm_pg_var_type("TypePGFunction");
|
||||||
StructNullableDatum = load_type(llvm_types_module, "StructNullableDatum");
|
StructNullableDatum = llvm_pg_var_type("StructNullableDatum");
|
||||||
StructExprContext = load_type(llvm_types_module, "StructExprContext");
|
StructExprContext = llvm_pg_var_type("StructExprContext");
|
||||||
StructExprEvalStep = load_type(llvm_types_module, "StructExprEvalStep");
|
StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
|
||||||
StructExprState = load_type(llvm_types_module, "StructExprState");
|
StructExprState = llvm_pg_var_type("StructExprState");
|
||||||
StructFunctionCallInfoData = load_type(llvm_types_module, "StructFunctionCallInfoData");
|
StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
|
||||||
StructMemoryContextData = load_type(llvm_types_module, "StructMemoryContextData");
|
StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
|
||||||
StructTupleTableSlot = load_type(llvm_types_module, "StructTupleTableSlot");
|
StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
|
||||||
StructHeapTupleTableSlot = load_type(llvm_types_module, "StructHeapTupleTableSlot");
|
StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
|
||||||
StructMinimalTupleTableSlot = load_type(llvm_types_module, "StructMinimalTupleTableSlot");
|
StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot");
|
||||||
StructHeapTupleData = load_type(llvm_types_module, "StructHeapTupleData");
|
StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData");
|
||||||
StructTupleDescData = load_type(llvm_types_module, "StructTupleDescData");
|
StructTupleDescData = llvm_pg_var_type("StructTupleDescData");
|
||||||
StructAggState = load_type(llvm_types_module, "StructAggState");
|
StructAggState = llvm_pg_var_type("StructAggState");
|
||||||
StructAggStatePerGroupData = load_type(llvm_types_module, "StructAggStatePerGroupData");
|
StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
|
||||||
StructAggStatePerTransData = load_type(llvm_types_module, "StructAggStatePerTransData");
|
StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
|
||||||
|
|
||||||
AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
|
AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,6 @@ llvm_compile_expr(ExprState *state)
|
|||||||
|
|
||||||
LLVMBuilderRef b;
|
LLVMBuilderRef b;
|
||||||
LLVMModuleRef mod;
|
LLVMModuleRef mod;
|
||||||
LLVMTypeRef eval_sig;
|
|
||||||
LLVMValueRef eval_fn;
|
LLVMValueRef eval_fn;
|
||||||
LLVMBasicBlockRef entry;
|
LLVMBasicBlockRef entry;
|
||||||
LLVMBasicBlockRef *opblocks;
|
LLVMBasicBlockRef *opblocks;
|
||||||
@ -149,19 +148,9 @@ llvm_compile_expr(ExprState *state)
|
|||||||
|
|
||||||
funcname = llvm_expand_funcname(context, "evalexpr");
|
funcname = llvm_expand_funcname(context, "evalexpr");
|
||||||
|
|
||||||
/* Create the signature and function */
|
/* create function */
|
||||||
{
|
eval_fn = LLVMAddFunction(mod, funcname,
|
||||||
LLVMTypeRef param_types[3];
|
llvm_pg_var_func_type("TypeExprStateEvalFunc"));
|
||||||
|
|
||||||
param_types[0] = l_ptr(StructExprState); /* state */
|
|
||||||
param_types[1] = l_ptr(StructExprContext); /* econtext */
|
|
||||||
param_types[2] = l_ptr(TypeStorageBool); /* isnull */
|
|
||||||
|
|
||||||
eval_sig = LLVMFunctionType(TypeSizeT,
|
|
||||||
param_types, lengthof(param_types),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
eval_fn = LLVMAddFunction(mod, funcname, eval_sig);
|
|
||||||
LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
|
LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
|
||||||
LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
|
LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
|
||||||
llvm_copy_attributes(AttributeTemplate, eval_fn);
|
llvm_copy_attributes(AttributeTemplate, eval_fn);
|
||||||
@ -1086,24 +1075,16 @@ llvm_compile_expr(ExprState *state)
|
|||||||
|
|
||||||
case EEOP_PARAM_CALLBACK:
|
case EEOP_PARAM_CALLBACK:
|
||||||
{
|
{
|
||||||
LLVMTypeRef param_types[3];
|
|
||||||
LLVMValueRef v_params[3];
|
|
||||||
LLVMTypeRef v_functype;
|
LLVMTypeRef v_functype;
|
||||||
LLVMValueRef v_func;
|
LLVMValueRef v_func;
|
||||||
|
LLVMValueRef v_params[3];
|
||||||
|
|
||||||
param_types[0] = l_ptr(StructExprState);
|
v_functype = llvm_pg_var_func_type("TypeExecEvalSubroutine");
|
||||||
param_types[1] = l_ptr(TypeSizeT);
|
|
||||||
param_types[2] = l_ptr(StructExprContext);
|
|
||||||
|
|
||||||
v_functype = LLVMFunctionType(LLVMVoidType(),
|
|
||||||
param_types,
|
|
||||||
lengthof(param_types),
|
|
||||||
false);
|
|
||||||
v_func = l_ptr_const(op->d.cparam.paramfunc,
|
v_func = l_ptr_const(op->d.cparam.paramfunc,
|
||||||
l_ptr(v_functype));
|
LLVMPointerType(v_functype, 0));
|
||||||
|
|
||||||
v_params[0] = v_state;
|
v_params[0] = v_state;
|
||||||
v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT));
|
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
|
||||||
v_params[2] = v_econtext;
|
v_params[2] = v_econtext;
|
||||||
LLVMBuildCall(b,
|
LLVMBuildCall(b,
|
||||||
v_func,
|
v_func,
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
PGFunction TypePGFunction;
|
PGFunction TypePGFunction;
|
||||||
size_t TypeSizeT;
|
size_t TypeSizeT;
|
||||||
bool TypeStorageBool;
|
bool TypeStorageBool;
|
||||||
|
ExprStateEvalFunc TypeExprStateEvalFunc;
|
||||||
|
ExecEvalSubroutine TypeExecEvalSubroutine;
|
||||||
|
|
||||||
NullableDatum StructNullableDatum;
|
NullableDatum StructNullableDatum;
|
||||||
AggState StructAggState;
|
AggState StructAggState;
|
||||||
|
@ -92,6 +92,8 @@ extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context);
|
|||||||
extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
|
extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
|
||||||
extern void *llvm_get_function(LLVMJitContext *context, const char *funcname);
|
extern void *llvm_get_function(LLVMJitContext *context, const char *funcname);
|
||||||
extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname);
|
extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname);
|
||||||
|
extern LLVMTypeRef llvm_pg_var_type(const char *varname);
|
||||||
|
extern LLVMTypeRef llvm_pg_var_func_type(const char *varname);
|
||||||
extern LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname);
|
extern LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname);
|
||||||
extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
|
extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
|
||||||
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,
|
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,
|
||||||
|
Loading…
Reference in New Issue
Block a user