v1-0001-jit-Eliminate-const-pointer-to-fmgrinfo.patch
application/octet-stream
Filename: v1-0001-jit-Eliminate-const-pointer-to-fmgrinfo.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v1-0001
Subject: jit: Eliminate const pointer to fmgrinfo
| File | + | − |
|---|---|---|
| src/backend/executor/execExpr.c | 75 | 21 |
| src/backend/jit/llvm/llvmjit_expr.c | 71 | 13 |
| src/include/executor/execExpr.h | 7 | 0 |
| src/include/jit/llvmjit.h | 3 | 3 |
From dcee28d76d28a396cc6e925af61690afecd9c516 Mon Sep 17 00:00:00 2001
From: soumyadeep2007 <sochakraborty@pivotal.io>
Date: Tue, 3 Mar 2020 09:25:52 -0800
Subject: [PATCH v1 1/1] jit: Eliminate const pointer to fmgrinfo
---
src/backend/executor/execExpr.c | 96 ++++++++++++++++++++++-------
src/backend/jit/llvm/llvmjit_expr.c | 84 +++++++++++++++++++++----
src/include/executor/execExpr.h | 7 +++
src/include/jit/llvmjit.h | 6 +-
4 files changed, 156 insertions(+), 37 deletions(-)
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 4e10f9aea8..a1ac44133c 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -149,8 +149,23 @@ ExprBuilderAllocNullableDatumArrayInit(ExprStateBuilder *esb, int nelems, Nullab
return (RelNullableDatumArray){alloc->ptr};
}
+static RelFunctionMgrInfo
+ExprBuilderAllocFunctionMgrInfo(ExprStateBuilder *esb, FmgrInfo **ptr)
+{
+ Size sz = sizeof(FmgrInfo);
+ ExprStateAllocation *alloc;
+
+ alloc = ExprBuilderAllocInternal(esb, ERP_FUNCTIONMGRINFO, sz);
+
+ alloc->zeroed = true;
+ alloc->initial_content = palloc0(sz);
+ *ptr = alloc->initial_content;
+
+ return (RelFunctionMgrInfo){alloc->ptr};
+}
+
static RelFunctionCallInfo
-ExprBuilderAllocFunctionCallInfo(ExprStateBuilder *esb, int nargs, FunctionCallInfo *ptr)
+ExprBuilderAllocFunctionCallInfo(ExprStateBuilder *esb, int nargs, RelFunctionMgrInfo finfoRel, FunctionCallInfo *ptr)
{
ExprStateAllocation *alloc;
Size sz = SizeForFunctionCallInfo(nargs);
@@ -161,7 +176,7 @@ ExprBuilderAllocFunctionCallInfo(ExprStateBuilder *esb, int nargs, FunctionCallI
alloc->initial_content = palloc0(sz);
*ptr = alloc->initial_content;
- return (RelFunctionCallInfo){alloc->ptr};
+ return (RelFunctionCallInfo){alloc->ptr, finfoRel.ptr};
}
static RelNullableDatum
@@ -1148,6 +1163,7 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
Expr *scalararg;
Expr *arrayarg;
+ RelFunctionMgrInfo finfo_rel;
FmgrInfo *finfo;
RelFunctionCallInfo fcinfo_rel;
FunctionCallInfo fcinfo;
@@ -1167,8 +1183,11 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
InvokeFunctionExecuteHook(opexpr->opfuncid);
/* Set up the primary fmgr lookup information */
- finfo = palloc0(sizeof(FmgrInfo));
- fcinfo_rel = ExprBuilderAllocFunctionCallInfo(esb, 2, &fcinfo);
+ finfo_rel = ExprBuilderAllocFunctionMgrInfo(esb, &finfo);
+ fcinfo_rel = ExprBuilderAllocFunctionCallInfo(esb,
+ 2,
+ finfo_rel,
+ &fcinfo);
fmgr_info(opexpr->opfuncid, finfo);
fmgr_info_set_expr((Node *) node, finfo);
@@ -1441,8 +1460,10 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
Oid typioparam;
FunctionCallInfo fcinfo_in;
FunctionCallInfo fcinfo_out;
- FmgrInfo *finfo_in = palloc0(sizeof(FmgrInfo));
- FmgrInfo *finfo_out = palloc0(sizeof(FmgrInfo));
+ RelFunctionMgrInfo finfo_in_rel;
+ FmgrInfo *finfo_in;
+ RelFunctionMgrInfo finfo_out_rel;
+ FmgrInfo *finfo_out;
/* evaluate argument into step's result area */
ExecInitExprRec(esb, iocoerce->arg, result);
@@ -1456,10 +1477,13 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
* function are assumed to be executable by everyone.
*/
scratch.opcode = EEOP_IOCOERCE;
-
/* lookup the source type's output function */
+ finfo_out_rel = ExprBuilderAllocFunctionMgrInfo(esb, &finfo_out);
scratch.d.iocoerce.fcinfo_data_out =
- ExprBuilderAllocFunctionCallInfo(esb, 1, &fcinfo_out);
+ ExprBuilderAllocFunctionCallInfo(esb,
+ 1,
+ finfo_out_rel,
+ &fcinfo_out);
getTypeOutputInfo(exprType((Node *) iocoerce->arg),
&iofunc, &typisvarlena);
@@ -1470,8 +1494,12 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
scratch.d.iocoerce.fn_addr_out = finfo_out->fn_addr;
/* lookup the result type's input function */
+ finfo_in_rel = ExprBuilderAllocFunctionMgrInfo(esb, &finfo_in);
scratch.d.iocoerce.fcinfo_data_in =
- ExprBuilderAllocFunctionCallInfo(esb, 3, &fcinfo_in);
+ ExprBuilderAllocFunctionCallInfo(esb,
+ 3,
+ finfo_in_rel,
+ &fcinfo_in);
getTypeInputInfo(iocoerce->resulttype,
&iofunc, &typioparam);
@@ -1888,6 +1916,7 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
Oid lefttype;
Oid righttype;
Oid proc;
+ RelFunctionMgrInfo finfo_rel;
FmgrInfo *finfo;
RelFunctionCallInfo fcinfo_rel;
FunctionCallInfo fcinfo;
@@ -1905,9 +1934,12 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
BTORDER_PROC, lefttype, righttype, opfamily);
/* Set up the primary fmgr lookup information */
- finfo = palloc0(sizeof(FmgrInfo));
+ finfo_rel = ExprBuilderAllocFunctionMgrInfo(esb, &finfo);
fcinfo_rel =
- ExprBuilderAllocFunctionCallInfo(esb, 3, &fcinfo);
+ ExprBuilderAllocFunctionCallInfo(esb,
+ 3,
+ finfo_rel,
+ &fcinfo);
fmgr_info(proc, finfo);
fmgr_info_set_expr((Node *) node, finfo);
@@ -2026,6 +2058,7 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
int nelems = list_length(minmaxexpr->args);
TypeCacheEntry *typentry;
+ RelFunctionMgrInfo finfo_rel;
FmgrInfo *finfo;
RelFunctionCallInfo fcinfo_rel;
FunctionCallInfo fcinfo;
@@ -2049,9 +2082,12 @@ ExecInitExprRec(ExprStateBuilder *esb, Expr *node, RelNullableDatum result)
*/
/* Perform function lookup */
- finfo = palloc0(sizeof(FmgrInfo));
+ finfo_rel = ExprBuilderAllocFunctionMgrInfo(esb, &finfo);
fcinfo_rel =
- ExprBuilderAllocFunctionCallInfo(esb, 2, &fcinfo);
+ ExprBuilderAllocFunctionCallInfo(esb,
+ 2,
+ finfo_rel,
+ &fcinfo);
fmgr_info(typentry->cmp_proc, finfo);
fmgr_info_set_expr((Node *) node, finfo);
InitFunctionCallInfoData(*fcinfo, finfo, 2,
@@ -2327,6 +2363,7 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
{
int nargs = list_length(args);
AclResult aclresult;
+ RelFunctionMgrInfo flinfo_rel;
FmgrInfo *flinfo;
RelFunctionCallInfo fcinfo_rel;
FunctionCallInfo fcinfo;
@@ -2354,8 +2391,11 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid,
FUNC_MAX_ARGS)));
/* Allocate function lookup data and parameter workspace for this call */
- flinfo = palloc0(sizeof(FmgrInfo));
- fcinfo_rel = ExprBuilderAllocFunctionCallInfo(esb, nargs, &fcinfo);
+ flinfo_rel = ExprBuilderAllocFunctionMgrInfo(esb, &flinfo);
+ fcinfo_rel = ExprBuilderAllocFunctionCallInfo(esb,
+ nargs,
+ flinfo_rel,
+ &fcinfo);
scratch->d.func.fcinfo_data = fcinfo_rel;
/* Set up the primary fmgr lookup information */
@@ -3145,6 +3185,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
for (int transno = 0; transno < aggstate->numtrans; transno++)
{
AggStatePerTrans pertrans = &aggstate->pertrans[transno];
+ RelFunctionMgrInfo trans_finfo_rel;
+ FmgrInfo *trans_finfo;
RelFunctionCallInfo trans_fcinfo_rel;
FunctionCallInfo trans_fcinfo;
List *adjust_bailout = NIL;
@@ -3154,13 +3196,17 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
ListCell *bail;
size_t numTransArgs;
+ trans_finfo_rel = ExprBuilderAllocFunctionMgrInfo(&esb, &trans_finfo);
+ *trans_finfo = pertrans->transfn;
/* account for the current transition state */
numTransArgs = pertrans->numTransInputs + 1;
trans_fcinfo_rel =
- ExprBuilderAllocFunctionCallInfo(&esb, numTransArgs,
+ ExprBuilderAllocFunctionCallInfo(&esb,
+ numTransArgs,
+ trans_finfo_rel,
&trans_fcinfo);
InitFunctionCallInfoData(*trans_fcinfo,
- &pertrans->transfn,
+ trans_finfo,
numTransArgs,
pertrans->aggCollation,
NULL, /* will get set when calling */
@@ -3218,6 +3264,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
}
else
{
+ RelFunctionMgrInfo ds_finfo_rel;
+ FmgrInfo *ds_finfo;
FunctionCallInfo ds_fcinfo;
RelFunctionCallInfo ds_fcinfo_rel;
AggStatePerCallContext *percall;
@@ -3226,12 +3274,17 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase,
percall->aggstate = aggstate;
percall->pertrans = pertrans;
+ ds_finfo_rel = ExprBuilderAllocFunctionMgrInfo(&esb, &ds_finfo);
+ *ds_finfo = pertrans->deserialfn;
+
ds_fcinfo_rel =
- ExprBuilderAllocFunctionCallInfo(&esb, numTransArgs,
+ ExprBuilderAllocFunctionCallInfo(&esb,
+ numTransArgs,
+ ds_finfo_rel,
&ds_fcinfo);
InitFunctionCallInfoData(*ds_fcinfo,
- &pertrans->deserialfn,
+ ds_finfo,
2,
InvalidOid,
(void *) percall, NULL);
@@ -3603,6 +3656,7 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1);
Oid foid = eqfunctions[natt];
Oid collid = collations[natt];
+ RelFunctionMgrInfo finfo_rel;
FmgrInfo *finfo;
RelFunctionCallInfo fcinfo_rel;
FunctionCallInfo fcinfo;
@@ -3616,8 +3670,8 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
InvokeFunctionExecuteHook(foid);
/* Set up the primary fmgr lookup information */
- finfo = palloc0(sizeof(FmgrInfo));
- fcinfo_rel = ExprBuilderAllocFunctionCallInfo(&esb, 2, &fcinfo);
+ finfo_rel = ExprBuilderAllocFunctionMgrInfo(&esb, &finfo);
+ fcinfo_rel = ExprBuilderAllocFunctionCallInfo(&esb,2, finfo_rel, &fcinfo);
fmgr_info(foid, finfo);
fmgr_info_set_expr(NULL, finfo);
InitFunctionCallInfoData(*fcinfo, finfo, 2,
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index 43501a5bb6..f9af5482f8 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -110,6 +110,7 @@ typedef struct ExprCompileState
static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull);
static void expr_emit_allocations(ExprCompileState *ecs);
+static void expr_init_fmgri(ExprCompileState *ecs, FmgrInfo *fmgrinfo, LLVMValueRef v_fmgrinfo);
static void expr_init_fci(ExprCompileState *ecs, FunctionCallInfo fcinfo, LLVMValueRef v_fcinfo);
static void expr_init_nullable_datums(ExprCompileState *ecs, int nelems, NullableDatum *datums, LLVMValueRef v_datums);
@@ -2672,6 +2673,13 @@ expr_emit_allocations(ExprCompileState *ecs)
v_allocation);
break;
+ case ERP_FUNCTIONMGRINFO:
+ Assert(allocation->initial_content != NULL);
+ allocname = psprintf("alloc.%u.fmgr_info", i + 1);
+ v_allocation = LLVMBuildAlloca(ecs->b, StructFmgrInfo, allocname);
+ expr_init_fmgri(ecs, (FmgrInfo *) allocation->initial_content, v_allocation);
+ break;
+
case ERP_FUNCTIONCALLINFO:
Assert(allocation->initial_content != NULL);
@@ -2704,22 +2712,49 @@ expr_emit_allocations(ExprCompileState *ecs)
}
}
+static void
+expr_init_fmgri(ExprCompileState *ecs, FmgrInfo *fmgrinfo, LLVMValueRef v_fmgrinfo)
+{
+ /*
+ * There is no need to set fn_addr as the function will be resolved via
+ * llvm_function_reference() followed by llvm_resolve_symbl().
+ */
+
+ LLVMBuildStore(ecs->b,
+ l_int32_const(fmgrinfo->fn_oid),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 1, ""));
+ LLVMBuildStore(ecs->b,
+ l_int16_const(fmgrinfo->fn_nargs),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 2, ""));
+ LLVMBuildStore(ecs->b,
+ l_sbool_const(fmgrinfo->fn_strict),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 3, ""));
+ LLVMBuildStore(ecs->b,
+ l_sbool_const(fmgrinfo->fn_retset),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 4, ""));
+ LLVMBuildStore(ecs->b,
+ l_int8_const(fmgrinfo->fn_stats),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 5, ""));
+ LLVMBuildStore(ecs->b,
+ l_ptr_const(fmgrinfo->fn_extra, LLVMStructGetTypeAtIndex(StructFmgrInfo, 6)),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 6, "")); /* TODO */
+ LLVMBuildStore(ecs->b,
+ l_ptr_const(fmgrinfo->fn_mcxt, l_ptr(StructMemoryContextData)),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 7, ""));
+ LLVMBuildStore(ecs->b,
+ l_ptr_const(fmgrinfo->fn_expr, l_ptr(StructNode)),
+ LLVMBuildStructGEP(ecs->b, v_fmgrinfo, 8, "")); /* TODO */
+}
+
static void
expr_init_fci(ExprCompileState *ecs, FunctionCallInfo fcinfo, LLVMValueRef v_fcinfo)
{
LLVMValueRef v_args;
/*
- * FIXME: should be allocated as part of the ExprState, allowing this to
- * be referenced efficiently / without pointer constants.
+ * We can't set fcinfo->flinfo here. It will be set inside expr_fcinfo_ref()
+ * where we have access to the flinfo relptr.
*/
- if (fcinfo->flinfo)
- LLVMBuildStore(ecs->b,
- l_ptr_const(fcinfo->flinfo, l_ptr(StructFmgrInfo)),
- LLVMBuildStructGEP(ecs->b,
- v_fcinfo,
- FIELDNO_FUNCTIONCALLINFODATA_FLINFO,
- ""));
/*
* FIXME: should be allocated as part of the ExprState, allowing this to
@@ -2910,13 +2945,36 @@ expr_allocation_ref(ExprCompileState *ecs, ExprRelPtr rel)
static LLVMValueRef
expr_fcinfo_ref(ExprCompileState *ecs, RelFunctionCallInfo relfc, FunctionCallInfo *fcinfo)
{
- ExprStateAllocation *alloc = list_nth(ecs->esb->allocations, relfc.ptr.allocno - 1);
+ FmgrInfo *fmgrInfo;
+ LLVMValueRef v_fmgrInfo;
+ LLVMValueRef v_fcinfo;
+ ExprStateAllocation *fcinfo_alloc;
+ ExprStateAllocation *fmgr_alloc;
+
+ fcinfo_alloc = list_nth(ecs->esb->allocations, relfc.ptr.allocno - 1);
+ Assert(fcinfo_alloc->initial_content != NULL);
+
+ fmgr_alloc = list_nth(ecs->esb->allocations, relfc.fmgrInfoPtr.allocno - 1);
+ Assert(fmgr_alloc->initial_content != NULL);
- Assert(alloc->initial_content != NULL);
if (fcinfo)
- *fcinfo = (FunctionCallInfo) alloc->initial_content;
+ {
+ *fcinfo = (FunctionCallInfo) fcinfo_alloc->initial_content;
+ fmgrInfo = (FmgrInfo *) fmgr_alloc->initial_content;
+ (*fcinfo)->flinfo = fmgrInfo;
+ }
+ v_fmgrInfo = expr_allocation_ref(ecs, relfc.fmgrInfoPtr);
+
+ v_fcinfo = expr_allocation_ref(ecs, relfc.ptr);
+
+ LLVMBuildStore(ecs->b,
+ v_fmgrInfo,
+ LLVMBuildStructGEP(ecs->b,
+ v_fcinfo,
+ FIELDNO_FUNCTIONCALLINFODATA_FLINFO,
+ ""));
- return expr_allocation_ref(ecs, relfc.ptr);
+ return v_fcinfo;
}
static LLVMValueRef
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index b523e839bb..a3f9e8676f 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -265,9 +265,15 @@ typedef struct RelNullableDatumArray
ExprRelPtr ptr;
} RelNullableDatumArray;
+typedef struct RelFunctionMgrInfo
+{
+ ExprRelPtr ptr;
+} RelFunctionMgrInfo;
+
typedef struct RelFunctionCallInfo
{
ExprRelPtr ptr;
+ ExprRelPtr fmgrInfoPtr;
} RelFunctionCallInfo;
typedef struct ExprEvalStep
@@ -682,6 +688,7 @@ typedef enum ExprRelPtrKind
ERP_BOOL,
ERP_NULLABLE_DATUM,
ERP_NULLABLE_DATUM_ARRAY,
+ ERP_FUNCTIONMGRINFO,
ERP_FUNCTIONCALLINFO
} ExprRelPtrKind;
diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h
index 6250148159..ae874fca03 100644
--- a/src/include/jit/llvmjit.h
+++ b/src/include/jit/llvmjit.h
@@ -112,9 +112,9 @@ extern void llvm_split_symbol_name(const char *name, char **modname, char **func
extern LLVMValueRef llvm_get_decl(LLVMModuleRef mod, LLVMValueRef f);
extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,
- LLVMBuilderRef builder,
- LLVMModuleRef mod,
- FunctionCallInfo fcinfo);
+ LLVMBuilderRef builder,
+ LLVMModuleRef mod,
+ FunctionCallInfo fcinfo);
extern void llvm_inline(LLVMModuleRef mod);
--
2.24.1