From dcee28d76d28a396cc6e925af61690afecd9c516 Mon Sep 17 00:00:00 2001 From: soumyadeep2007 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