jit: Reference expression step functions via llvmjit_types.
authorAndres Freund <andres@anarazel.de>
Fri, 7 Feb 2020 06:13:52 +0000 (22:13 -0800)
committerAndres Freund <andres@anarazel.de>
Fri, 7 Feb 2020 06:29:14 +0000 (22:29 -0800)
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

src/backend/jit/llvm/llvmjit.c
src/backend/jit/llvm/llvmjit_deform.c
src/backend/jit/llvm/llvmjit_expr.c
src/backend/jit/llvm/llvmjit_types.c
src/include/jit/llvmjit.h

index 2e77b8a1eac9f11663e2a04a607d7a89f122b5a1..af8b34aaaf3c7684ad13208976b0565d8eb47a15 100644 (file)
@@ -76,16 +76,8 @@ LLVMTypeRef StructAggStatePerGroupData;
 LLVMTypeRef StructAggStatePerTransData;
 
 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 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
- * necessary.
+ * Return declaration for a function referenced in llvmjit_types.c, adding it
+ * to the module if necessary.
  *
- * This is used to make functions imported by llvm_create_types() known to the
- * module that's currently being worked on.
+ * This is used to make functions discovered via llvm_create_types() known to
+ * the module that's currently being worked on.
  */
 LLVMValueRef
-llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src)
+llvm_pg_func(LLVMModuleRef mod, const char *funcname)
 {
+   LLVMValueRef v_srcfn;
    LLVMValueRef v_fn;
 
    /* don't repeatedly add function */
-   v_fn = LLVMGetNamedFunction(mod, LLVMGetValueName(v_src));
+   v_fn = LLVMGetNamedFunction(mod, funcname);
    if (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,
-                          LLVMGetValueName(v_src),
-                          LLVMGetElementType(LLVMTypeOf(v_src)));
-   llvm_copy_attributes(v_src, v_fn);
+                          funcname,
+                          LLVMGetElementType(LLVMTypeOf(v_srcfn)));
+   llvm_copy_attributes(v_srcfn, v_fn);
 
    return v_fn;
 }
@@ -775,7 +773,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");
 
@@ -787,7 +784,7 @@ llvm_create_types(void)
    }
 
    /* 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);
    }
@@ -797,43 +794,29 @@ 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");
-   StructNullableDatum = load_type(mod, "StructNullableDatum");
-   StructExprContext = load_type(mod, "StructExprContext");
-   StructExprEvalStep = load_type(mod, "StructExprEvalStep");
-   StructExprState = load_type(mod, "StructExprState");
-   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");
-   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");
-
-   /*
-    * Leave the module alive, otherwise references to function would be
-    * dangling.
-    */
+   llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
+   llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
+
+   TypeSizeT = load_type(llvm_types_module, "TypeSizeT");
+   TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
+   TypeStorageBool = load_type(llvm_types_module, "TypeStorageBool");
+   TypePGFunction = load_type(llvm_types_module, "TypePGFunction");
+   StructNullableDatum = load_type(llvm_types_module, "StructNullableDatum");
+   StructExprContext = load_type(llvm_types_module, "StructExprContext");
+   StructExprEvalStep = load_type(llvm_types_module, "StructExprEvalStep");
+   StructExprState = load_type(llvm_types_module, "StructExprState");
+   StructFunctionCallInfoData = load_type(llvm_types_module, "StructFunctionCallInfoData");
+   StructMemoryContextData = load_type(llvm_types_module, "StructMemoryContextData");
+   StructTupleTableSlot = load_type(llvm_types_module, "StructTupleTableSlot");
+   StructHeapTupleTableSlot = load_type(llvm_types_module, "StructHeapTupleTableSlot");
+   StructMinimalTupleTableSlot = load_type(llvm_types_module, "StructMinimalTupleTableSlot");
+   StructHeapTupleData = load_type(llvm_types_module, "StructHeapTupleData");
+   StructTupleDescData = load_type(llvm_types_module, "StructTupleDescData");
+   StructAggState = load_type(llvm_types_module, "StructAggState");
+   StructAggStatePerGroupData = load_type(llvm_types_module, "StructAggStatePerGroupData");
+   StructAggStatePerTransData = load_type(llvm_types_module, "StructAggStatePerTransData");
+
+   AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
 }
 
 /*
index ad2d3e5a5c8579b804d9f74420a4ec00bb8c4ef3..d7a7b328e8be60e903b26c9f79e9d16f54986c1a 100644 (file)
@@ -331,7 +331,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
        v_params[0] = v_slot;
        v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), "");
        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), "");
        LLVMBuildBr(b, b_find_start);
    }
@@ -682,7 +682,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
        else if (att->attlen == -1)
        {
            v_incby = LLVMBuildCall(b,
-                                   llvm_get_decl(mod, FuncVarsizeAny),
+                                   llvm_pg_func(mod, "varsize_any"),
                                    &v_attdatap, 1,
                                    "varsize_any");
            l_callsite_ro(v_incby);
@@ -691,7 +691,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
        else if (att->attlen == -2)
        {
            v_incby = LLVMBuildCall(b,
-                                   llvm_get_decl(mod, FuncStrlen),
+                                   llvm_pg_func(mod, "strlen"),
                                    &v_attdatap, 1, "strlen");
 
            l_callsite_ro(v_incby);
index 44a221b9a3a7e4befe2d11f3526de28dd8096cf7..cea0d6fa5ce8658a8233eacec069c9d4ea432e6a 100644 (file)
@@ -57,12 +57,19 @@ static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *
 static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
                                LLVMModuleRef mod, FunctionCallInfo fcinfo,
                                LLVMValueRef *v_fcinfo_isnull);
-static void build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod,
-                           const char *funcname,
-                           LLVMValueRef v_state, LLVMValueRef v_econtext,
-                           ExprEvalStep *op);
+static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod,
+                                      const char *funcname,
+                                      LLVMValueRef v_state,
+                                      ExprEvalStep *op,
+                                      int natts, LLVMValueRef v_args[]);
 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.
@@ -344,7 +351,7 @@ llvm_compile_expr(ExprState *state)
                        params[1] = l_int32_const(op->d.fetch.last_var);
 
                        LLVMBuildCall(b,
-                                     llvm_get_decl(mod, FuncSlotGetsomeattrsInt),
+                                     llvm_pg_func(mod, "slot_getsomeattrs_int"),
                                      params, lengthof(params), "");
                    }
 
@@ -393,7 +400,6 @@ llvm_compile_expr(ExprState *state)
            case EEOP_SCAN_SYSVAR:
                {
                    LLVMValueRef v_slot;
-                   LLVMValueRef v_params[4];
 
                    if (opcode == EEOP_INNER_SYSVAR)
                        v_slot = v_innerslot;
@@ -402,14 +408,8 @@ llvm_compile_expr(ExprState *state)
                    else
                        v_slot = v_scanslot;
 
-                   v_params[0] = v_state;
-                   v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
-                   v_params[2] = v_econtext;
-                   v_params[3] = v_slot;
-
-                   LLVMBuildCall(b,
-                                 llvm_get_decl(mod, FuncExecEvalSysVar),
-                                 v_params, lengthof(v_params), "");
+                   build_EvalXFunc(b, mod, "ExecEvalSysVar",
+                                   v_state, op, v_econtext, v_slot);
 
                    LLVMBuildBr(b, opblocks[opno + 1]);
                    break;
@@ -417,7 +417,7 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_WHOLEROW:
                build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -514,7 +514,7 @@ llvm_compile_expr(ExprState *state)
                        v_params[0] = v_value;
                        v_value =
                            LLVMBuildCall(b,
-                                         llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal),
+                                         llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
                                          v_params, lengthof(v_params), "");
 
                        /*
@@ -631,14 +631,14 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_FUNCEXPR_FUSAGE:
                build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
 
            case EEOP_FUNCEXPR_STRICT_FUSAGE:
                build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -999,13 +999,13 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_NULLTEST_ROWISNULL:
                build_EvalXFunc(b, mod, "ExecEvalRowNull",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_NULLTEST_ROWISNOTNULL:
                build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -1076,13 +1076,13 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_PARAM_EXEC:
                build_EvalXFunc(b, mod, "ExecEvalParamExec",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_PARAM_EXTERN:
                build_EvalXFunc(b, mod, "ExecEvalParamExtern",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -1117,19 +1117,19 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_SBSREF_OLD:
                build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_SBSREF_ASSIGN:
                build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_SBSREF_FETCH:
                build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -1221,7 +1221,7 @@ llvm_compile_expr(ExprState *state)
                    v_params[0] = v_value;
                    v_ret =
                        LLVMBuildCall(b,
-                                     llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal),
+                                     llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
                                      v_params, lengthof(v_params), "");
                    LLVMBuildStore(b, v_ret, v_resvaluep);
 
@@ -1539,37 +1539,37 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_SQLVALUEFUNCTION:
                build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_CURRENTOFEXPR:
                build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_NEXTVALUEEXPR:
                build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_ARRAYEXPR:
                build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_ARRAYCOERCE:
                build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_ROW:
                build_EvalXFunc(b, mod, "ExecEvalRow",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -1724,40 +1724,35 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_MINMAX:
                build_EvalXFunc(b, mod, "ExecEvalMinMax",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_FIELDSELECT:
                build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_FIELDSTORE_DEFORM:
                build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_FIELDSTORE_FORM:
                build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_SBSREF_SUBSCRIPT:
                {
                    int         jumpdone = op->d.sbsref_subscript.jumpdone;
-                   LLVMValueRef v_params[2];
                    LLVMValueRef v_ret;
 
-                   v_params[0] = v_state;
-                   v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
-                   v_ret =
-                       LLVMBuildCall(b,
-                                     llvm_get_decl(mod, FuncExecEvalSubscriptingRef),
-                                     v_params, lengthof(v_params), "");
+                   v_ret = build_EvalXFunc(b, mod, "ExecEvalSubscriptingRef",
+                                           v_state, op);
                    v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
 
                    LLVMBuildCondBr(b,
@@ -1824,31 +1819,31 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_DOMAIN_NOTNULL:
                build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_DOMAIN_CHECK:
                build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_CONVERT_ROWTYPE:
                build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_SCALARARRAYOP:
                build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_XMLEXPR:
                build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -1883,7 +1878,7 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_GROUPING_FUNC:
                build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
-                               v_state, v_econtext, op);
+                               v_state, op);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -1919,13 +1914,13 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_SUBPLAN:
                build_EvalXFunc(b, mod, "ExecEvalSubPlan",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_ALTERNATIVE_SUBPLAN:
                build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -2138,7 +2133,7 @@ llvm_compile_expr(ExprState *state)
                        params[2] = v_pergroupp;
 
                        LLVMBuildCall(b,
-                                     llvm_get_decl(mod, FuncExecAggInitGroup),
+                                     llvm_pg_func(mod, "ExecAggInitGroup"),
                                      params, lengthof(params),
                                      "");
                    }
@@ -2357,7 +2352,7 @@ 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),
@@ -2386,13 +2381,13 @@ llvm_compile_expr(ExprState *state)
 
            case EEOP_AGG_ORDERED_TRANS_DATUM:
                build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
            case EEOP_AGG_ORDERED_TRANS_TUPLE:
                build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
-                               v_state, v_econtext, op);
+                               v_state, op, v_econtext);
                LLVMBuildBr(b, opblocks[opno + 1]);
                break;
 
@@ -2504,36 +2499,34 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
 /*
  * Implement an expression step by calling the function funcname.
  */
-static void
-build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
-               LLVMValueRef v_state, LLVMValueRef v_econtext,
-               ExprEvalStep *op)
+static LLVMValueRef
+build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
+                  LLVMValueRef v_state, ExprEvalStep *op,
+                  int nargs, LLVMValueRef v_args[])
 {
-   LLVMTypeRef sig;
-   LLVMValueRef v_fn;
-   LLVMTypeRef param_types[3];
-   LLVMValueRef params[3];
+   LLVMValueRef v_fn = llvm_pg_func(mod, funcname);
+   LLVMValueRef *params;
+   int         argno = 0;
+   LLVMValueRef v_ret;
 
-   v_fn = LLVMGetNamedFunction(mod, funcname);
-   if (!v_fn)
-   {
-       param_types[0] = l_ptr(StructExprState);
-       param_types[1] = l_ptr(StructExprEvalStep);
-       param_types[2] = l_ptr(StructExprContext);
-
-       sig = LLVMFunctionType(LLVMVoidType(),
-                              param_types, lengthof(param_types),
-                              false);
-       v_fn = LLVMAddFunction(mod, funcname, sig);
-   }
+   /* cheap pre-check as llvm just asserts out */
+   if (LLVMCountParams(v_fn) != (nargs + 2))
+       elog(ERROR, "parameter mismatch: %s expects %d passed %d",
+            funcname, LLVMCountParams(v_fn), nargs + 2);
+
+   params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
+
+   params[argno++] = v_state;
+   params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
+
+   for (int i = 0; i < nargs; i++)
+       params[argno++] = v_args[i];
+
+   v_ret = LLVMBuildCall(b, v_fn, params, argno, "");
 
-   params[0] = v_state;
-   params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
-   params[2] = v_econtext;
+   pfree(params);
 
-   LLVMBuildCall(b,
-                 v_fn,
-                 params, lengthof(params), "");
+   return v_ret;
 }
 
 static LLVMValueRef
index 48768e6f898848796959dd59ab864d033cf927e7..0a93d5f6658cf1429137454a32f9c766105db51e 100644 (file)
@@ -98,13 +98,43 @@ FunctionReturningBool(void)
  */
 void      *referenced_functions[] =
 {
-   strlen,
-   varsize_any,
-   slot_getsomeattrs_int,
-   slot_getmissingattrs,
-   MakeExpandedObjectReadOnlyInternal,
+   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,
-   ExecAggTransReparent,
-   ExecAggInitGroup
+   ExecEvalWholeRowVar,
+   ExecEvalXmlExpr,
+   MakeExpandedObjectReadOnlyInternal,
+   slot_getmissingattrs,
+   slot_getsomeattrs_int,
+   strlen,
+   varsize_any,
 };
index a4eaa827354bab9cbbfa4082c8fa67be58f58418..706906c1cc833902932d7ade411bc269b5ff5643 100644 (file)
@@ -55,6 +55,8 @@ typedef struct LLVMJitContext
    List       *handles;
 } LLVMJitContext;
 
+/* llvm module containing information about types */
+extern LLVMModuleRef llvm_types_module;
 
 /* type and struct definitions */
 extern LLVMTypeRef TypeParamBool;
@@ -78,15 +80,6 @@ extern LLVMTypeRef StructAggStatePerTransData;
 extern LLVMTypeRef StructAggStatePerGroupData;
 
 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);
@@ -99,7 +92,7 @@ extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context);
 extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
 extern void *llvm_get_function(LLVMJitContext *context, const 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 LLVMValueRef llvm_function_reference(LLVMJitContext *context,
                        LLVMBuilderRef builder,