diff options
author | Andres Freund <andres@anarazel.de> | 2020-12-07 13:16:55 -0800 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2020-12-08 16:55:20 -0800 |
commit | df99ddc70b971a991c5111a33f2f08bd7945d5c2 (patch) | |
tree | a217066cdd0309b8fb29c3eb5f46973547f8e71c /src/backend/jit/llvm/llvmjit.c | |
parent | 62ee70331336161cb44733b6c3e0811696d962aa (diff) | |
download | postgresql-df99ddc70b971a991c5111a33f2f08bd7945d5c2.tar.gz postgresql-df99ddc70b971a991c5111a33f2f08bd7945d5c2.zip |
jit: Reference function pointer types via llvmjit_types.c.
It is error prone (see 5da871bfa1b) 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
Diffstat (limited to 'src/backend/jit/llvm/llvmjit.c')
-rw-r--r-- | src/backend/jit/llvm/llvmjit.c | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 40a439326c6..9c4fc75f656 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -368,6 +368,47 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) } /* + * 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 * to the module if necessary. * @@ -889,26 +930,6 @@ llvm_shutdown(int code, Datum arg) #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 */ static LLVMTypeRef load_return_type(LLVMModuleRef mod, const char *name) @@ -970,24 +991,24 @@ llvm_create_types(void) llvm_triple = pstrdup(LLVMGetTarget(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"); - TypeStorageBool = load_type(llvm_types_module, "TypeStorageBool"); - TypePGFunction = load_type(llvm_types_module, "TypePGFunction"); - StructNullableDatum = load_type(llvm_types_module, "StructNullableDatum"); - StructExprContext = load_type(llvm_types_module, "StructExprContext"); - StructExprEvalStep = load_type(llvm_types_module, "StructExprEvalStep"); - StructExprState = load_type(llvm_types_module, "StructExprState"); - StructFunctionCallInfoData = load_type(llvm_types_module, "StructFunctionCallInfoData"); - StructMemoryContextData = load_type(llvm_types_module, "StructMemoryContextData"); - StructTupleTableSlot = load_type(llvm_types_module, "StructTupleTableSlot"); - StructHeapTupleTableSlot = load_type(llvm_types_module, "StructHeapTupleTableSlot"); - StructMinimalTupleTableSlot = load_type(llvm_types_module, "StructMinimalTupleTableSlot"); - StructHeapTupleData = load_type(llvm_types_module, "StructHeapTupleData"); - StructTupleDescData = load_type(llvm_types_module, "StructTupleDescData"); - StructAggState = load_type(llvm_types_module, "StructAggState"); - StructAggStatePerGroupData = load_type(llvm_types_module, "StructAggStatePerGroupData"); - StructAggStatePerTransData = load_type(llvm_types_module, "StructAggStatePerTransData"); + TypeStorageBool = llvm_pg_var_type("TypeStorageBool"); + TypePGFunction = llvm_pg_var_type("TypePGFunction"); + StructNullableDatum = llvm_pg_var_type("StructNullableDatum"); + StructExprContext = llvm_pg_var_type("StructExprContext"); + StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep"); + StructExprState = llvm_pg_var_type("StructExprState"); + StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData"); + StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData"); + StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot"); + StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot"); + StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot"); + StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData"); + StructTupleDescData = llvm_pg_var_type("StructTupleDescData"); + StructAggState = llvm_pg_var_type("StructAggState"); + StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData"); + StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData"); AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate"); } |