mirror of
https://github.com/postgres/postgres.git
synced 2025-06-23 14:01:44 +03:00
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
This commit is contained in:
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|||||||
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 *
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
/*
|
/*
|
||||||
* 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);
|
|
||||||
|
|
||||||
sig = LLVMFunctionType(LLVMVoidType(),
|
params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
|
||||||
param_types, lengthof(param_types),
|
|
||||||
false);
|
|
||||||
v_fn = LLVMAddFunction(mod, funcname, sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
params[0] = v_state;
|
params[argno++] = v_state;
|
||||||
params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
|
params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
|
||||||
params[2] = v_econtext;
|
|
||||||
|
|
||||||
LLVMBuildCall(b,
|
for (int i = 0; i < nargs; i++)
|
||||||
v_fn,
|
params[argno++] = v_args[i];
|
||||||
params, lengthof(params), "");
|
|
||||||
|
v_ret = LLVMBuildCall(b, v_fn, params, argno, "");
|
||||||
|
|
||||||
|
pfree(params);
|
||||||
|
|
||||||
|
return v_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef
|
static LLVMValueRef
|
||||||
|
@ -98,13 +98,43 @@ FunctionReturningBool(void)
|
|||||||
*/
|
*/
|
||||||
void *referenced_functions[] =
|
void *referenced_functions[] =
|
||||||
{
|
{
|
||||||
|
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,
|
||||||
|
ExecEvalWholeRowVar,
|
||||||
|
ExecEvalXmlExpr,
|
||||||
|
MakeExpandedObjectReadOnlyInternal,
|
||||||
|
slot_getmissingattrs,
|
||||||
|
slot_getsomeattrs_int,
|
||||||
strlen,
|
strlen,
|
||||||
varsize_any,
|
varsize_any,
|
||||||
slot_getsomeattrs_int,
|
|
||||||
slot_getmissingattrs,
|
|
||||||
MakeExpandedObjectReadOnlyInternal,
|
|
||||||
ExecEvalSubscriptingRef,
|
|
||||||
ExecEvalSysVar,
|
|
||||||
ExecAggTransReparent,
|
|
||||||
ExecAggInitGroup
|
|
||||||
};
|
};
|
||||||
|
@ -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;
|
|||||||
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);
|
|||||||
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,
|
||||||
|
Reference in New Issue
Block a user