Commit b059d2f4 authored by Andres Freund's avatar Andres Freund

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
parent c4f3b63c
...@@ -76,16 +76,8 @@ LLVMTypeRef StructAggStatePerGroupData; ...@@ -76,16 +76,8 @@ LLVMTypeRef StructAggStatePerGroupData;
LLVMTypeRef StructAggStatePerTransData; LLVMTypeRef StructAggStatePerTransData;
LLVMValueRef AttributeTemplate; 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 bool llvm_session_initialized = false;
static size_t llvm_generation = 0; static size_t llvm_generation = 0;
...@@ -301,26 +293,32 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) ...@@ -301,26 +293,32 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
} }
/* /*
* Return declaration for passed function, adding it to the module if * Return declaration for a function referenced in llvmjit_types.c, adding it
* necessary. * to the module if necessary.
* *
* This is used to make functions imported by llvm_create_types() known to the * This is used to make functions discovered via llvm_create_types() known to
* module that's currently being worked on. * the module that's currently being worked on.
*/ */
LLVMValueRef LLVMValueRef
llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src) llvm_pg_func(LLVMModuleRef mod, const char *funcname)
{ {
LLVMValueRef v_srcfn;
LLVMValueRef v_fn; LLVMValueRef v_fn;
/* don't repeatedly add function */ /* don't repeatedly add function */
v_fn = LLVMGetNamedFunction(mod, LLVMGetValueName(v_src)); v_fn = LLVMGetNamedFunction(mod, funcname);
if (v_fn) if (v_fn)
return 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, v_fn = LLVMAddFunction(mod,
LLVMGetValueName(v_src), funcname,
LLVMGetElementType(LLVMTypeOf(v_src))); LLVMGetElementType(LLVMTypeOf(v_srcfn)));
llvm_copy_attributes(v_src, v_fn); llvm_copy_attributes(v_srcfn, v_fn);
return v_fn; return v_fn;
} }
...@@ -775,7 +773,6 @@ llvm_create_types(void) ...@@ -775,7 +773,6 @@ llvm_create_types(void)
char path[MAXPGPATH]; char path[MAXPGPATH];
LLVMMemoryBufferRef buf; LLVMMemoryBufferRef buf;
char *msg; char *msg;
LLVMModuleRef mod = NULL;
snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc"); snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
...@@ -787,7 +784,7 @@ llvm_create_types(void) ...@@ -787,7 +784,7 @@ llvm_create_types(void)
} }
/* eagerly load contents, going to need it all */ /* 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); elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
} }
...@@ -797,43 +794,29 @@ llvm_create_types(void) ...@@ -797,43 +794,29 @@ llvm_create_types(void)
* Load triple & layout from clang emitted file so we're guaranteed to be * Load triple & layout from clang emitted file so we're guaranteed to be
* compatible. * compatible.
*/ */
llvm_triple = pstrdup(LLVMGetTarget(mod)); llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod)); llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
TypeSizeT = load_type(mod, "TypeSizeT"); TypeSizeT = load_type(llvm_types_module, "TypeSizeT");
TypeParamBool = load_return_type(mod, "FunctionReturningBool"); TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
TypeStorageBool = load_type(mod, "TypeStorageBool"); TypeStorageBool = load_type(llvm_types_module, "TypeStorageBool");
TypePGFunction = load_type(mod, "TypePGFunction"); TypePGFunction = load_type(llvm_types_module, "TypePGFunction");
StructNullableDatum = load_type(mod, "StructNullableDatum"); StructNullableDatum = load_type(llvm_types_module, "StructNullableDatum");
StructExprContext = load_type(mod, "StructExprContext"); StructExprContext = load_type(llvm_types_module, "StructExprContext");
StructExprEvalStep = load_type(mod, "StructExprEvalStep"); StructExprEvalStep = load_type(llvm_types_module, "StructExprEvalStep");
StructExprState = load_type(mod, "StructExprState"); StructExprState = load_type(llvm_types_module, "StructExprState");
StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData"); StructFunctionCallInfoData = load_type(llvm_types_module, "StructFunctionCallInfoData");
StructMemoryContextData = load_type(mod, "StructMemoryContextData"); StructMemoryContextData = load_type(llvm_types_module, "StructMemoryContextData");
StructTupleTableSlot = load_type(mod, "StructTupleTableSlot"); StructTupleTableSlot = load_type(llvm_types_module, "StructTupleTableSlot");
StructHeapTupleTableSlot = load_type(mod, "StructHeapTupleTableSlot"); StructHeapTupleTableSlot = load_type(llvm_types_module, "StructHeapTupleTableSlot");
StructMinimalTupleTableSlot = load_type(mod, "StructMinimalTupleTableSlot"); StructMinimalTupleTableSlot = load_type(llvm_types_module, "StructMinimalTupleTableSlot");
StructHeapTupleData = load_type(mod, "StructHeapTupleData"); StructHeapTupleData = load_type(llvm_types_module, "StructHeapTupleData");
StructTupleDescData = load_type(mod, "StructTupleDescData"); StructTupleDescData = load_type(llvm_types_module, "StructTupleDescData");
StructAggState = load_type(mod, "StructAggState"); StructAggState = load_type(llvm_types_module, "StructAggState");
StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData"); StructAggStatePerGroupData = load_type(llvm_types_module, "StructAggStatePerGroupData");
StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData"); StructAggStatePerTransData = load_type(llvm_types_module, "StructAggStatePerTransData");
AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate"); AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "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.
*/
} }
/* /*
......
...@@ -331,7 +331,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, ...@@ -331,7 +331,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_params[0] = v_slot; v_params[0] = v_slot;
v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), ""); v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), "");
v_params[2] = l_int32_const(natts); 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), ""); v_params, lengthof(v_params), "");
LLVMBuildBr(b, b_find_start); LLVMBuildBr(b, b_find_start);
} }
...@@ -682,7 +682,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, ...@@ -682,7 +682,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
else if (att->attlen == -1) else if (att->attlen == -1)
{ {
v_incby = LLVMBuildCall(b, v_incby = LLVMBuildCall(b,
llvm_get_decl(mod, FuncVarsizeAny), llvm_pg_func(mod, "varsize_any"),
&v_attdatap, 1, &v_attdatap, 1,
"varsize_any"); "varsize_any");
l_callsite_ro(v_incby); l_callsite_ro(v_incby);
...@@ -691,7 +691,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, ...@@ -691,7 +691,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
else if (att->attlen == -2) else if (att->attlen == -2)
{ {
v_incby = LLVMBuildCall(b, v_incby = LLVMBuildCall(b,
llvm_get_decl(mod, FuncStrlen), llvm_pg_func(mod, "strlen"),
&v_attdatap, 1, "strlen"); &v_attdatap, 1, "strlen");
l_callsite_ro(v_incby); l_callsite_ro(v_incby);
......
...@@ -57,12 +57,19 @@ static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool * ...@@ -57,12 +57,19 @@ static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *
static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
LLVMModuleRef mod, FunctionCallInfo fcinfo, LLVMModuleRef mod, FunctionCallInfo fcinfo,
LLVMValueRef *v_fcinfo_isnull); LLVMValueRef *v_fcinfo_isnull);
static void build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod,
const char *funcname, const char *funcname,
LLVMValueRef v_state, LLVMValueRef v_econtext, LLVMValueRef v_state,
ExprEvalStep *op); ExprEvalStep *op,
int natts, LLVMValueRef v_args[]);
static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod); 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. * JIT compile expression.
...@@ -344,7 +351,7 @@ llvm_compile_expr(ExprState *state) ...@@ -344,7 +351,7 @@ llvm_compile_expr(ExprState *state)
params[1] = l_int32_const(op->d.fetch.last_var); params[1] = l_int32_const(op->d.fetch.last_var);
LLVMBuildCall(b, LLVMBuildCall(b,
llvm_get_decl(mod, FuncSlotGetsomeattrsInt), llvm_pg_func(mod, "slot_getsomeattrs_int"),
params, lengthof(params), ""); params, lengthof(params), "");
} }
...@@ -393,7 +400,6 @@ llvm_compile_expr(ExprState *state) ...@@ -393,7 +400,6 @@ llvm_compile_expr(ExprState *state)
case EEOP_SCAN_SYSVAR: case EEOP_SCAN_SYSVAR:
{ {
LLVMValueRef v_slot; LLVMValueRef v_slot;
LLVMValueRef v_params[4];
if (opcode == EEOP_INNER_SYSVAR) if (opcode == EEOP_INNER_SYSVAR)
v_slot = v_innerslot; v_slot = v_innerslot;
...@@ -402,14 +408,8 @@ llvm_compile_expr(ExprState *state) ...@@ -402,14 +408,8 @@ llvm_compile_expr(ExprState *state)
else else
v_slot = v_scanslot; v_slot = v_scanslot;
v_params[0] = v_state; build_EvalXFunc(b, mod, "ExecEvalSysVar",
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); v_state, op, v_econtext, v_slot);
v_params[2] = v_econtext;
v_params[3] = v_slot;
LLVMBuildCall(b,
llvm_get_decl(mod, FuncExecEvalSysVar),
v_params, lengthof(v_params), "");
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -417,7 +417,7 @@ llvm_compile_expr(ExprState *state) ...@@ -417,7 +417,7 @@ llvm_compile_expr(ExprState *state)
case EEOP_WHOLEROW: case EEOP_WHOLEROW:
build_EvalXFunc(b, mod, "ExecEvalWholeRowVar", build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -514,7 +514,7 @@ llvm_compile_expr(ExprState *state) ...@@ -514,7 +514,7 @@ llvm_compile_expr(ExprState *state)
v_params[0] = v_value; v_params[0] = v_value;
v_value = v_value =
LLVMBuildCall(b, LLVMBuildCall(b,
llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal), llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), ""); v_params, lengthof(v_params), "");
/* /*
...@@ -631,14 +631,14 @@ llvm_compile_expr(ExprState *state) ...@@ -631,14 +631,14 @@ llvm_compile_expr(ExprState *state)
case EEOP_FUNCEXPR_FUSAGE: case EEOP_FUNCEXPR_FUSAGE:
build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage", build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_FUNCEXPR_STRICT_FUSAGE: case EEOP_FUNCEXPR_STRICT_FUSAGE:
build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage", build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -999,13 +999,13 @@ llvm_compile_expr(ExprState *state) ...@@ -999,13 +999,13 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ROWISNULL: case EEOP_NULLTEST_ROWISNULL:
build_EvalXFunc(b, mod, "ExecEvalRowNull", build_EvalXFunc(b, mod, "ExecEvalRowNull",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_NULLTEST_ROWISNOTNULL: case EEOP_NULLTEST_ROWISNOTNULL:
build_EvalXFunc(b, mod, "ExecEvalRowNotNull", build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -1076,13 +1076,13 @@ llvm_compile_expr(ExprState *state) ...@@ -1076,13 +1076,13 @@ llvm_compile_expr(ExprState *state)
case EEOP_PARAM_EXEC: case EEOP_PARAM_EXEC:
build_EvalXFunc(b, mod, "ExecEvalParamExec", build_EvalXFunc(b, mod, "ExecEvalParamExec",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_PARAM_EXTERN: case EEOP_PARAM_EXTERN:
build_EvalXFunc(b, mod, "ExecEvalParamExtern", build_EvalXFunc(b, mod, "ExecEvalParamExtern",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -1117,19 +1117,19 @@ llvm_compile_expr(ExprState *state) ...@@ -1117,19 +1117,19 @@ llvm_compile_expr(ExprState *state)
case EEOP_SBSREF_OLD: case EEOP_SBSREF_OLD:
build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld", build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_SBSREF_ASSIGN: case EEOP_SBSREF_ASSIGN:
build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign", build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_SBSREF_FETCH: case EEOP_SBSREF_FETCH:
build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch", build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -1221,7 +1221,7 @@ llvm_compile_expr(ExprState *state) ...@@ -1221,7 +1221,7 @@ llvm_compile_expr(ExprState *state)
v_params[0] = v_value; v_params[0] = v_value;
v_ret = v_ret =
LLVMBuildCall(b, LLVMBuildCall(b,
llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal), llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), ""); v_params, lengthof(v_params), "");
LLVMBuildStore(b, v_ret, v_resvaluep); LLVMBuildStore(b, v_ret, v_resvaluep);
...@@ -1539,37 +1539,37 @@ llvm_compile_expr(ExprState *state) ...@@ -1539,37 +1539,37 @@ llvm_compile_expr(ExprState *state)
case EEOP_SQLVALUEFUNCTION: case EEOP_SQLVALUEFUNCTION:
build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction", build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_CURRENTOFEXPR: case EEOP_CURRENTOFEXPR:
build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr", build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_NEXTVALUEEXPR: case EEOP_NEXTVALUEEXPR:
build_EvalXFunc(b, mod, "ExecEvalNextValueExpr", build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_ARRAYEXPR: case EEOP_ARRAYEXPR:
build_EvalXFunc(b, mod, "ExecEvalArrayExpr", build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_ARRAYCOERCE: case EEOP_ARRAYCOERCE:
build_EvalXFunc(b, mod, "ExecEvalArrayCoerce", build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_ROW: case EEOP_ROW:
build_EvalXFunc(b, mod, "ExecEvalRow", build_EvalXFunc(b, mod, "ExecEvalRow",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -1724,40 +1724,35 @@ llvm_compile_expr(ExprState *state) ...@@ -1724,40 +1724,35 @@ llvm_compile_expr(ExprState *state)
case EEOP_MINMAX: case EEOP_MINMAX:
build_EvalXFunc(b, mod, "ExecEvalMinMax", build_EvalXFunc(b, mod, "ExecEvalMinMax",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_FIELDSELECT: case EEOP_FIELDSELECT:
build_EvalXFunc(b, mod, "ExecEvalFieldSelect", build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_FIELDSTORE_DEFORM: case EEOP_FIELDSTORE_DEFORM:
build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm", build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_FIELDSTORE_FORM: case EEOP_FIELDSTORE_FORM:
build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm", build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_SBSREF_SUBSCRIPT: case EEOP_SBSREF_SUBSCRIPT:
{ {
int jumpdone = op->d.sbsref_subscript.jumpdone; int jumpdone = op->d.sbsref_subscript.jumpdone;
LLVMValueRef v_params[2];
LLVMValueRef v_ret; LLVMValueRef v_ret;
v_params[0] = v_state; v_ret = build_EvalXFunc(b, mod, "ExecEvalSubscriptingRef",
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); v_state, op);
v_ret =
LLVMBuildCall(b,
llvm_get_decl(mod, FuncExecEvalSubscriptingRef),
v_params, lengthof(v_params), "");
v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
...@@ -1824,31 +1819,31 @@ llvm_compile_expr(ExprState *state) ...@@ -1824,31 +1819,31 @@ llvm_compile_expr(ExprState *state)
case EEOP_DOMAIN_NOTNULL: case EEOP_DOMAIN_NOTNULL:
build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull", build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_DOMAIN_CHECK: case EEOP_DOMAIN_CHECK:
build_EvalXFunc(b, mod, "ExecEvalConstraintCheck", build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_CONVERT_ROWTYPE: case EEOP_CONVERT_ROWTYPE:
build_EvalXFunc(b, mod, "ExecEvalConvertRowtype", build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_SCALARARRAYOP: case EEOP_SCALARARRAYOP:
build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp", build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_XMLEXPR: case EEOP_XMLEXPR:
build_EvalXFunc(b, mod, "ExecEvalXmlExpr", build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -1883,7 +1878,7 @@ llvm_compile_expr(ExprState *state) ...@@ -1883,7 +1878,7 @@ llvm_compile_expr(ExprState *state)
case EEOP_GROUPING_FUNC: case EEOP_GROUPING_FUNC:
build_EvalXFunc(b, mod, "ExecEvalGroupingFunc", build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
v_state, v_econtext, op); v_state, op);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -1919,13 +1914,13 @@ llvm_compile_expr(ExprState *state) ...@@ -1919,13 +1914,13 @@ llvm_compile_expr(ExprState *state)
case EEOP_SUBPLAN: case EEOP_SUBPLAN:
build_EvalXFunc(b, mod, "ExecEvalSubPlan", build_EvalXFunc(b, mod, "ExecEvalSubPlan",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_ALTERNATIVE_SUBPLAN: case EEOP_ALTERNATIVE_SUBPLAN:
build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan", build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -2138,7 +2133,7 @@ llvm_compile_expr(ExprState *state) ...@@ -2138,7 +2133,7 @@ llvm_compile_expr(ExprState *state)
params[2] = v_pergroupp; params[2] = v_pergroupp;
LLVMBuildCall(b, LLVMBuildCall(b,
llvm_get_decl(mod, FuncExecAggInitGroup), llvm_pg_func(mod, "ExecAggInitGroup"),
params, lengthof(params), params, lengthof(params),
""); "");
} }
...@@ -2357,7 +2352,7 @@ llvm_compile_expr(ExprState *state) ...@@ -2357,7 +2352,7 @@ llvm_compile_expr(ExprState *state)
params[5] = LLVMBuildTrunc(b, v_transnull, params[5] = LLVMBuildTrunc(b, v_transnull,
TypeParamBool, ""); TypeParamBool, "");
v_fn = llvm_get_decl(mod, FuncExecAggTransReparent); v_fn = llvm_pg_func(mod, "ExecAggTransReparent");
v_newval = v_newval =
LLVMBuildCall(b, v_fn, LLVMBuildCall(b, v_fn,
params, lengthof(params), params, lengthof(params),
...@@ -2386,13 +2381,13 @@ llvm_compile_expr(ExprState *state) ...@@ -2386,13 +2381,13 @@ llvm_compile_expr(ExprState *state)
case EEOP_AGG_ORDERED_TRANS_DATUM: case EEOP_AGG_ORDERED_TRANS_DATUM:
build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum", build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
case EEOP_AGG_ORDERED_TRANS_TUPLE: case EEOP_AGG_ORDERED_TRANS_TUPLE:
build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple", build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
v_state, v_econtext, op); v_state, op, v_econtext);
LLVMBuildBr(b, opblocks[opno + 1]); LLVMBuildBr(b, opblocks[opno + 1]);
break; break;
...@@ -2504,36 +2499,34 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, ...@@ -2504,36 +2499,34 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
/* /*
* Implement an expression step by calling the function funcname. * Implement an expression step by calling the function funcname.
*/ */
static void static LLVMValueRef
build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname, build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
LLVMValueRef v_state, LLVMValueRef v_econtext, LLVMValueRef v_state, ExprEvalStep *op,
ExprEvalStep *op) int nargs, LLVMValueRef v_args[])
{ {
LLVMTypeRef sig; LLVMValueRef v_fn = llvm_pg_func(mod, funcname);
LLVMValueRef v_fn; LLVMValueRef *params;
LLVMTypeRef param_types[3]; int argno = 0;
LLVMValueRef params[3]; LLVMValueRef v_ret;
v_fn = LLVMGetNamedFunction(mod, funcname); /* cheap pre-check as llvm just asserts out */
if (!v_fn) if (LLVMCountParams(v_fn) != (nargs + 2))
{ elog(ERROR, "parameter mismatch: %s expects %d passed %d",
param_types[0] = l_ptr(StructExprState); funcname, LLVMCountParams(v_fn), nargs + 2);
param_types[1] = l_ptr(StructExprEvalStep);
param_types[2] = l_ptr(StructExprContext); params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
sig = LLVMFunctionType(LLVMVoidType(), params[argno++] = v_state;
param_types, lengthof(param_types), params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
false);
v_fn = LLVMAddFunction(mod, funcname, sig); for (int i = 0; i < nargs; i++)
} params[argno++] = v_args[i];
v_ret = LLVMBuildCall(b, v_fn, params, argno, "");
params[0] = v_state; pfree(params);
params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
params[2] = v_econtext;
LLVMBuildCall(b, return v_ret;
v_fn,
params, lengthof(params), "");
} }
static LLVMValueRef static LLVMValueRef
......
...@@ -98,13 +98,43 @@ FunctionReturningBool(void) ...@@ -98,13 +98,43 @@ FunctionReturningBool(void)
*/ */
void *referenced_functions[] = void *referenced_functions[] =
{ {
strlen, ExecAggInitGroup,
varsize_any, ExecAggTransReparent,
slot_getsomeattrs_int, ExecEvalAggOrderedTransDatum,
slot_getmissingattrs, ExecEvalAggOrderedTransTuple,
MakeExpandedObjectReadOnlyInternal, ExecEvalAlternativeSubPlan,
ExecEvalArrayCoerce,
ExecEvalArrayExpr,
ExecEvalConstraintCheck,
ExecEvalConstraintNotNull,
ExecEvalConvertRowtype,
ExecEvalCurrentOfExpr,
ExecEvalFieldSelect,
ExecEvalFieldStoreDeForm,
ExecEvalFieldStoreForm,
ExecEvalFuncExprFusage,
ExecEvalFuncExprStrictFusage,
ExecEvalGroupingFunc,
ExecEvalMinMax,
ExecEvalNextValueExpr,
ExecEvalParamExec,
ExecEvalParamExtern,
ExecEvalRow,
ExecEvalRowNotNull,
ExecEvalRowNull,
ExecEvalSQLValueFunction,
ExecEvalScalarArrayOp,
ExecEvalSubPlan,
ExecEvalSubscriptingRef, ExecEvalSubscriptingRef,
ExecEvalSubscriptingRefAssign,
ExecEvalSubscriptingRefFetch,
ExecEvalSubscriptingRefOld,
ExecEvalSysVar, ExecEvalSysVar,
ExecAggTransReparent, ExecEvalWholeRowVar,
ExecAggInitGroup ExecEvalXmlExpr,
MakeExpandedObjectReadOnlyInternal,
slot_getmissingattrs,
slot_getsomeattrs_int,
strlen,
varsize_any,
}; };
...@@ -55,6 +55,8 @@ typedef struct LLVMJitContext ...@@ -55,6 +55,8 @@ typedef struct LLVMJitContext
List *handles; List *handles;
} LLVMJitContext; } LLVMJitContext;
/* llvm module containing information about types */
extern LLVMModuleRef llvm_types_module;
/* type and struct definitions */ /* type and struct definitions */
extern LLVMTypeRef TypeParamBool; extern LLVMTypeRef TypeParamBool;
...@@ -78,15 +80,6 @@ extern LLVMTypeRef StructAggStatePerTransData; ...@@ -78,15 +80,6 @@ extern LLVMTypeRef StructAggStatePerTransData;
extern LLVMTypeRef StructAggStatePerGroupData; extern LLVMTypeRef StructAggStatePerGroupData;
extern LLVMValueRef AttributeTemplate; 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); extern void llvm_enter_fatal_on_oom(void);
...@@ -99,7 +92,7 @@ extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context); ...@@ -99,7 +92,7 @@ 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 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 void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context, extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,
LLVMBuilderRef builder, LLVMBuilderRef builder,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment