From 31e27a06c265abcaf8bc991b691194fc6b7f90a0 Mon Sep 17 00:00:00 2001
From: soumyadeep2007 <sochakraborty@pivotal.io>
Date: Mon, 28 Oct 2019 22:25:20 -0700
Subject: [PATCH v2] Rely on llvmjit_types for building EvalFunc calls

Rely on llvmjit_types's referenced_functions for building calls to EvalFuncs.
This ensures signature checks for the calls constructed.
---
 src/backend/jit/llvm/llvmjit.c       |  84 +++++++--------
 src/backend/jit/llvm/llvmjit_expr.c  | 146 +++++++++++++++++----------
 src/backend/jit/llvm/llvmjit_types.c |  31 +++++-
 src/include/jit/llvmjit.h            |   3 +-
 4 files changed, 166 insertions(+), 98 deletions(-)

diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index cdac7b1c5d..be86ef2054 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -49,6 +49,7 @@ typedef struct LLVMJitHandle
 	LLVMOrcModuleHandle orc_handle;
 } LLVMJitHandle;
 
+LLVMModuleRef LLVMJITPGTypesModule = NULL;
 
 /* types & functions commonly needed for JITing */
 LLVMTypeRef TypeSizeT;
@@ -866,7 +867,6 @@ llvm_create_types(void)
 	char		path[MAXPGPATH];
 	LLVMMemoryBufferRef buf;
 	char	   *msg;
-	LLVMModuleRef mod = NULL;
 
 	snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
 
@@ -878,7 +878,7 @@ llvm_create_types(void)
 	}
 
 	/* eagerly load contents, going to need it all */
-	if (LLVMParseBitcode2(buf, &mod))
+	if (LLVMParseBitcode2(buf, &LLVMJITPGTypesModule))
 	{
 		elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
 	}
@@ -888,46 +888,46 @@ llvm_create_types(void)
 	 * Load triple & layout from clang emitted file so we're guaranteed to be
 	 * compatible.
 	 */
-	llvm_triple = pstrdup(LLVMGetTarget(mod));
-	llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod));
-
-	TypeSizeT = load_type(mod, "TypeSizeT");
-	TypeParamBool = load_return_type(mod, "FunctionReturningBool");
-	TypeStorageBool = load_type(mod, "TypeStorageBool");
-	TypePGFunction = load_type(mod, "TypePGFunction");
-	TypeExecEvalParamCallback = load_type(mod, "TypeExecEvalParamCallback");
-	StructNode = load_type(mod, "StructNode");
-	StructNullableDatum = load_type(mod, "StructNullableDatum");
-	StructExprContext = load_type(mod, "StructExprContext");
-	StructExprEvalStep = load_type(mod, "StructExprEvalStep");
-	StructExprEvalStepParamCallback = load_type(mod, "StructExprEvalStepParamCallback");
-	StructExprState = load_type(mod, "StructExprState");
-	StructFmgrInfo = load_type(mod, "StructFmgrInfo");
-	StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData");
-	StructMemoryContextData = load_type(mod, "StructMemoryContextData");
-	StructTupleTableSlot = load_type(mod, "StructTupleTableSlot");
-	StructHeapTupleTableSlot = load_type(mod, "StructHeapTupleTableSlot");
-	StructMinimalTupleTableSlot = load_type(mod, "StructMinimalTupleTableSlot");
-	StructHeapTupleData = load_type(mod, "StructHeapTupleData");
-	StructTupleDescData = load_type(mod, "StructTupleDescData");
-	StructAggState = load_type(mod, "StructAggState");
-	StructAggStatePerCallContext = load_type(mod, "StructAggStatePerCallContext");
-	StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData");
-	StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData");
-
-	AttributeTemplate = LLVMGetNamedFunction(mod, "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");
-	FuncExecEvalArrayCoerceRelabel = LLVMGetNamedFunction(mod, "ExecEvalArrayCoerceRelabel");
-	FuncExecEvalArrayCoerceUnpack = LLVMGetNamedFunction(mod, "ExecEvalArrayCoerceUnpack");
-	FuncExecEvalArrayCoercePack = LLVMGetNamedFunction(mod, "ExecEvalArrayCoercePack");
+	llvm_triple = pstrdup(LLVMGetTarget(LLVMJITPGTypesModule));
+	llvm_layout = pstrdup(LLVMGetDataLayoutStr(LLVMJITPGTypesModule));
+
+	TypeSizeT = load_type(LLVMJITPGTypesModule, "TypeSizeT");
+	TypeParamBool = load_return_type(LLVMJITPGTypesModule, "FunctionReturningBool");
+	TypeStorageBool = load_type(LLVMJITPGTypesModule, "TypeStorageBool");
+	TypePGFunction = load_type(LLVMJITPGTypesModule, "TypePGFunction");
+	TypeExecEvalParamCallback = load_type(LLVMJITPGTypesModule, "TypeExecEvalParamCallback");
+	StructNode = load_type(LLVMJITPGTypesModule, "StructNode");
+	StructNullableDatum = load_type(LLVMJITPGTypesModule, "StructNullableDatum");
+	StructExprContext = load_type(LLVMJITPGTypesModule, "StructExprContext");
+	StructExprEvalStep = load_type(LLVMJITPGTypesModule, "StructExprEvalStep");
+	StructExprEvalStepParamCallback = load_type(LLVMJITPGTypesModule, "StructExprEvalStepParamCallback");
+	StructExprState = load_type(LLVMJITPGTypesModule, "StructExprState");
+	StructFmgrInfo = load_type(LLVMJITPGTypesModule, "StructFmgrInfo");
+	StructFunctionCallInfoData = load_type(LLVMJITPGTypesModule, "StructFunctionCallInfoData");
+	StructMemoryContextData = load_type(LLVMJITPGTypesModule, "StructMemoryContextData");
+	StructTupleTableSlot = load_type(LLVMJITPGTypesModule, "StructTupleTableSlot");
+	StructHeapTupleTableSlot = load_type(LLVMJITPGTypesModule, "StructHeapTupleTableSlot");
+	StructMinimalTupleTableSlot = load_type(LLVMJITPGTypesModule, "StructMinimalTupleTableSlot");
+	StructHeapTupleData = load_type(LLVMJITPGTypesModule, "StructHeapTupleData");
+	StructTupleDescData = load_type(LLVMJITPGTypesModule, "StructTupleDescData");
+	StructAggState = load_type(LLVMJITPGTypesModule, "StructAggState");
+	StructAggStatePerCallContext = load_type(LLVMJITPGTypesModule, "StructAggStatePerCallContext");
+	StructAggStatePerGroupData = load_type(LLVMJITPGTypesModule, "StructAggStatePerGroupData");
+	StructAggStatePerTransData = load_type(LLVMJITPGTypesModule, "StructAggStatePerTransData");
+
+	AttributeTemplate = LLVMGetNamedFunction(LLVMJITPGTypesModule, "AttributeTemplate");
+	FuncStrlen = LLVMGetNamedFunction(LLVMJITPGTypesModule, "strlen");
+	FuncVarsizeAny = LLVMGetNamedFunction(LLVMJITPGTypesModule, "varsize_any");
+	FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(LLVMJITPGTypesModule, "slot_getsomeattrs_int");
+	FuncSlotGetmissingattrs = LLVMGetNamedFunction(LLVMJITPGTypesModule, "slot_getmissingattrs");
+	FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(LLVMJITPGTypesModule, "MakeExpandedObjectReadOnlyInternal");
+	FuncExecEvalSubscriptingRef = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSubscriptingRef");
+	FuncExecEvalSysVar = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSysVar");
+	FuncExecAggTransReparent = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecAggTransReparent");
+	FuncExecAggInitGroup = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecAggInitGroup");
+	FuncExecEvalArrayCoerceRelabel = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalArrayCoerceRelabel");
+	FuncExecEvalArrayCoerceUnpack = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalArrayCoerceUnpack");
+	FuncExecEvalArrayCoercePack = LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalArrayCoercePack");
 
 	/*
 	 * Leave the module alive, otherwise references to function would be
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index bbe0fd0cb3..d7e528f032 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -131,12 +131,12 @@ static LLVMValueRef BuildV1CallFC(ExprCompileState *ecs,
 								  LLVMValueRef v_fcinfo,
 								  LLVMValueRef *v_fcinfo_isnull);
 
-#define build_EvalXFunc(ecs, funcname, opno, ...) \
-	build_EvalXFuncInt(ecs, funcname, opno, \
+#define build_EvalXFunc(ecs, v_fn, opno, ...) \
+	build_EvalXFuncInt(ecs, v_fn, opno, \
 					   lengthof(((LLVMValueRef[]){__VA_ARGS__})), \
 					   ((LLVMValueRef[]){__VA_ARGS__}))
 
-static void build_EvalXFuncInt(ExprCompileState *ecs, const char *funcname,
+static void build_EvalXFuncInt(ExprCompileState *ecs, LLVMValueRef v_fn,
 							   int opno, int natts, LLVMValueRef v_args[]);
 
 /*
@@ -561,7 +561,9 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_WHOLEROW:
-				build_EvalXFunc(&ecs, "ExecEvalWholeRowVar", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalWholeRowVar"),
+								opno,
 								ecs.v_econtext,	v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -798,7 +800,9 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_FUNCEXPR_FUSAGE:
-				build_EvalXFunc(&ecs, "ExecEvalFuncExprFusage", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "EvalFuncExprFusage"),
+								opno,
 								v_resultp,
 								expr_fcinfo_ref(&ecs, op->d.func.fcinfo_data, NULL));
 				LLVMBuildBr(b, opblocks[opno + 1]);
@@ -806,7 +810,9 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 
 
 			case EEOP_FUNCEXPR_STRICT_FUSAGE:
-				build_EvalXFunc(&ecs, "ExecEvalFuncExprStrictFusage", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalFuncExprStrictFusage"),
+								opno,
 								v_resultp,
 								expr_fcinfo_ref(&ecs, op->d.func.fcinfo_data, NULL));
 				LLVMBuildBr(b, opblocks[opno + 1]);
@@ -1190,13 +1196,17 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_NULLTEST_ROWISNULL:
-				build_EvalXFunc(&ecs, "ExecEvalRowNull", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalRowNull"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_NULLTEST_ROWISNOTNULL:
-				build_EvalXFunc(&ecs, "ExecEvalRowNotNull", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalRowNotNull"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -1269,13 +1279,17 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_PARAM_EXEC:
-				build_EvalXFunc(&ecs, "ExecEvalParamExec", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalParamExec"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_PARAM_EXTERN:
-				build_EvalXFunc(&ecs, "ExecEvalParamExtern", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalParamExtern"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -1322,21 +1336,27 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_SBSREF_OLD:
-				build_EvalXFunc(&ecs, "ExecEvalSubscriptingRefOld", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSubscriptingRefOld"),
+								opno,
 								v_resultp,
 								expr_nullable_datum_ref(&ecs, op->d.sbsref.prev));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_SBSREF_ASSIGN:
-				build_EvalXFunc(&ecs, "ExecEvalSubscriptingRefAssign", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSubscriptingRefAssign"),
+									opno,
 								v_resultp,
 								expr_nullable_datum_ref(&ecs, op->d.sbsref.replace));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_SBSREF_FETCH:
-				build_EvalXFunc(&ecs, "ExecEvalSubscriptingRefFetch", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSubscriptingRefFetch"),
+								opno,
 								v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -1755,24 +1775,32 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_SQLVALUEFUNCTION:
-				build_EvalXFunc(&ecs, "ExecEvalSQLValueFunction", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSQLValueFunction"),
+								opno,
 								v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_CURRENTOFEXPR:
-				build_EvalXFunc(&ecs, "ExecEvalCurrentOfExpr", opno);
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalCurrentOfExpr"),
+								opno);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_NEXTVALUEEXPR:
-				build_EvalXFunc(&ecs, "ExecEvalNextValueExpr", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalNextValueExpr"),
+								opno,
 								v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_ARRAYEXPR:
-				build_EvalXFunc(&ecs, "ExecEvalArrayExpr", opno, v_resultp,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalArrayExpr"),
+								opno, v_resultp,
 								expr_nullable_datum_array_ref(&ecs, op->d.arrayexpr.elements));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -1842,7 +1870,9 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_ROW:
-				build_EvalXFunc(&ecs, "ExecEvalRow", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalRow"),
+								opno,
 								v_resultp,
 								expr_nullable_datum_array_ref(&ecs, op->d.row.elements));
 				LLVMBuildBr(b, opblocks[opno + 1]);
@@ -2003,7 +2033,9 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_MINMAX:
-				build_EvalXFunc(&ecs, "ExecEvalMinMax", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalMinMax"),
+								opno,
 								v_resultp,
 								expr_nullable_datum_array_ref(&ecs, op->d.minmax.arguments),
 								expr_fcinfo_ref(&ecs, op->d.minmax.fcinfo_data, NULL));
@@ -2011,20 +2043,26 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				break;
 
 			case EEOP_FIELDSELECT:
-				build_EvalXFunc(&ecs, "ExecEvalFieldSelect", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalFieldSelect"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_FIELDSTORE_DEFORM:
-				build_EvalXFunc(&ecs, "ExecEvalFieldStoreDeForm", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalFieldStoreDeForm"),
+								opno,
 								ecs.v_econtext, v_resultp,
 								expr_nullable_datum_array_ref(&ecs, op->d.fieldstore.columns));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_FIELDSTORE_FORM:
-				build_EvalXFunc(&ecs, "ExecEvalFieldStoreForm", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalFieldStoreForm"),
+								opno,
 								v_resultp,
 								expr_nullable_datum_array_ref(&ecs, op->d.fieldstore.columns));
 				LLVMBuildBr(b, opblocks[opno + 1]);
@@ -2101,32 +2139,42 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_DOMAIN_NOTNULL:
-				build_EvalXFunc(&ecs, "ExecEvalConstraintNotNull", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalConstraintNotNull"),
+								opno,
 								v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_DOMAIN_CHECK:
-				build_EvalXFunc(&ecs, "ExecEvalConstraintCheck", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalConstraintCheck"),
+								opno,
 								expr_nullable_datum_ref(&ecs, op->d.domaincheck.check));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_CONVERT_ROWTYPE:
-				build_EvalXFunc(&ecs, "ExecEvalConvertRowtype", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalConvertRowtype"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_SCALARARRAYOP:
-				build_EvalXFunc(&ecs, "ExecEvalScalarArrayOp", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalScalarArrayOp"),
+								opno,
 								v_resultp,
 								expr_fcinfo_ref(&ecs, op->d.scalararrayop.fcinfo_data, NULL));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_XMLEXPR:
-				build_EvalXFunc(&ecs, "ExecEvalXmlExpr", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalXmlExpr"),
+								opno,
 								v_resultp,
 								expr_nullable_datum_array_ref(&ecs, op->d.xmlexpr.args),
 								expr_nullable_datum_array_ref(&ecs, op->d.xmlexpr.named_args));
@@ -2162,7 +2210,9 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_GROUPING_FUNC:
-				build_EvalXFunc(&ecs, "ExecEvalGroupingFunc", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalGroupingFunc"),
+								opno,
 								v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -2196,13 +2246,17 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_SUBPLAN:
-				build_EvalXFunc(&ecs, "ExecEvalSubPlan", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalSubPlan"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_ALTERNATIVE_SUBPLAN:
-				build_EvalXFunc(&ecs, "ExecEvalAlternativeSubPlan", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalAlternativeSubPlan"),
+								opno,
 								ecs.v_econtext, v_resultp);
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -2551,13 +2605,17 @@ llvm_compile_expr(ExprState *state, ExprStateBuilder *esb)
 				}
 
 			case EEOP_AGG_ORDERED_TRANS_DATUM:
-				build_EvalXFunc(&ecs, "ExecEvalAggOrderedTransDatum", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalAggOrderedTransDatum"),
+								opno,
 								expr_nullable_datum_array_ref(&ecs, op->d.agg_trans_ordered.columns));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
 
 			case EEOP_AGG_ORDERED_TRANS_TUPLE:
-				build_EvalXFunc(&ecs, "ExecEvalAggOrderedTransTuple", opno,
+				build_EvalXFunc(&ecs,
+								LLVMGetNamedFunction(LLVMJITPGTypesModule, "ExecEvalAggOrderedTransTuple"),
+								opno,
 								expr_nullable_datum_array_ref(&ecs, op->d.agg_trans_ordered.columns));
 				LLVMBuildBr(b, opblocks[opno + 1]);
 				break;
@@ -3115,37 +3173,17 @@ BuildV1CallFC(ExprCompileState *ecs,
  * Implement an expression step by calling the function funcname.
  */
 static void
-build_EvalXFuncInt(ExprCompileState *ecs, const char *funcname, int opno,
+build_EvalXFuncInt(ExprCompileState *ecs, LLVMValueRef v_fn, int opno,
 				   int nargs, LLVMValueRef v_args[])
 {
 	LLVMValueRef v_opno = l_int32_const(opno);
 	LLVMValueRef v_opp;
-	LLVMTypeRef sig;
-	LLVMValueRef v_fn;
 	LLVMValueRef *params;
-	LLVMTypeRef *param_types;
 
 	params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
-	param_types = palloc(sizeof(LLVMValueRef) * (2 + nargs));
 
 	v_opp = LLVMBuildGEP(ecs->b, ecs->v_steps,
 						 (LLVMValueRef[]){l_int32_const(0), v_opno}, 2, "");
-	v_fn = LLVMGetNamedFunction(ecs->mod, funcname);
-	if (!v_fn)
-	{
-		int argno = 0;
-
-		param_types[argno++] = l_ptr(StructExprState);
-		param_types[argno++] = l_ptr(StructExprEvalStep);
-
-		for (int i = 0; i < nargs; i++)
-			param_types[argno++] = LLVMTypeOf(v_args[i]);
-
-		sig = LLVMFunctionType(LLVMVoidType(),
-							   param_types, argno,
-							   false);
-		v_fn = LLVMAddFunction(ecs->mod, funcname, sig);
-	}
 
 	{
 		int argno = 0;
@@ -3156,6 +3194,6 @@ build_EvalXFuncInt(ExprCompileState *ecs, const char *funcname, int opno,
 		for (int i = 0; i < nargs; i++)
 			params[argno++] = v_args[i];
 
-		LLVMBuildCall(ecs->b, v_fn, params, argno, "");
+		LLVMBuildCall(ecs->b, llvm_get_decl(ecs->mod, v_fn), params, argno, "");
 	}
 }
diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c
index 082b312060..d414e60b99 100644
--- a/src/backend/jit/llvm/llvmjit_types.c
+++ b/src/backend/jit/llvm/llvmjit_types.c
@@ -114,5 +114,34 @@ void	   *referenced_functions[] =
 	ExecAggInitGroup,
 	ExecEvalArrayCoerceRelabel,
 	ExecEvalArrayCoerceUnpack,
-	ExecEvalArrayCoercePack
+	ExecEvalArrayCoercePack,
+	ExecEvalFuncExprFusage,
+	ExecEvalFuncExprStrictFusage,
+	ExecEvalRowNull,
+	ExecEvalRowNotNull,
+	ExecEvalParamExec,
+	ExecEvalParamExtern,
+	ExecEvalSubscriptingRefOld,
+	ExecEvalSubscriptingRefAssign,
+	ExecEvalSubscriptingRefFetch,
+	ExecEvalSQLValueFunction,
+	ExecEvalCurrentOfExpr,
+	ExecEvalNextValueExpr,
+	ExecEvalArrayExpr,
+	ExecEvalRow,
+	ExecEvalMinMax,
+	ExecEvalFieldSelect,
+	ExecEvalFieldStoreDeForm,
+	ExecEvalFieldStoreForm,
+	ExecEvalConstraintNotNull,
+	ExecEvalConstraintCheck,
+	ExecEvalConvertRowtype,
+	ExecEvalScalarArrayOp,
+	ExecEvalXmlExpr,
+	ExecEvalGroupingFunc,
+	ExecEvalSubPlan,
+	ExecEvalAlternativeSubPlan,
+	ExecEvalAggOrderedTransDatum,
+	ExecEvalAggOrderedTransTuple,
+	ExecEvalWholeRowVar
 };
diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h
index 751bb69e25..2fb25eb899 100644
--- a/src/include/jit/llvmjit.h
+++ b/src/include/jit/llvmjit.h
@@ -57,6 +57,8 @@ typedef struct LLVMJitContext
 	List	   *handles;
 } LLVMJitContext;
 
+extern LLVMModuleRef LLVMJITPGTypesModule;
+
 
 /* type and struct definitions */
 extern LLVMTypeRef TypeParamBool;
@@ -98,7 +100,6 @@ extern LLVMValueRef FuncExecEvalArrayCoerceRelabel;
 extern LLVMValueRef FuncExecEvalArrayCoerceUnpack;
 extern LLVMValueRef FuncExecEvalArrayCoercePack;
 
-
 extern void llvm_enter_fatal_on_oom(void);
 extern void llvm_leave_fatal_on_oom(void);
 extern void llvm_reset_after_error(void);
-- 
2.23.0

