From b059d2f45685a946da061ee15692fa306bd67f12 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Thu, 6 Feb 2020 22:13:52 -0800 Subject: [PATCH] jit: Reference expression step functions via llvmjit_types. The main benefit of doing so is that this allows llvm to ensure that types match - previously that'd only be detected by a crash within the called function. There were a number of cases where we passed a superfluous parameter... To avoid needing to add all the functions to llvmjit.{c,h}, instead get them from the llvm module for llvmjit_types.c. Also use that for the functions from llvmjit_types already in llvmjit.h. Author: Soumyadeep Chakraborty and Andres Freund Discussion: https://postgr.es/m/CADwEdooww3wZv-sXSfatzFRwMuwa186LyTwkBfwEW6NjtooBPA@mail.gmail.com --- src/backend/jit/llvm/llvmjit.c | 97 +++++++--------- src/backend/jit/llvm/llvmjit_deform.c | 6 +- src/backend/jit/llvm/llvmjit_expr.c | 155 ++++++++++++-------------- src/backend/jit/llvm/llvmjit_types.c | 44 ++++++-- src/include/jit/llvmjit.h | 13 +-- 5 files changed, 157 insertions(+), 158 deletions(-) diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 2e77b8a1eac..af8b34aaaf3 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -76,16 +76,8 @@ LLVMTypeRef StructAggStatePerGroupData; LLVMTypeRef StructAggStatePerTransData; LLVMValueRef AttributeTemplate; -LLVMValueRef FuncStrlen; -LLVMValueRef FuncVarsizeAny; -LLVMValueRef FuncSlotGetsomeattrsInt; -LLVMValueRef FuncSlotGetmissingattrs; -LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal; -LLVMValueRef FuncExecEvalSubscriptingRef; -LLVMValueRef FuncExecEvalSysVar; -LLVMValueRef FuncExecAggTransReparent; -LLVMValueRef FuncExecAggInitGroup; +LLVMModuleRef llvm_types_module = NULL; static bool llvm_session_initialized = false; static size_t llvm_generation = 0; @@ -301,26 +293,32 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) } /* - * Return declaration for passed function, adding it to the module if - * necessary. + * Return declaration for a function referenced in llvmjit_types.c, adding it + * to the module if necessary. * - * This is used to make functions imported by llvm_create_types() known to the - * module that's currently being worked on. + * This is used to make functions discovered via llvm_create_types() known to + * the module that's currently being worked on. */ LLVMValueRef -llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src) +llvm_pg_func(LLVMModuleRef mod, const char *funcname) { + LLVMValueRef v_srcfn; LLVMValueRef v_fn; /* don't repeatedly add function */ - v_fn = LLVMGetNamedFunction(mod, LLVMGetValueName(v_src)); + v_fn = LLVMGetNamedFunction(mod, funcname); if (v_fn) return v_fn; + v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname); + + if (!v_srcfn) + elog(ERROR, "function %s not in llvmjit_types.c", funcname); + v_fn = LLVMAddFunction(mod, - LLVMGetValueName(v_src), - LLVMGetElementType(LLVMTypeOf(v_src))); - llvm_copy_attributes(v_src, v_fn); + funcname, + LLVMGetElementType(LLVMTypeOf(v_srcfn))); + llvm_copy_attributes(v_srcfn, v_fn); return v_fn; } @@ -775,7 +773,6 @@ llvm_create_types(void) char path[MAXPGPATH]; LLVMMemoryBufferRef buf; char *msg; - LLVMModuleRef mod = NULL; snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc"); @@ -787,7 +784,7 @@ llvm_create_types(void) } /* eagerly load contents, going to need it all */ - if (LLVMParseBitcode2(buf, &mod)) + if (LLVMParseBitcode2(buf, &llvm_types_module)) { elog(ERROR, "LLVMParseBitcode2 of %s failed", path); } @@ -797,43 +794,29 @@ llvm_create_types(void) * Load triple & layout from clang emitted file so we're guaranteed to be * compatible. */ - llvm_triple = pstrdup(LLVMGetTarget(mod)); - llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod)); - - TypeSizeT = load_type(mod, "TypeSizeT"); - TypeParamBool = load_return_type(mod, "FunctionReturningBool"); - TypeStorageBool = load_type(mod, "TypeStorageBool"); - TypePGFunction = load_type(mod, "TypePGFunction"); - StructNullableDatum = load_type(mod, "StructNullableDatum"); - StructExprContext = load_type(mod, "StructExprContext"); - StructExprEvalStep = load_type(mod, "StructExprEvalStep"); - StructExprState = load_type(mod, "StructExprState"); - StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData"); - StructMemoryContextData = load_type(mod, "StructMemoryContextData"); - StructTupleTableSlot = load_type(mod, "StructTupleTableSlot"); - StructHeapTupleTableSlot = load_type(mod, "StructHeapTupleTableSlot"); - StructMinimalTupleTableSlot = load_type(mod, "StructMinimalTupleTableSlot"); - StructHeapTupleData = load_type(mod, "StructHeapTupleData"); - StructTupleDescData = load_type(mod, "StructTupleDescData"); - StructAggState = load_type(mod, "StructAggState"); - StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData"); - StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData"); - - AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate"); - FuncStrlen = LLVMGetNamedFunction(mod, "strlen"); - FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any"); - FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(mod, "slot_getsomeattrs_int"); - FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs"); - FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal"); - FuncExecEvalSubscriptingRef = LLVMGetNamedFunction(mod, "ExecEvalSubscriptingRef"); - FuncExecEvalSysVar = LLVMGetNamedFunction(mod, "ExecEvalSysVar"); - FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent"); - FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup"); - - /* - * Leave the module alive, otherwise references to function would be - * dangling. - */ + llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module)); + llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module)); + + TypeSizeT = load_type(llvm_types_module, "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"); + + AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate"); } /* diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c index ad2d3e5a5c8..d7a7b328e8b 100644 --- a/src/backend/jit/llvm/llvmjit_deform.c +++ b/src/backend/jit/llvm/llvmjit_deform.c @@ -331,7 +331,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, v_params[0] = v_slot; v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), ""); v_params[2] = l_int32_const(natts); - LLVMBuildCall(b, llvm_get_decl(mod, FuncSlotGetmissingattrs), + LLVMBuildCall(b, llvm_pg_func(mod, "slot_getmissingattrs"), v_params, lengthof(v_params), ""); LLVMBuildBr(b, b_find_start); } @@ -682,7 +682,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, else if (att->attlen == -1) { v_incby = LLVMBuildCall(b, - llvm_get_decl(mod, FuncVarsizeAny), + llvm_pg_func(mod, "varsize_any"), &v_attdatap, 1, "varsize_any"); l_callsite_ro(v_incby); @@ -691,7 +691,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, else if (att->attlen == -2) { v_incby = LLVMBuildCall(b, - llvm_get_decl(mod, FuncStrlen), + llvm_pg_func(mod, "strlen"), &v_attdatap, 1, "strlen"); l_callsite_ro(v_incby); diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c index 44a221b9a3a..cea0d6fa5ce 100644 --- a/src/backend/jit/llvm/llvmjit_expr.c +++ b/src/backend/jit/llvm/llvmjit_expr.c @@ -57,12 +57,19 @@ static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool * static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, LLVMModuleRef mod, FunctionCallInfo fcinfo, LLVMValueRef *v_fcinfo_isnull); -static void build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, - const char *funcname, - LLVMValueRef v_state, LLVMValueRef v_econtext, - ExprEvalStep *op); +static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, + const char *funcname, + LLVMValueRef v_state, + ExprEvalStep *op, + int natts, LLVMValueRef v_args[]); static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod); +/* macro making it easier to call ExecEval* functions */ +#define build_EvalXFunc(b, mod, funcname, v_state, op, ...) \ + build_EvalXFuncInt(b, mod, funcname, v_state, op, \ + lengthof(((LLVMValueRef[]){__VA_ARGS__})), \ + ((LLVMValueRef[]){__VA_ARGS__})) + /* * JIT compile expression. @@ -344,7 +351,7 @@ llvm_compile_expr(ExprState *state) params[1] = l_int32_const(op->d.fetch.last_var); LLVMBuildCall(b, - llvm_get_decl(mod, FuncSlotGetsomeattrsInt), + llvm_pg_func(mod, "slot_getsomeattrs_int"), params, lengthof(params), ""); } @@ -393,7 +400,6 @@ llvm_compile_expr(ExprState *state) case EEOP_SCAN_SYSVAR: { LLVMValueRef v_slot; - LLVMValueRef v_params[4]; if (opcode == EEOP_INNER_SYSVAR) v_slot = v_innerslot; @@ -402,14 +408,8 @@ llvm_compile_expr(ExprState *state) else v_slot = v_scanslot; - v_params[0] = v_state; - v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); - v_params[2] = v_econtext; - v_params[3] = v_slot; - - LLVMBuildCall(b, - llvm_get_decl(mod, FuncExecEvalSysVar), - v_params, lengthof(v_params), ""); + build_EvalXFunc(b, mod, "ExecEvalSysVar", + v_state, op, v_econtext, v_slot); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -417,7 +417,7 @@ llvm_compile_expr(ExprState *state) case EEOP_WHOLEROW: build_EvalXFunc(b, mod, "ExecEvalWholeRowVar", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -514,7 +514,7 @@ llvm_compile_expr(ExprState *state) v_params[0] = v_value; v_value = LLVMBuildCall(b, - llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal), + llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"), v_params, lengthof(v_params), ""); /* @@ -631,14 +631,14 @@ llvm_compile_expr(ExprState *state) case EEOP_FUNCEXPR_FUSAGE: build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_FUNCEXPR_STRICT_FUSAGE: build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -999,13 +999,13 @@ llvm_compile_expr(ExprState *state) case EEOP_NULLTEST_ROWISNULL: build_EvalXFunc(b, mod, "ExecEvalRowNull", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_NULLTEST_ROWISNOTNULL: build_EvalXFunc(b, mod, "ExecEvalRowNotNull", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -1076,13 +1076,13 @@ llvm_compile_expr(ExprState *state) case EEOP_PARAM_EXEC: build_EvalXFunc(b, mod, "ExecEvalParamExec", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_PARAM_EXTERN: build_EvalXFunc(b, mod, "ExecEvalParamExtern", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -1117,19 +1117,19 @@ llvm_compile_expr(ExprState *state) case EEOP_SBSREF_OLD: build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_SBSREF_ASSIGN: build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_SBSREF_FETCH: build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -1221,7 +1221,7 @@ llvm_compile_expr(ExprState *state) v_params[0] = v_value; v_ret = LLVMBuildCall(b, - llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal), + llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"), v_params, lengthof(v_params), ""); LLVMBuildStore(b, v_ret, v_resvaluep); @@ -1539,37 +1539,37 @@ llvm_compile_expr(ExprState *state) case EEOP_SQLVALUEFUNCTION: build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_CURRENTOFEXPR: build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_NEXTVALUEEXPR: build_EvalXFunc(b, mod, "ExecEvalNextValueExpr", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_ARRAYEXPR: build_EvalXFunc(b, mod, "ExecEvalArrayExpr", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_ARRAYCOERCE: build_EvalXFunc(b, mod, "ExecEvalArrayCoerce", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_ROW: build_EvalXFunc(b, mod, "ExecEvalRow", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -1724,40 +1724,35 @@ llvm_compile_expr(ExprState *state) case EEOP_MINMAX: build_EvalXFunc(b, mod, "ExecEvalMinMax", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_FIELDSELECT: build_EvalXFunc(b, mod, "ExecEvalFieldSelect", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_FIELDSTORE_DEFORM: build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_FIELDSTORE_FORM: build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_SBSREF_SUBSCRIPT: { int jumpdone = op->d.sbsref_subscript.jumpdone; - LLVMValueRef v_params[2]; LLVMValueRef v_ret; - v_params[0] = v_state; - v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); - v_ret = - LLVMBuildCall(b, - llvm_get_decl(mod, FuncExecEvalSubscriptingRef), - v_params, lengthof(v_params), ""); + v_ret = build_EvalXFunc(b, mod, "ExecEvalSubscriptingRef", + v_state, op); v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); LLVMBuildCondBr(b, @@ -1824,31 +1819,31 @@ llvm_compile_expr(ExprState *state) case EEOP_DOMAIN_NOTNULL: build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_DOMAIN_CHECK: build_EvalXFunc(b, mod, "ExecEvalConstraintCheck", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_CONVERT_ROWTYPE: build_EvalXFunc(b, mod, "ExecEvalConvertRowtype", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_SCALARARRAYOP: build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_XMLEXPR: build_EvalXFunc(b, mod, "ExecEvalXmlExpr", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -1883,7 +1878,7 @@ llvm_compile_expr(ExprState *state) case EEOP_GROUPING_FUNC: build_EvalXFunc(b, mod, "ExecEvalGroupingFunc", - v_state, v_econtext, op); + v_state, op); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -1919,13 +1914,13 @@ llvm_compile_expr(ExprState *state) case EEOP_SUBPLAN: build_EvalXFunc(b, mod, "ExecEvalSubPlan", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_ALTERNATIVE_SUBPLAN: build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -2138,7 +2133,7 @@ llvm_compile_expr(ExprState *state) params[2] = v_pergroupp; LLVMBuildCall(b, - llvm_get_decl(mod, FuncExecAggInitGroup), + llvm_pg_func(mod, "ExecAggInitGroup"), params, lengthof(params), ""); } @@ -2357,7 +2352,7 @@ llvm_compile_expr(ExprState *state) params[5] = LLVMBuildTrunc(b, v_transnull, TypeParamBool, ""); - v_fn = llvm_get_decl(mod, FuncExecAggTransReparent); + v_fn = llvm_pg_func(mod, "ExecAggTransReparent"); v_newval = LLVMBuildCall(b, v_fn, params, lengthof(params), @@ -2386,13 +2381,13 @@ llvm_compile_expr(ExprState *state) case EEOP_AGG_ORDERED_TRANS_DATUM: build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; case EEOP_AGG_ORDERED_TRANS_TUPLE: build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple", - v_state, v_econtext, op); + v_state, op, v_econtext); LLVMBuildBr(b, opblocks[opno + 1]); break; @@ -2504,36 +2499,34 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, /* * Implement an expression step by calling the function funcname. */ -static void -build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname, - LLVMValueRef v_state, LLVMValueRef v_econtext, - ExprEvalStep *op) +static LLVMValueRef +build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname, + LLVMValueRef v_state, ExprEvalStep *op, + int nargs, LLVMValueRef v_args[]) { - LLVMTypeRef sig; - LLVMValueRef v_fn; - LLVMTypeRef param_types[3]; - LLVMValueRef params[3]; + LLVMValueRef v_fn = llvm_pg_func(mod, funcname); + LLVMValueRef *params; + int argno = 0; + LLVMValueRef v_ret; - v_fn = LLVMGetNamedFunction(mod, funcname); - if (!v_fn) - { - param_types[0] = l_ptr(StructExprState); - param_types[1] = l_ptr(StructExprEvalStep); - param_types[2] = l_ptr(StructExprContext); - - sig = LLVMFunctionType(LLVMVoidType(), - param_types, lengthof(param_types), - false); - v_fn = LLVMAddFunction(mod, funcname, sig); - } + /* cheap pre-check as llvm just asserts out */ + if (LLVMCountParams(v_fn) != (nargs + 2)) + elog(ERROR, "parameter mismatch: %s expects %d passed %d", + funcname, LLVMCountParams(v_fn), nargs + 2); + + params = palloc(sizeof(LLVMValueRef) * (2 + nargs)); + + params[argno++] = v_state; + params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep)); + + for (int i = 0; i < nargs; i++) + params[argno++] = v_args[i]; + + v_ret = LLVMBuildCall(b, v_fn, params, argno, ""); - params[0] = v_state; - params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); - params[2] = v_econtext; + pfree(params); - LLVMBuildCall(b, - v_fn, - params, lengthof(params), ""); + return v_ret; } static LLVMValueRef diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c index 48768e6f898..0a93d5f6658 100644 --- a/src/backend/jit/llvm/llvmjit_types.c +++ b/src/backend/jit/llvm/llvmjit_types.c @@ -98,13 +98,43 @@ FunctionReturningBool(void) */ void *referenced_functions[] = { - strlen, - varsize_any, - slot_getsomeattrs_int, - slot_getmissingattrs, - MakeExpandedObjectReadOnlyInternal, + ExecAggInitGroup, + ExecAggTransReparent, + ExecEvalAggOrderedTransDatum, + ExecEvalAggOrderedTransTuple, + ExecEvalAlternativeSubPlan, + ExecEvalArrayCoerce, + ExecEvalArrayExpr, + ExecEvalConstraintCheck, + ExecEvalConstraintNotNull, + ExecEvalConvertRowtype, + ExecEvalCurrentOfExpr, + ExecEvalFieldSelect, + ExecEvalFieldStoreDeForm, + ExecEvalFieldStoreForm, + ExecEvalFuncExprFusage, + ExecEvalFuncExprStrictFusage, + ExecEvalGroupingFunc, + ExecEvalMinMax, + ExecEvalNextValueExpr, + ExecEvalParamExec, + ExecEvalParamExtern, + ExecEvalRow, + ExecEvalRowNotNull, + ExecEvalRowNull, + ExecEvalSQLValueFunction, + ExecEvalScalarArrayOp, + ExecEvalSubPlan, ExecEvalSubscriptingRef, + ExecEvalSubscriptingRefAssign, + ExecEvalSubscriptingRefFetch, + ExecEvalSubscriptingRefOld, ExecEvalSysVar, - ExecAggTransReparent, - ExecAggInitGroup + ExecEvalWholeRowVar, + ExecEvalXmlExpr, + MakeExpandedObjectReadOnlyInternal, + slot_getmissingattrs, + slot_getsomeattrs_int, + strlen, + varsize_any, }; diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h index a4eaa827354..706906c1cc8 100644 --- a/src/include/jit/llvmjit.h +++ b/src/include/jit/llvmjit.h @@ -55,6 +55,8 @@ typedef struct LLVMJitContext List *handles; } LLVMJitContext; +/* llvm module containing information about types */ +extern LLVMModuleRef llvm_types_module; /* type and struct definitions */ extern LLVMTypeRef TypeParamBool; @@ -78,15 +80,6 @@ extern LLVMTypeRef StructAggStatePerTransData; extern LLVMTypeRef StructAggStatePerGroupData; extern LLVMValueRef AttributeTemplate; -extern LLVMValueRef FuncStrlen; -extern LLVMValueRef FuncVarsizeAny; -extern LLVMValueRef FuncSlotGetmissingattrs; -extern LLVMValueRef FuncSlotGetsomeattrsInt; -extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal; -extern LLVMValueRef FuncExecEvalSubscriptingRef; -extern LLVMValueRef FuncExecEvalSysVar; -extern LLVMValueRef FuncExecAggTransReparent; -extern LLVMValueRef FuncExecAggInitGroup; extern void llvm_enter_fatal_on_oom(void); @@ -99,7 +92,7 @@ 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 LLVMValueRef llvm_get_decl(LLVMModuleRef mod, LLVMValueRef f); +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, LLVMBuilderRef builder, -- 2.39.5