]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
jit: Reference function pointer types via llvmjit_types.c.
authorAndres Freund <andres@anarazel.de>
Mon, 7 Dec 2020 21:16:55 +0000 (13:16 -0800)
committerAndres Freund <andres@anarazel.de>
Wed, 9 Dec 2020 00:55:20 +0000 (16:55 -0800)
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

src/backend/jit/llvm/llvmjit.c
src/backend/jit/llvm/llvmjit_expr.c
src/backend/jit/llvm/llvmjit_types.c
src/include/jit/llvmjit.h

index 40a439326c6fb2ee3faefc87a29650ec82e48109..9c4fc75f6567a535a173b392b1fcd0c9cd5c5184 100644 (file)
@@ -367,6 +367,47 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
        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
  * 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");
 }
index da5e3a2c1d03c56c6894dbf77111e245bdf688fd..e0d53c0d0a21d0d464bf73e4bcf65cadb53e060a 100644 (file)
@@ -84,7 +84,6 @@ llvm_compile_expr(ExprState *state)
 
        LLVMBuilderRef b;
        LLVMModuleRef mod;
-       LLVMTypeRef eval_sig;
        LLVMValueRef eval_fn;
        LLVMBasicBlockRef entry;
        LLVMBasicBlockRef *opblocks;
@@ -149,19 +148,9 @@ llvm_compile_expr(ExprState *state)
 
        funcname = llvm_expand_funcname(context, "evalexpr");
 
-       /* Create the signature and function */
-       {
-               LLVMTypeRef param_types[3];
-
-               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);
+       /* create function */
+       eval_fn = LLVMAddFunction(mod, funcname,
+                                                         llvm_pg_var_func_type("TypeExprStateEvalFunc"));
        LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
        LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
        llvm_copy_attributes(AttributeTemplate, eval_fn);
@@ -1086,24 +1075,16 @@ llvm_compile_expr(ExprState *state)
 
                        case EEOP_PARAM_CALLBACK:
                                {
-                                       LLVMTypeRef param_types[3];
-                                       LLVMValueRef v_params[3];
                                        LLVMTypeRef v_functype;
                                        LLVMValueRef v_func;
+                                       LLVMValueRef v_params[3];
 
-                                       param_types[0] = l_ptr(StructExprState);
-                                       param_types[1] = l_ptr(TypeSizeT);
-                                       param_types[2] = l_ptr(StructExprContext);
-
-                                       v_functype = LLVMFunctionType(LLVMVoidType(),
-                                                                                                 param_types,
-                                                                                                 lengthof(param_types),
-                                                                                                 false);
+                                       v_functype = llvm_pg_var_func_type("TypeExecEvalSubroutine");
                                        v_func = l_ptr_const(op->d.cparam.paramfunc,
-                                                                                l_ptr(v_functype));
+                                                                                LLVMPointerType(v_functype, 0));
 
                                        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;
                                        LLVMBuildCall(b,
                                                                  v_func,
index 1ed3cafa2f23bf81ca804e8c14815eb7d5cd7c4a..e1b23d3052407c410b25302736a2740f6a32fd8a 100644 (file)
@@ -48,6 +48,8 @@
 PGFunction     TypePGFunction;
 size_t         TypeSizeT;
 bool           TypeStorageBool;
+ExprStateEvalFunc TypeExprStateEvalFunc;
+ExecEvalSubroutine TypeExecEvalSubroutine;
 
 NullableDatum StructNullableDatum;
 AggState       StructAggState;
index 325409acd5c57d28e1333407b1508464480a0bb7..1c89075eaffe4757cffcd312f4598ef55953b81f 100644 (file)
@@ -92,6 +92,8 @@ extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context);
 extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
 extern void *llvm_get_function(LLVMJitContext *context, const 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 void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
 extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,