aboutsummaryrefslogtreecommitdiff
path: root/src/backend/jit/llvm/llvmjit_expr.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2023-10-18 22:09:05 +1300
committerThomas Munro <tmunro@postgresql.org>2023-10-18 23:18:16 +1300
commit15ddc9725eb73d97a16652c7c90d993302773544 (patch)
tree62edba6b6ed3af6c3ae417f9e508c9e2dd357505 /src/backend/jit/llvm/llvmjit_expr.c
parent0e32652a79164965e8ef409bb84804a6e608e9ea (diff)
downloadpostgresql-15ddc9725eb73d97a16652c7c90d993302773544.tar.gz
postgresql-15ddc9725eb73d97a16652c7c90d993302773544.zip
jit: Support opaque pointers in LLVM 16.
Remove use of LLVMGetElementType() and provide the type of all pointers to LLVMBuildXXX() functions when emitting IR, as required by modern LLVM versions[1]. * For LLVM <= 14, we'll still use the old LLVMBuildXXX() functions. * For LLVM == 15, we'll continue to do the same, explicitly opting out of opaque pointer mode. * For LLVM >= 16, we'll use the new LLVMBuildXXX2() functions that take the extra type argument. The difference is hidden behind some new IR emitting wrapper functions l_load(), l_gep(), l_call() etc. The change is mostly mechanical, except that at each site the correct type had to be provided. In some places we needed to do some extra work to get functions types, including some new wrappers for C++ APIs that are not yet exposed by in LLVM's C API, and some new "example" functions in llvmjit_types.c because it's no longer possible to start from the function pointer type and ask for the function type. Back-patch to 12, because it's a little tricker in 11 and we agreed not to put the latest LLVM support into the upcoming final release of 11. [1] https://llvm.org/docs/OpaquePointers.html Reviewed-by: Dmitry Dolgov <9erthalion6@gmail.com> Reviewed-by: Ronan Dunklau <ronan.dunklau@aiven.io> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CA%2BhUKGKNX_%3Df%2B1C4r06WETKTq0G4Z_7q4L4Fxn5WWpMycDj9Fw%40mail.gmail.com
Diffstat (limited to 'src/backend/jit/llvm/llvmjit_expr.c')
-rw-r--r--src/backend/jit/llvm/llvmjit_expr.c471
1 files changed, 269 insertions, 202 deletions
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 6ed02639bb9..075ee76310e 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -80,7 +80,6 @@ llvm_compile_expr(ExprState *state)
LLVMBuilderRef b;
LLVMModuleRef mod;
- LLVMTypeRef eval_sig;
LLVMValueRef eval_fn;
LLVMBasicBlockRef entry;
LLVMBasicBlockRef *opblocks;
@@ -145,19 +144,9 @@ llvm_compile_expr(ExprState *state)
funcname = llvm_expand_funcname(context, "evalexpr");
- /* Create the signature and function */
- {
- LLVMTypeRef param_types[3];
-
- param_types[0] = l_ptr(StructExprState); /* state */
- param_types[1] = l_ptr(StructExprContext); /* econtext */
- param_types[2] = l_ptr(TypeStorageBool); /* isnull */
-
- eval_sig = LLVMFunctionType(TypeSizeT,
- param_types, lengthof(param_types),
- false);
- }
- eval_fn = LLVMAddFunction(mod, funcname, eval_sig);
+ /* create function */
+ eval_fn = LLVMAddFunction(mod, funcname,
+ llvm_pg_var_func_type("ExecInterpExprStillValid"));
LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
llvm_copy_attributes(AttributeTemplate, eval_fn);
@@ -171,58 +160,90 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, entry);
- v_tmpvaluep = LLVMBuildStructGEP(b, v_state,
- FIELDNO_EXPRSTATE_RESVALUE,
- "v.state.resvalue");
- v_tmpisnullp = LLVMBuildStructGEP(b, v_state,
- FIELDNO_EXPRSTATE_RESNULL,
- "v.state.resnull");
+ v_tmpvaluep = l_struct_gep(b,
+ StructExprState,
+ v_state,
+ FIELDNO_EXPRSTATE_RESVALUE,
+ "v.state.resvalue");
+ v_tmpisnullp = l_struct_gep(b,
+ StructExprState,
+ v_state,
+ FIELDNO_EXPRSTATE_RESNULL,
+ "v.state.resnull");
/* build global slots */
- v_scanslot = l_load_struct_gep(b, v_econtext,
+ v_scanslot = l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_SCANTUPLE,
"v_scanslot");
- v_innerslot = l_load_struct_gep(b, v_econtext,
+ v_innerslot = l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_INNERTUPLE,
"v_innerslot");
- v_outerslot = l_load_struct_gep(b, v_econtext,
+ v_outerslot = l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_OUTERTUPLE,
"v_outerslot");
- v_resultslot = l_load_struct_gep(b, v_state,
+ v_resultslot = l_load_struct_gep(b,
+ StructExprState,
+ v_state,
FIELDNO_EXPRSTATE_RESULTSLOT,
"v_resultslot");
/* build global values/isnull pointers */
- v_scanvalues = l_load_struct_gep(b, v_scanslot,
+ v_scanvalues = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_scanslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_scanvalues");
- v_scannulls = l_load_struct_gep(b, v_scanslot,
+ v_scannulls = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_scanslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_scannulls");
- v_innervalues = l_load_struct_gep(b, v_innerslot,
+ v_innervalues = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_innerslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_innervalues");
- v_innernulls = l_load_struct_gep(b, v_innerslot,
+ v_innernulls = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_innerslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_innernulls");
- v_outervalues = l_load_struct_gep(b, v_outerslot,
+ v_outervalues = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_outerslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_outervalues");
- v_outernulls = l_load_struct_gep(b, v_outerslot,
+ v_outernulls = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_outerslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_outernulls");
- v_resultvalues = l_load_struct_gep(b, v_resultslot,
+ v_resultvalues = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_resultslot,
FIELDNO_TUPLETABLESLOT_VALUES,
"v_resultvalues");
- v_resultnulls = l_load_struct_gep(b, v_resultslot,
+ v_resultnulls = l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_resultslot,
FIELDNO_TUPLETABLESLOT_ISNULL,
"v_resultnulls");
/* aggvalues/aggnulls */
- v_aggvalues = l_load_struct_gep(b, v_econtext,
+ v_aggvalues = l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_AGGVALUES,
"v.econtext.aggvalues");
- v_aggnulls = l_load_struct_gep(b, v_econtext,
+ v_aggnulls = l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_AGGNULLS,
"v.econtext.aggnulls");
@@ -256,8 +277,8 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_tmpisnull,
v_tmpvalue;
- v_tmpvalue = LLVMBuildLoad(b, v_tmpvaluep, "");
- v_tmpisnull = LLVMBuildLoad(b, v_tmpisnullp, "");
+ v_tmpvalue = l_load(b, TypeSizeT, v_tmpvaluep, "");
+ v_tmpisnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
LLVMBuildStore(b, v_tmpisnull, v_isnullp);
@@ -300,7 +321,9 @@ llvm_compile_expr(ExprState *state)
* be a virtual slot.
*/
v_nvalid =
- l_load_struct_gep(b, v_slot,
+ l_load_struct_gep(b,
+ StructTupleTableSlot,
+ v_slot,
FIELDNO_TUPLETABLESLOT_NVALID,
"");
LLVMBuildCondBr(b,
@@ -331,8 +354,10 @@ llvm_compile_expr(ExprState *state)
params[0] = v_slot;
- LLVMBuildCall(b, l_jit_deform,
- params, lengthof(params), "");
+ l_call(b,
+ LLVMGetFunctionType(l_jit_deform),
+ l_jit_deform,
+ params, lengthof(params), "");
}
else
{
@@ -341,9 +366,10 @@ llvm_compile_expr(ExprState *state)
params[0] = v_slot;
params[1] = l_int32_const(op->d.fetch.last_var);
- LLVMBuildCall(b,
- llvm_get_decl(mod, FuncSlotGetsomeattrsInt),
- params, lengthof(params), "");
+ l_call(b,
+ llvm_pg_var_func_type("slot_getsomeattrs_int"),
+ llvm_pg_func(mod, "slot_getsomeattrs_int"),
+ params, lengthof(params), "");
}
LLVMBuildBr(b, opblocks[i + 1]);
@@ -377,8 +403,8 @@ llvm_compile_expr(ExprState *state)
}
v_attnum = l_int32_const(op->d.var.attnum);
- value = l_load_gep1(b, v_values, v_attnum, "");
- isnull = l_load_gep1(b, v_nulls, v_attnum, "");
+ value = l_load_gep1(b, TypeSizeT, v_values, v_attnum, "");
+ isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
LLVMBuildStore(b, value, v_resvaluep);
LLVMBuildStore(b, isnull, v_resnullp);
@@ -405,9 +431,10 @@ llvm_compile_expr(ExprState *state)
v_params[2] = v_econtext;
v_params[3] = v_slot;
- LLVMBuildCall(b,
- llvm_get_decl(mod, FuncExecEvalSysVar),
- v_params, lengthof(v_params), "");
+ l_call(b,
+ llvm_pg_var_func_type("ExecEvalSysVar"),
+ llvm_pg_func(mod, "ExecEvalSysVar"),
+ v_params, lengthof(v_params), "");
LLVMBuildBr(b, opblocks[i + 1]);
break;
@@ -450,15 +477,19 @@ llvm_compile_expr(ExprState *state)
/* load data */
v_attnum = l_int32_const(op->d.assign_var.attnum);
- v_value = l_load_gep1(b, v_values, v_attnum, "");
- v_isnull = l_load_gep1(b, v_nulls, v_attnum, "");
+ v_value = l_load_gep1(b, TypeSizeT, v_values, v_attnum, "");
+ v_isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
/* compute addresses of targets */
v_resultnum = l_int32_const(op->d.assign_var.resultnum);
- v_rvaluep = LLVMBuildGEP(b, v_resultvalues,
- &v_resultnum, 1, "");
- v_risnullp = LLVMBuildGEP(b, v_resultnulls,
- &v_resultnum, 1, "");
+ v_rvaluep = l_gep(b,
+ TypeSizeT,
+ v_resultvalues,
+ &v_resultnum, 1, "");
+ v_risnullp = l_gep(b,
+ TypeStorageBool,
+ v_resultnulls,
+ &v_resultnum, 1, "");
/* and store */
LLVMBuildStore(b, v_value, v_rvaluep);
@@ -478,15 +509,15 @@ llvm_compile_expr(ExprState *state)
size_t resultnum = op->d.assign_tmp.resultnum;
/* load data */
- v_value = LLVMBuildLoad(b, v_tmpvaluep, "");
- v_isnull = LLVMBuildLoad(b, v_tmpisnullp, "");
+ v_value = l_load(b, TypeSizeT, v_tmpvaluep, "");
+ v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
/* compute addresses of targets */
v_resultnum = l_int32_const(resultnum);
v_rvaluep =
- LLVMBuildGEP(b, v_resultvalues, &v_resultnum, 1, "");
+ l_gep(b, TypeSizeT, v_resultvalues, &v_resultnum, 1, "");
v_risnullp =
- LLVMBuildGEP(b, v_resultnulls, &v_resultnum, 1, "");
+ l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
/* and store */
LLVMBuildStore(b, v_value, v_rvaluep);
@@ -512,15 +543,15 @@ llvm_compile_expr(ExprState *state)
"op.%d.assign_tmp.notnull", i);
/* load data */
- v_value = LLVMBuildLoad(b, v_tmpvaluep, "");
- v_isnull = LLVMBuildLoad(b, v_tmpisnullp, "");
+ v_value = l_load(b, TypeSizeT, v_tmpvaluep, "");
+ v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
/* compute addresses of targets */
v_resultnum = l_int32_const(resultnum);
- v_rvaluep = LLVMBuildGEP(b, v_resultvalues,
- &v_resultnum, 1, "");
- v_risnullp = LLVMBuildGEP(b, v_resultnulls,
- &v_resultnum, 1, "");
+ v_rvaluep =
+ l_gep(b, TypeSizeT, v_resultvalues, &v_resultnum, 1, "");
+ v_risnullp =
+ l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
/* store nullness */
LLVMBuildStore(b, v_isnull, v_risnullp);
@@ -535,9 +566,10 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_notnull);
v_params[0] = v_value;
v_ret =
- LLVMBuildCall(b,
- llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal),
- v_params, lengthof(v_params), "");
+ l_call(b,
+ llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
+ v_params, lengthof(v_params), "");
/* store value */
LLVMBuildStore(b, v_ret, v_rvaluep);
@@ -699,8 +731,8 @@ llvm_compile_expr(ExprState *state)
v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
l_ptr(TypeStorageBool));
- v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
- v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
+ v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
/* set resnull to boolnull */
LLVMBuildStore(b, v_boolnull, v_resnullp);
@@ -741,7 +773,7 @@ llvm_compile_expr(ExprState *state)
/* Build block that continues if bool is TRUE. */
LLVMPositionBuilderAtEnd(b, b_boolcont);
- v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, "");
+ v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
/* set value to NULL if any previous values were NULL */
LLVMBuildCondBr(b,
@@ -801,8 +833,8 @@ llvm_compile_expr(ExprState *state)
v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
l_ptr(TypeStorageBool));
- v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
- v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
+ v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
/* set resnull to boolnull */
LLVMBuildStore(b, v_boolnull, v_resnullp);
@@ -842,7 +874,7 @@ llvm_compile_expr(ExprState *state)
/* build block that continues if bool is FALSE */
LLVMPositionBuilderAtEnd(b, b_boolcont);
- v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, "");
+ v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
/* set value to NULL if any previous values were NULL */
LLVMBuildCondBr(b,
@@ -866,8 +898,8 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_boolnull;
LLVMValueRef v_negbool;
- v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
- v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
+ v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
+ v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
v_negbool = LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ,
@@ -894,8 +926,8 @@ llvm_compile_expr(ExprState *state)
b_qualfail = l_bb_before_v(opblocks[i + 1],
"op.%d.qualfail", i);
- v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
- v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
+ v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_nullorfalse =
LLVMBuildOr(b,
@@ -933,7 +965,7 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is null */
- v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
@@ -949,7 +981,7 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is non-null */
- v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
@@ -968,8 +1000,8 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is null or false */
- v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
- v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
+ v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_nullorfalse =
LLVMBuildOr(b,
@@ -988,7 +1020,7 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ISNULL:
{
- LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMValueRef v_resvalue;
v_resvalue =
@@ -1007,7 +1039,7 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ISNOTNULL:
{
- LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMValueRef v_resvalue;
v_resvalue =
@@ -1043,7 +1075,7 @@ llvm_compile_expr(ExprState *state)
{
LLVMBasicBlockRef b_isnull,
b_notnull;
- LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
b_isnull = l_bb_before_v(opblocks[i + 1],
"op.%d.isnull", i);
@@ -1087,7 +1119,7 @@ llvm_compile_expr(ExprState *state)
else
{
LLVMValueRef v_value =
- LLVMBuildLoad(b, v_resvaluep, "");
+ l_load(b, TypeSizeT, v_resvaluep, "");
v_value = LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ,
@@ -1115,28 +1147,19 @@ llvm_compile_expr(ExprState *state)
case EEOP_PARAM_CALLBACK:
{
- LLVMTypeRef param_types[3];
LLVMValueRef v_params[3];
- LLVMTypeRef v_functype;
LLVMValueRef v_func;
- param_types[0] = l_ptr(StructExprState);
- param_types[1] = l_ptr(TypeSizeT);
- param_types[2] = l_ptr(StructExprContext);
-
- v_functype = LLVMFunctionType(LLVMVoidType(),
- param_types,
- lengthof(param_types),
- false);
v_func = l_ptr_const(op->d.cparam.paramfunc,
- l_ptr(v_functype));
+ llvm_pg_var_type("TypeExecEvalSubroutine"));
v_params[0] = v_state;
v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT));
v_params[2] = v_econtext;
- LLVMBuildCall(b,
- v_func,
- v_params, lengthof(v_params), "");
+ l_call(b,
+ LLVMGetFunctionType(ExecEvalSubroutineTemplate),
+ v_func,
+ v_params, lengthof(v_params), "");
LLVMBuildBr(b, opblocks[i + 1]);
break;
@@ -1189,8 +1212,8 @@ llvm_compile_expr(ExprState *state)
/* if casetest != NULL */
LLVMPositionBuilderAtEnd(b, b_avail);
- v_casevalue = LLVMBuildLoad(b, v_casevaluep, "");
- v_casenull = LLVMBuildLoad(b, v_casenullp, "");
+ v_casevalue = l_load(b, TypeSizeT, v_casevaluep, "");
+ v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp);
LLVMBuildBr(b, opblocks[i + 1]);
@@ -1198,10 +1221,14 @@ llvm_compile_expr(ExprState *state)
/* if casetest == NULL */
LLVMPositionBuilderAtEnd(b, b_notavail);
v_casevalue =
- l_load_struct_gep(b, v_econtext,
+ l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_CASEDATUM, "");
v_casenull =
- l_load_struct_gep(b, v_econtext,
+ l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_CASENULL, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp);
@@ -1226,7 +1253,7 @@ llvm_compile_expr(ExprState *state)
v_nullp = l_ptr_const(op->d.make_readonly.isnull,
l_ptr(TypeStorageBool));
- v_null = LLVMBuildLoad(b, v_nullp, "");
+ v_null = l_load(b, TypeStorageBool, v_nullp, "");
/* store null isnull value in result */
LLVMBuildStore(b, v_null, v_resnullp);
@@ -1243,13 +1270,14 @@ llvm_compile_expr(ExprState *state)
v_valuep = l_ptr_const(op->d.make_readonly.value,
l_ptr(TypeSizeT));
- v_value = LLVMBuildLoad(b, v_valuep, "");
+ v_value = l_load(b, TypeSizeT, v_valuep, "");
v_params[0] = v_value;
v_ret =
- LLVMBuildCall(b,
- llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal),
- v_params, lengthof(v_params), "");
+ l_call(b,
+ llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
+ llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
+ v_params, lengthof(v_params), "");
LLVMBuildStore(b, v_ret, v_resvaluep);
LLVMBuildBr(b, opblocks[i + 1]);
@@ -1260,10 +1288,10 @@ llvm_compile_expr(ExprState *state)
{
FunctionCallInfo fcinfo_out,
fcinfo_in;
+ LLVMValueRef v_fn_out,
+ v_fn_in;
LLVMValueRef v_fcinfo_out,
v_fcinfo_in;
- LLVMValueRef v_fn_addr_out,
- v_fn_addr_in;
LLVMValueRef v_fcinfo_in_isnullp;
LLVMValueRef v_retval;
LLVMValueRef v_resvalue;
@@ -1289,18 +1317,20 @@ llvm_compile_expr(ExprState *state)
b_inputcall = l_bb_before_v(opblocks[i + 1],
"op.%d.inputcall", i);
+ v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out);
+ v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in);
v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
- v_fn_addr_out = l_ptr_const(fcinfo_out->flinfo->fn_addr, TypePGFunction);
- v_fn_addr_in = l_ptr_const(fcinfo_in->flinfo->fn_addr, TypePGFunction);
v_fcinfo_in_isnullp =
- LLVMBuildStructGEP(b, v_fcinfo_in,
- FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
- "v_fcinfo_in_isnull");
+ l_struct_gep(b,
+ StructFunctionCallInfoData,
+ v_fcinfo_in,
+ FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
+ "v_fcinfo_in_isnull");
/* output functions are not called on nulls */
- v_resnull = LLVMBuildLoad(b, v_resnullp, "");
+ v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
l_sbool_const(1), ""),
@@ -1312,7 +1342,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildBr(b, b_input);
LLVMPositionBuilderAtEnd(b, b_calloutput);
- v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
+ v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
/* set arg[0] */
LLVMBuildStore(b,
@@ -1322,8 +1352,10 @@ llvm_compile_expr(ExprState *state)
l_sbool_const(0),
l_funcnullp(b, v_fcinfo_out, 0));
/* and call output function (can never return NULL) */
- v_output = LLVMBuildCall(b, v_fn_addr_out, &v_fcinfo_out,
- 1, "funccall_coerce_out");
+ v_output = l_call(b,
+ LLVMGetFunctionType(v_fn_out),
+ v_fn_out, &v_fcinfo_out,
+ 1, "funccall_coerce_out");
LLVMBuildBr(b, b_input);
/* build block handling input function call */
@@ -1377,8 +1409,10 @@ llvm_compile_expr(ExprState *state)
/* reset fcinfo_in->isnull */
LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
/* and call function */
- v_retval = LLVMBuildCall(b, v_fn_addr_in, &v_fcinfo_in, 1,
- "funccall_iocoerce_in");
+ v_retval = l_call(b,
+ LLVMGetFunctionType(v_fn_in),
+ v_fn_in, &v_fcinfo_in, 1,
+ "funccall_iocoerce_in");
LLVMBuildStore(b, v_retval, v_resvaluep);
@@ -1711,7 +1745,7 @@ llvm_compile_expr(ExprState *state)
*/
v_cmpresult =
LLVMBuildTrunc(b,
- LLVMBuildLoad(b, v_resvaluep, ""),
+ l_load(b, TypeSizeT, v_resvaluep, ""),
LLVMInt32Type(), "");
switch (rctype)
@@ -1775,17 +1809,16 @@ llvm_compile_expr(ExprState *state)
case EEOP_SBSREF_SUBSCRIPT:
{
- LLVMValueRef v_fn;
int jumpdone = op->d.sbsref_subscript.jumpdone;
LLVMValueRef v_params[2];
LLVMValueRef v_ret;
- v_fn = llvm_get_decl(mod, FuncExecEvalSubscriptingRef);
-
v_params[0] = v_state;
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
- v_ret = LLVMBuildCall(b, v_fn,
- v_params, lengthof(v_params), "");
+ v_ret = l_call(b,
+ llvm_pg_var_func_type("ExecEvalSubscriptingRef"),
+ llvm_pg_func(mod, "ExecEvalSubscriptingRef"),
+ v_params, lengthof(v_params), "");
v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
LLVMBuildCondBr(b,
@@ -1827,8 +1860,8 @@ llvm_compile_expr(ExprState *state)
/* if casetest != NULL */
LLVMPositionBuilderAtEnd(b, b_avail);
- v_casevalue = LLVMBuildLoad(b, v_casevaluep, "");
- v_casenull = LLVMBuildLoad(b, v_casenullp, "");
+ v_casevalue = l_load(b, TypeSizeT, v_casevaluep, "");
+ v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp);
LLVMBuildBr(b, opblocks[i + 1]);
@@ -1836,11 +1869,15 @@ llvm_compile_expr(ExprState *state)
/* if casetest == NULL */
LLVMPositionBuilderAtEnd(b, b_notavail);
v_casevalue =
- l_load_struct_gep(b, v_econtext,
+ l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_DOMAINDATUM,
"");
v_casenull =
- l_load_struct_gep(b, v_econtext,
+ l_load_struct_gep(b,
+ StructExprContext,
+ v_econtext,
FIELDNO_EXPRCONTEXT_DOMAINNULL,
"");
LLVMBuildStore(b, v_casevalue, v_resvaluep);
@@ -1895,11 +1932,11 @@ llvm_compile_expr(ExprState *state)
*/
v_aggnop = l_ptr_const(&aggref->aggno,
l_ptr(LLVMInt32Type()));
- v_aggno = LLVMBuildLoad(b, v_aggnop, "v_aggno");
+ v_aggno = l_load(b, LLVMInt32Type(), v_aggnop, "v_aggno");
/* load agg value / null */
- value = l_load_gep1(b, v_aggvalues, v_aggno, "aggvalue");
- isnull = l_load_gep1(b, v_aggnulls, v_aggno, "aggnull");
+ value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_aggno, "aggvalue");
+ isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
/* and store result */
LLVMBuildStore(b, value, v_resvaluep);
@@ -1930,12 +1967,12 @@ llvm_compile_expr(ExprState *state)
*/
v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
l_ptr(LLVMInt32Type()));
- v_wfuncno = LLVMBuildLoad(b, v_wfuncnop, "v_wfuncno");
+ v_wfuncno = l_load(b, LLVMInt32Type(), v_wfuncnop, "v_wfuncno");
/* load window func value / null */
- value = l_load_gep1(b, v_aggvalues, v_wfuncno,
+ value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_wfuncno,
"windowvalue");
- isnull = l_load_gep1(b, v_aggnulls, v_wfuncno,
+ isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_wfuncno,
"windownull");
LLVMBuildStore(b, value, v_resvaluep);
@@ -2057,14 +2094,14 @@ llvm_compile_expr(ExprState *state)
b_argnotnull = b_checknulls[argno + 1];
if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
- v_argisnull = l_load_gep1(b, v_nullsp, v_argno, "");
+ v_argisnull = l_load_gep1(b, TypeStorageBool, v_nullsp, v_argno, "");
else
{
LLVMValueRef v_argn;
- v_argn = LLVMBuildGEP(b, v_argsp, &v_argno, 1, "");
+ v_argn = l_gep(b, StructNullableDatum, v_argsp, &v_argno, 1, "");
v_argisnull =
- l_load_struct_gep(b, v_argn,
+ l_load_struct_gep(b, StructNullableDatum, v_argn,
FIELDNO_NULLABLE_DATUM_ISNULL,
"");
}
@@ -2114,18 +2151,24 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_init_trans_check.transno];
*/
v_allpergroupsp =
- l_load_struct_gep(b, v_aggstatep,
+ l_load_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups");
v_setoff = l_int32_const(op->d.agg_init_trans.setoff);
v_transno = l_int32_const(op->d.agg_init_trans.transno);
v_pergroupp =
- LLVMBuildGEP(b,
- l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
- &v_transno, 1, "");
+ l_gep(b,
+ StructAggStatePerGroupData,
+ l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
+ v_allpergroupsp, v_setoff, ""),
+ &v_transno, 1, "");
v_notransvalue =
- l_load_struct_gep(b, v_pergroupp,
+ l_load_struct_gep(b,
+ StructAggStatePerGroupData,
+ v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE,
"notransvalue");
@@ -2150,15 +2193,17 @@ llvm_compile_expr(ExprState *state)
l_ptr(StructExprContext));
v_current_set =
- LLVMBuildStructGEP(b,
- v_aggstatep,
- FIELDNO_AGGSTATE_CURRENT_SET,
- "aggstate.current_set");
+ l_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
+ FIELDNO_AGGSTATE_CURRENT_SET,
+ "aggstate.current_set");
v_curaggcontext =
- LLVMBuildStructGEP(b,
- v_aggstatep,
- FIELDNO_AGGSTATE_CURAGGCONTEXT,
- "aggstate.curaggcontext");
+ l_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
+ FIELDNO_AGGSTATE_CURAGGCONTEXT,
+ "aggstate.curaggcontext");
LLVMBuildStore(b, l_int32_const(op->d.agg_init_trans.setno),
v_current_set);
@@ -2169,10 +2214,11 @@ llvm_compile_expr(ExprState *state)
params[1] = v_pertransp;
params[2] = v_pergroupp;
- LLVMBuildCall(b,
- llvm_get_decl(mod, FuncExecAggInitGroup),
- params, lengthof(params),
- "");
+ l_call(b,
+ llvm_pg_var_func_type("ExecAggInitGroup"),
+ llvm_pg_func(mod, "ExecAggInitGroup"),
+ params, lengthof(params),
+ "");
}
LLVMBuildBr(b, opblocks[op->d.agg_init_trans.jumpnull]);
@@ -2202,7 +2248,9 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_init_trans_check.transno];
*/
v_allpergroupsp =
- l_load_struct_gep(b, v_aggstatep,
+ l_load_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups");
v_setoff =
@@ -2210,12 +2258,16 @@ llvm_compile_expr(ExprState *state)
v_transno =
l_int32_const(op->d.agg_strict_trans_check.transno);
v_pergroupp =
- LLVMBuildGEP(b,
- l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
- &v_transno, 1, "");
+ l_gep(b,
+ StructAggStatePerGroupData,
+ l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
+ v_allpergroupsp, v_setoff, ""),
+ &v_transno, 1, "");
v_transnull =
- l_load_struct_gep(b, v_pergroupp,
+ l_load_struct_gep(b,
+ StructAggStatePerGroupData,
+ v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
"transnull");
@@ -2277,15 +2329,19 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_init_trans_check.transno];
*/
v_allpergroupsp =
- l_load_struct_gep(b, v_aggstatep,
+ l_load_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups");
v_setoff = l_int32_const(op->d.agg_trans.setoff);
v_transno = l_int32_const(op->d.agg_trans.transno);
v_pergroupp =
- LLVMBuildGEP(b,
- l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
- &v_transno, 1, "");
+ l_gep(b,
+ StructAggStatePerGroupData,
+ l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
+ v_allpergroupsp, v_setoff, ""),
+ &v_transno, 1, "");
v_fcinfo = l_ptr_const(fcinfo,
l_ptr(StructFunctionCallInfoData));
@@ -2293,20 +2349,23 @@ llvm_compile_expr(ExprState *state)
l_ptr(StructExprContext));
v_current_setp =
- LLVMBuildStructGEP(b,
- v_aggstatep,
- FIELDNO_AGGSTATE_CURRENT_SET,
- "aggstate.current_set");
+ l_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
+ FIELDNO_AGGSTATE_CURRENT_SET,
+ "aggstate.current_set");
v_curaggcontext =
- LLVMBuildStructGEP(b,
- v_aggstatep,
- FIELDNO_AGGSTATE_CURAGGCONTEXT,
- "aggstate.curaggcontext");
+ l_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
+ FIELDNO_AGGSTATE_CURAGGCONTEXT,
+ "aggstate.curaggcontext");
v_current_pertransp =
- LLVMBuildStructGEP(b,
- v_aggstatep,
- FIELDNO_AGGSTATE_CURPERTRANS,
- "aggstate.curpertrans");
+ l_struct_gep(b,
+ StructAggState,
+ v_aggstatep,
+ FIELDNO_AGGSTATE_CURPERTRANS,
+ "aggstate.curpertrans");
/* set aggstate globals */
LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
@@ -2322,19 +2381,25 @@ llvm_compile_expr(ExprState *state)
/* store transvalue in fcinfo->args[0] */
v_transvaluep =
- LLVMBuildStructGEP(b, v_pergroupp,
- FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
- "transvalue");
+ l_struct_gep(b,
+ StructAggStatePerGroupData,
+ v_pergroupp,
+ FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
+ "transvalue");
v_transnullp =
- LLVMBuildStructGEP(b, v_pergroupp,
- FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
- "transnullp");
+ l_struct_gep(b,
+ StructAggStatePerGroupData,
+ v_pergroupp,
+ FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
+ "transnullp");
LLVMBuildStore(b,
- LLVMBuildLoad(b, v_transvaluep,
- "transvalue"),
+ l_load(b,
+ TypeSizeT,
+ v_transvaluep,
+ "transvalue"),
l_funcvaluep(b, v_fcinfo, 0));
LLVMBuildStore(b,
- LLVMBuildLoad(b, v_transnullp, "transnull"),
+ l_load(b, TypeStorageBool, v_transnullp, "transnull"),
l_funcnullp(b, v_fcinfo, 0));
/* and invoke transition function */
@@ -2365,8 +2430,8 @@ llvm_compile_expr(ExprState *state)
b_nocall = l_bb_before_v(opblocks[i + 1],
"op.%d.transnocall", i);
- v_transvalue = LLVMBuildLoad(b, v_transvaluep, "");
- v_transnull = LLVMBuildLoad(b, v_transnullp, "");
+ v_transvalue = l_load(b, TypeSizeT, v_transvaluep, "");
+ v_transnull = l_load(b, TypeStorageBool, v_transnullp, "");
/*
* DatumGetPointer(newVal) !=
@@ -2390,11 +2455,13 @@ 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),
- "");
+ l_call(b,
+ LLVMGetFunctionType(v_fn),
+ v_fn,
+ params, lengthof(params),
+ "");
/* store trans value */
LLVMBuildStore(b, v_newval, v_transvaluep);
@@ -2504,15 +2571,17 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
v_fn = llvm_function_reference(context, b, mod, fcinfo);
v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
- v_fcinfo_isnullp = LLVMBuildStructGEP(b, v_fcinfo,
- FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
- "v_fcinfo_isnull");
+ v_fcinfo_isnullp = l_struct_gep(b,
+ StructFunctionCallInfoData,
+ v_fcinfo,
+ FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
+ "v_fcinfo_isnull");
LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
- v_retval = LLVMBuildCall(b, v_fn, &v_fcinfo, 1, "funccall");
+ v_retval = l_call(b, LLVMGetFunctionType(AttributeTemplate), v_fn, &v_fcinfo, 1, "funccall");
if (v_fcinfo_isnull)
- *v_fcinfo_isnull = LLVMBuildLoad(b, v_fcinfo_isnullp, "");
+ *v_fcinfo_isnull = l_load(b, TypeStorageBool, v_fcinfo_isnullp, "");
/*
* Add lifetime-end annotation, signalling that writes to memory don't
@@ -2524,11 +2593,11 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs);
params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type()));
- LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
+ l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
params[0] = l_int64_const(sizeof(fcinfo->isnull));
params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8Type()));
- LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
+ l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
}
return v_retval;
@@ -2564,9 +2633,7 @@ build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
params[2] = v_econtext;
- LLVMBuildCall(b,
- v_fn,
- params, lengthof(params), "");
+ l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, lengthof(params), "");
}
static LLVMValueRef