aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2020-02-06 22:13:52 -0800
committerAndres Freund <andres@anarazel.de>2020-02-06 22:29:14 -0800
commitb059d2f45685a946da061ee15692fa306bd67f12 (patch)
treee25766aa5b1d63796236c8c3a8e17e7be94531fe
parentc4f3b63caba02b087519d58cb9bf4990b9c8ec45 (diff)
downloadpostgresql-b059d2f45685a946da061ee15692fa306bd67f12.tar.gz
postgresql-b059d2f45685a946da061ee15692fa306bd67f12.zip
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
-rw-r--r--src/backend/jit/llvm/llvmjit.c97
-rw-r--r--src/backend/jit/llvm/llvmjit_deform.c6
-rw-r--r--src/backend/jit/llvm/llvmjit_expr.c155
-rw-r--r--src/backend/jit/llvm/llvmjit_types.c44
-rw-r--r--src/include/jit/llvmjit.h13
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,