LCOV - code coverage report
Current view: top level - src/backend/jit/llvm - llvmjit_expr.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 582 874 66.6 %
Date: 2020-05-31 23:07:13 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * llvmjit_expr.c
       4             :  *    JIT compile expressions.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/jit/llvm/llvmjit_expr.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres.h"
      17             : 
      18             : #include <llvm-c/Core.h>
      19             : #include <llvm-c/Target.h>
      20             : 
      21             : #include "access/htup_details.h"
      22             : #include "access/nbtree.h"
      23             : #include "catalog/objectaccess.h"
      24             : #include "catalog/pg_type.h"
      25             : #include "executor/execExpr.h"
      26             : #include "executor/execdebug.h"
      27             : #include "executor/nodeAgg.h"
      28             : #include "executor/nodeSubplan.h"
      29             : #include "funcapi.h"
      30             : #include "jit/llvmjit.h"
      31             : #include "jit/llvmjit_emit.h"
      32             : #include "miscadmin.h"
      33             : #include "nodes/makefuncs.h"
      34             : #include "nodes/nodeFuncs.h"
      35             : #include "parser/parse_coerce.h"
      36             : #include "parser/parsetree.h"
      37             : #include "pgstat.h"
      38             : #include "utils/acl.h"
      39             : #include "utils/builtins.h"
      40             : #include "utils/date.h"
      41             : #include "utils/fmgrtab.h"
      42             : #include "utils/lsyscache.h"
      43             : #include "utils/memutils.h"
      44             : #include "utils/timestamp.h"
      45             : #include "utils/typcache.h"
      46             : #include "utils/xml.h"
      47             : 
      48             : typedef struct CompiledExprState
      49             : {
      50             :     LLVMJitContext *context;
      51             :     const char *funcname;
      52             : } CompiledExprState;
      53             : 
      54             : 
      55             : static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull);
      56             : 
      57             : static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
      58             :                                 LLVMModuleRef mod, FunctionCallInfo fcinfo,
      59             :                                 LLVMValueRef *v_fcinfo_isnull);
      60             : static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod,
      61             :                                        const char *funcname,
      62             :                                        LLVMValueRef v_state,
      63             :                                        ExprEvalStep *op,
      64             :                                        int natts, LLVMValueRef v_args[]);
      65             : static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod);
      66             : 
      67             : /* macro making it easier to call ExecEval* functions */
      68             : #define build_EvalXFunc(b, mod, funcname, v_state, op, ...) \
      69             :     build_EvalXFuncInt(b, mod, funcname, v_state, op, \
      70             :                        lengthof(((LLVMValueRef[]){__VA_ARGS__})), \
      71             :                        ((LLVMValueRef[]){__VA_ARGS__}))
      72             : 
      73             : 
      74             : /*
      75             :  * JIT compile expression.
      76             :  */
      77             : bool
      78        5072 : llvm_compile_expr(ExprState *state)
      79             : {
      80        5072 :     PlanState  *parent = state->parent;
      81             :     char       *funcname;
      82             : 
      83        5072 :     LLVMJitContext *context = NULL;
      84             : 
      85             :     LLVMBuilderRef b;
      86             :     LLVMModuleRef mod;
      87             :     LLVMTypeRef eval_sig;
      88             :     LLVMValueRef eval_fn;
      89             :     LLVMBasicBlockRef entry;
      90             :     LLVMBasicBlockRef *opblocks;
      91             : 
      92             :     /* state itself */
      93             :     LLVMValueRef v_state;
      94             :     LLVMValueRef v_econtext;
      95             :     LLVMValueRef v_parent;
      96             : 
      97             :     /* returnvalue */
      98             :     LLVMValueRef v_isnullp;
      99             : 
     100             :     /* tmp vars in state */
     101             :     LLVMValueRef v_tmpvaluep;
     102             :     LLVMValueRef v_tmpisnullp;
     103             : 
     104             :     /* slots */
     105             :     LLVMValueRef v_innerslot;
     106             :     LLVMValueRef v_outerslot;
     107             :     LLVMValueRef v_scanslot;
     108             :     LLVMValueRef v_resultslot;
     109             : 
     110             :     /* nulls/values of slots */
     111             :     LLVMValueRef v_innervalues;
     112             :     LLVMValueRef v_innernulls;
     113             :     LLVMValueRef v_outervalues;
     114             :     LLVMValueRef v_outernulls;
     115             :     LLVMValueRef v_scanvalues;
     116             :     LLVMValueRef v_scannulls;
     117             :     LLVMValueRef v_resultvalues;
     118             :     LLVMValueRef v_resultnulls;
     119             : 
     120             :     /* stuff in econtext */
     121             :     LLVMValueRef v_aggvalues;
     122             :     LLVMValueRef v_aggnulls;
     123             : 
     124             :     instr_time  starttime;
     125             :     instr_time  endtime;
     126             : 
     127        5072 :     llvm_enter_fatal_on_oom();
     128             : 
     129             :     /*
     130             :      * Right now we don't support compiling expressions without a parent, as
     131             :      * we need access to the EState.
     132             :      */
     133             :     Assert(parent);
     134             : 
     135             :     /* get or create JIT context */
     136        5072 :     if (parent->state->es_jit)
     137        4134 :         context = (LLVMJitContext *) parent->state->es_jit;
     138             :     else
     139             :     {
     140         938 :         context = llvm_create_context(parent->state->es_jit_flags);
     141         938 :         parent->state->es_jit = &context->base;
     142             :     }
     143             : 
     144        5072 :     INSTR_TIME_SET_CURRENT(starttime);
     145             : 
     146        5072 :     mod = llvm_mutable_module(context);
     147             : 
     148        5072 :     b = LLVMCreateBuilder();
     149             : 
     150        5072 :     funcname = llvm_expand_funcname(context, "evalexpr");
     151             : 
     152             :     /* Create the signature and function */
     153             :     {
     154             :         LLVMTypeRef param_types[3];
     155             : 
     156        5072 :         param_types[0] = l_ptr(StructExprState);    /* state */
     157        5072 :         param_types[1] = l_ptr(StructExprContext);  /* econtext */
     158        5072 :         param_types[2] = l_ptr(TypeParamBool);  /* isnull */
     159             : 
     160        5072 :         eval_sig = LLVMFunctionType(TypeSizeT,
     161             :                                     param_types, lengthof(param_types),
     162             :                                     false);
     163             :     }
     164        5072 :     eval_fn = LLVMAddFunction(mod, funcname, eval_sig);
     165        5072 :     LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
     166        5072 :     LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
     167        5072 :     llvm_copy_attributes(AttributeTemplate, eval_fn);
     168             : 
     169        5072 :     entry = LLVMAppendBasicBlock(eval_fn, "entry");
     170             : 
     171             :     /* build state */
     172        5072 :     v_state = LLVMGetParam(eval_fn, 0);
     173        5072 :     v_econtext = LLVMGetParam(eval_fn, 1);
     174        5072 :     v_isnullp = LLVMGetParam(eval_fn, 2);
     175             : 
     176        5072 :     LLVMPositionBuilderAtEnd(b, entry);
     177             : 
     178        5072 :     v_tmpvaluep = LLVMBuildStructGEP(b, v_state,
     179             :                                      FIELDNO_EXPRSTATE_RESVALUE,
     180             :                                      "v.state.resvalue");
     181        5072 :     v_tmpisnullp = LLVMBuildStructGEP(b, v_state,
     182             :                                       FIELDNO_EXPRSTATE_RESNULL,
     183             :                                       "v.state.resnull");
     184        5072 :     v_parent = l_load_struct_gep(b, v_state,
     185             :                                  FIELDNO_EXPRSTATE_PARENT,
     186             :                                  "v.state.parent");
     187             : 
     188             :     /* build global slots */
     189        5072 :     v_scanslot = l_load_struct_gep(b, v_econtext,
     190             :                                    FIELDNO_EXPRCONTEXT_SCANTUPLE,
     191             :                                    "v_scanslot");
     192        5072 :     v_innerslot = l_load_struct_gep(b, v_econtext,
     193             :                                     FIELDNO_EXPRCONTEXT_INNERTUPLE,
     194             :                                     "v_innerslot");
     195        5072 :     v_outerslot = l_load_struct_gep(b, v_econtext,
     196             :                                     FIELDNO_EXPRCONTEXT_OUTERTUPLE,
     197             :                                     "v_outerslot");
     198        5072 :     v_resultslot = l_load_struct_gep(b, v_state,
     199             :                                      FIELDNO_EXPRSTATE_RESULTSLOT,
     200             :                                      "v_resultslot");
     201             : 
     202             :     /* build global values/isnull pointers */
     203        5072 :     v_scanvalues = l_load_struct_gep(b, v_scanslot,
     204             :                                      FIELDNO_TUPLETABLESLOT_VALUES,
     205             :                                      "v_scanvalues");
     206        5072 :     v_scannulls = l_load_struct_gep(b, v_scanslot,
     207             :                                     FIELDNO_TUPLETABLESLOT_ISNULL,
     208             :                                     "v_scannulls");
     209        5072 :     v_innervalues = l_load_struct_gep(b, v_innerslot,
     210             :                                       FIELDNO_TUPLETABLESLOT_VALUES,
     211             :                                       "v_innervalues");
     212        5072 :     v_innernulls = l_load_struct_gep(b, v_innerslot,
     213             :                                      FIELDNO_TUPLETABLESLOT_ISNULL,
     214             :                                      "v_innernulls");
     215        5072 :     v_outervalues = l_load_struct_gep(b, v_outerslot,
     216             :                                       FIELDNO_TUPLETABLESLOT_VALUES,
     217             :                                       "v_outervalues");
     218        5072 :     v_outernulls = l_load_struct_gep(b, v_outerslot,
     219             :                                      FIELDNO_TUPLETABLESLOT_ISNULL,
     220             :                                      "v_outernulls");
     221        5072 :     v_resultvalues = l_load_struct_gep(b, v_resultslot,
     222             :                                        FIELDNO_TUPLETABLESLOT_VALUES,
     223             :                                        "v_resultvalues");
     224        5072 :     v_resultnulls = l_load_struct_gep(b, v_resultslot,
     225             :                                       FIELDNO_TUPLETABLESLOT_ISNULL,
     226             :                                       "v_resultnulls");
     227             : 
     228             :     /* aggvalues/aggnulls */
     229        5072 :     v_aggvalues = l_load_struct_gep(b, v_econtext,
     230             :                                     FIELDNO_EXPRCONTEXT_AGGVALUES,
     231             :                                     "v.econtext.aggvalues");
     232        5072 :     v_aggnulls = l_load_struct_gep(b, v_econtext,
     233             :                                    FIELDNO_EXPRCONTEXT_AGGNULLS,
     234             :                                    "v.econtext.aggnulls");
     235             : 
     236             :     /* allocate blocks for each op upfront, so we can do jumps easily */
     237        5072 :     opblocks = palloc(sizeof(LLVMBasicBlockRef) * state->steps_len);
     238       28182 :     for (int opno = 0; opno < state->steps_len; opno++)
     239       23110 :         opblocks[opno] = l_bb_append_v(eval_fn, "b.op.%d.start", opno);
     240             : 
     241             :     /* jump from entry to first block */
     242        5072 :     LLVMBuildBr(b, opblocks[0]);
     243             : 
     244       28182 :     for (int opno = 0; opno < state->steps_len; opno++)
     245             :     {
     246             :         ExprEvalStep *op;
     247             :         ExprEvalOp  opcode;
     248             :         LLVMValueRef v_resvaluep;
     249             :         LLVMValueRef v_resnullp;
     250             : 
     251       23110 :         LLVMPositionBuilderAtEnd(b, opblocks[opno]);
     252             : 
     253       23110 :         op = &state->steps[opno];
     254       23110 :         opcode = ExecEvalStepOp(state, op);
     255             : 
     256       23110 :         v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeSizeT));
     257       23110 :         v_resnullp = l_ptr_const(op->resnull, l_ptr(TypeStorageBool));
     258             : 
     259       23110 :         switch (opcode)
     260             :         {
     261        5072 :             case EEOP_DONE:
     262             :                 {
     263             :                     LLVMValueRef v_tmpisnull;
     264             :                     LLVMValueRef v_tmpvalue;
     265             : 
     266        5072 :                     v_tmpvalue = LLVMBuildLoad(b, v_tmpvaluep, "");
     267        5072 :                     v_tmpisnull = LLVMBuildLoad(b, v_tmpisnullp, "");
     268             :                     v_tmpisnull =
     269        5072 :                         LLVMBuildTrunc(b, v_tmpisnull, TypeParamBool, "");
     270             : 
     271        5072 :                     LLVMBuildStore(b, v_tmpisnull, v_isnullp);
     272             : 
     273        5072 :                     LLVMBuildRet(b, v_tmpvalue);
     274        5072 :                     break;
     275             :                 }
     276             : 
     277        3686 :             case EEOP_INNER_FETCHSOME:
     278             :             case EEOP_OUTER_FETCHSOME:
     279             :             case EEOP_SCAN_FETCHSOME:
     280             :                 {
     281        3686 :                     TupleDesc   desc = NULL;
     282             :                     LLVMValueRef v_slot;
     283             :                     LLVMBasicBlockRef b_fetch;
     284             :                     LLVMValueRef v_nvalid;
     285        3686 :                     LLVMValueRef l_jit_deform = NULL;
     286        3686 :                     const TupleTableSlotOps *tts_ops = NULL;
     287             : 
     288        3686 :                     b_fetch = l_bb_before_v(opblocks[opno + 1],
     289             :                                             "op.%d.fetch", opno);
     290             : 
     291        3686 :                     if (op->d.fetch.known_desc)
     292        3162 :                         desc = op->d.fetch.known_desc;
     293             : 
     294        3686 :                     if (op->d.fetch.fixed)
     295        3162 :                         tts_ops = op->d.fetch.kind;
     296             : 
     297             :                     /* step should not have been generated */
     298             :                     Assert(tts_ops != &TTSOpsVirtual);
     299             : 
     300        3686 :                     if (opcode == EEOP_INNER_FETCHSOME)
     301         840 :                         v_slot = v_innerslot;
     302        2846 :                     else if (opcode == EEOP_OUTER_FETCHSOME)
     303        1092 :                         v_slot = v_outerslot;
     304             :                     else
     305        1754 :                         v_slot = v_scanslot;
     306             : 
     307             :                     /*
     308             :                      * Check if all required attributes are available, or
     309             :                      * whether deforming is required.
     310             :                      */
     311             :                     v_nvalid =
     312        3686 :                         l_load_struct_gep(b, v_slot,
     313             :                                           FIELDNO_TUPLETABLESLOT_NVALID,
     314             :                                           "");
     315        3686 :                     LLVMBuildCondBr(b,
     316             :                                     LLVMBuildICmp(b, LLVMIntUGE, v_nvalid,
     317        3686 :                                                   l_int16_const(op->d.fetch.last_var),
     318             :                                                   ""),
     319        3686 :                                     opblocks[opno + 1], b_fetch);
     320             : 
     321        3686 :                     LLVMPositionBuilderAtEnd(b, b_fetch);
     322             : 
     323             :                     /*
     324             :                      * If the tupledesc of the to-be-deformed tuple is known,
     325             :                      * and JITing of deforming is enabled, build deform
     326             :                      * function specific to tupledesc and the exact number of
     327             :                      * to-be-extracted attributes.
     328             :                      */
     329        3686 :                     if (tts_ops && desc && (context->base.flags & PGJIT_DEFORM))
     330             :                     {
     331             :                         l_jit_deform =
     332        3162 :                             slot_compile_deform(context, desc,
     333             :                                                 tts_ops,
     334             :                                                 op->d.fetch.last_var);
     335             :                     }
     336             : 
     337        3686 :                     if (l_jit_deform)
     338             :                     {
     339             :                         LLVMValueRef params[1];
     340             : 
     341        3162 :                         params[0] = v_slot;
     342             : 
     343        3162 :                         LLVMBuildCall(b, l_jit_deform,
     344             :                                       params, lengthof(params), "");
     345             :                     }
     346             :                     else
     347             :                     {
     348             :                         LLVMValueRef params[2];
     349             : 
     350         524 :                         params[0] = v_slot;
     351         524 :                         params[1] = l_int32_const(op->d.fetch.last_var);
     352             : 
     353         524 :                         LLVMBuildCall(b,
     354             :                                       llvm_pg_func(mod, "slot_getsomeattrs_int"),
     355             :                                       params, lengthof(params), "");
     356             :                     }
     357             : 
     358        3686 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     359        3686 :                     break;
     360             :                 }
     361             : 
     362        3694 :             case EEOP_INNER_VAR:
     363             :             case EEOP_OUTER_VAR:
     364             :             case EEOP_SCAN_VAR:
     365             :                 {
     366             :                     LLVMValueRef value,
     367             :                                 isnull;
     368             :                     LLVMValueRef v_attnum;
     369             :                     LLVMValueRef v_values;
     370             :                     LLVMValueRef v_nulls;
     371             : 
     372        3694 :                     if (opcode == EEOP_INNER_VAR)
     373             :                     {
     374         888 :                         v_values = v_innervalues;
     375         888 :                         v_nulls = v_innernulls;
     376             :                     }
     377        2806 :                     else if (opcode == EEOP_OUTER_VAR)
     378             :                     {
     379        1790 :                         v_values = v_outervalues;
     380        1790 :                         v_nulls = v_outernulls;
     381             :                     }
     382             :                     else
     383             :                     {
     384        1016 :                         v_values = v_scanvalues;
     385        1016 :                         v_nulls = v_scannulls;
     386             :                     }
     387             : 
     388        3694 :                     v_attnum = l_int32_const(op->d.var.attnum);
     389        3694 :                     value = l_load_gep1(b, v_values, v_attnum, "");
     390        3694 :                     isnull = l_load_gep1(b, v_nulls, v_attnum, "");
     391        3694 :                     LLVMBuildStore(b, value, v_resvaluep);
     392        3694 :                     LLVMBuildStore(b, isnull, v_resnullp);
     393             : 
     394        3694 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     395        3694 :                     break;
     396             :                 }
     397             : 
     398         174 :             case EEOP_INNER_SYSVAR:
     399             :             case EEOP_OUTER_SYSVAR:
     400             :             case EEOP_SCAN_SYSVAR:
     401             :                 {
     402             :                     LLVMValueRef v_slot;
     403             : 
     404         174 :                     if (opcode == EEOP_INNER_SYSVAR)
     405           0 :                         v_slot = v_innerslot;
     406         174 :                     else if (opcode == EEOP_OUTER_SYSVAR)
     407           0 :                         v_slot = v_outerslot;
     408             :                     else
     409         174 :                         v_slot = v_scanslot;
     410             : 
     411         174 :                     build_EvalXFunc(b, mod, "ExecEvalSysVar",
     412             :                                     v_state, op, v_econtext, v_slot);
     413             : 
     414         174 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     415         174 :                     break;
     416             :                 }
     417             : 
     418          96 :             case EEOP_WHOLEROW:
     419          96 :                 build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
     420             :                                 v_state, op, v_econtext);
     421          96 :                 LLVMBuildBr(b, opblocks[opno + 1]);
     422          96 :                 break;
     423             : 
     424        2474 :             case EEOP_ASSIGN_INNER_VAR:
     425             :             case EEOP_ASSIGN_OUTER_VAR:
     426             :             case EEOP_ASSIGN_SCAN_VAR:
     427             :                 {
     428             :                     LLVMValueRef v_value;
     429             :                     LLVMValueRef v_isnull;
     430             :                     LLVMValueRef v_rvaluep;
     431             :                     LLVMValueRef v_risnullp;
     432             :                     LLVMValueRef v_attnum;
     433             :                     LLVMValueRef v_resultnum;
     434             :                     LLVMValueRef v_values;
     435             :                     LLVMValueRef v_nulls;
     436             : 
     437        2474 :                     if (opcode == EEOP_ASSIGN_INNER_VAR)
     438             :                     {
     439         398 :                         v_values = v_innervalues;
     440         398 :                         v_nulls = v_innernulls;
     441             :                     }
     442        2076 :                     else if (opcode == EEOP_ASSIGN_OUTER_VAR)
     443             :                     {
     444         868 :                         v_values = v_outervalues;
     445         868 :                         v_nulls = v_outernulls;
     446             :                     }
     447             :                     else
     448             :                     {
     449        1208 :                         v_values = v_scanvalues;
     450        1208 :                         v_nulls = v_scannulls;
     451             :                     }
     452             : 
     453             :                     /* load data */
     454        2474 :                     v_attnum = l_int32_const(op->d.assign_var.attnum);
     455        2474 :                     v_value = l_load_gep1(b, v_values, v_attnum, "");
     456        2474 :                     v_isnull = l_load_gep1(b, v_nulls, v_attnum, "");
     457             : 
     458             :                     /* compute addresses of targets */
     459        2474 :                     v_resultnum = l_int32_const(op->d.assign_var.resultnum);
     460        2474 :                     v_rvaluep = LLVMBuildGEP(b, v_resultvalues,
     461             :                                              &v_resultnum, 1, "");
     462        2474 :                     v_risnullp = LLVMBuildGEP(b, v_resultnulls,
     463             :                                               &v_resultnum, 1, "");
     464             : 
     465             :                     /* and store */
     466        2474 :                     LLVMBuildStore(b, v_value, v_rvaluep);
     467        2474 :                     LLVMBuildStore(b, v_isnull, v_risnullp);
     468             : 
     469        2474 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     470        2474 :                     break;
     471             :                 }
     472             : 
     473        1236 :             case EEOP_ASSIGN_TMP:
     474             :             case EEOP_ASSIGN_TMP_MAKE_RO:
     475             :                 {
     476             :                     LLVMValueRef v_value,
     477             :                                 v_isnull;
     478             :                     LLVMValueRef v_rvaluep,
     479             :                                 v_risnullp;
     480             :                     LLVMValueRef v_resultnum;
     481        1236 :                     size_t      resultnum = op->d.assign_tmp.resultnum;
     482             : 
     483             :                     /* load data */
     484        1236 :                     v_value = LLVMBuildLoad(b, v_tmpvaluep, "");
     485        1236 :                     v_isnull = LLVMBuildLoad(b, v_tmpisnullp, "");
     486             : 
     487             :                     /* compute addresses of targets */
     488        1236 :                     v_resultnum = l_int32_const(resultnum);
     489             :                     v_rvaluep =
     490        1236 :                         LLVMBuildGEP(b, v_resultvalues, &v_resultnum, 1, "");
     491             :                     v_risnullp =
     492        1236 :                         LLVMBuildGEP(b, v_resultnulls, &v_resultnum, 1, "");
     493             : 
     494             :                     /* store nullness */
     495        1236 :                     LLVMBuildStore(b, v_isnull, v_risnullp);
     496             : 
     497             :                     /* make value readonly if necessary */
     498        1236 :                     if (opcode == EEOP_ASSIGN_TMP_MAKE_RO)
     499             :                     {
     500             :                         LLVMBasicBlockRef b_notnull;
     501             :                         LLVMValueRef v_params[1];
     502             : 
     503         456 :                         b_notnull = l_bb_before_v(opblocks[opno + 1],
     504             :                                                   "op.%d.assign_tmp.notnull", opno);
     505             : 
     506             :                         /* check if value is NULL */
     507         456 :                         LLVMBuildCondBr(b,
     508             :                                         LLVMBuildICmp(b, LLVMIntEQ, v_isnull,
     509             :                                                       l_sbool_const(0), ""),
     510         456 :                                         b_notnull, opblocks[opno + 1]);
     511             : 
     512             :                         /* if value is not null, convert to RO datum */
     513         456 :                         LLVMPositionBuilderAtEnd(b, b_notnull);
     514         456 :                         v_params[0] = v_value;
     515             :                         v_value =
     516         456 :                             LLVMBuildCall(b,
     517             :                                           llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
     518             :                                           v_params, lengthof(v_params), "");
     519             : 
     520             :                         /*
     521             :                          * Falling out of the if () with builder in b_notnull,
     522             :                          * which is fine - the null is already stored above.
     523             :                          */
     524             :                     }
     525             : 
     526             :                     /* and finally store result */
     527        1236 :                     LLVMBuildStore(b, v_value, v_rvaluep);
     528             : 
     529        1236 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     530        1236 :                     break;
     531             :                 }
     532             : 
     533         532 :             case EEOP_CONST:
     534             :                 {
     535             :                     LLVMValueRef v_constvalue,
     536             :                                 v_constnull;
     537             : 
     538         532 :                     v_constvalue = l_sizet_const(op->d.constval.value);
     539         532 :                     v_constnull = l_sbool_const(op->d.constval.isnull);
     540             : 
     541         532 :                     LLVMBuildStore(b, v_constvalue, v_resvaluep);
     542         532 :                     LLVMBuildStore(b, v_constnull, v_resnullp);
     543             : 
     544         532 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     545         532 :                     break;
     546             :                 }
     547             : 
     548        1596 :             case EEOP_FUNCEXPR:
     549             :             case EEOP_FUNCEXPR_STRICT:
     550             :                 {
     551        1596 :                     FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
     552             :                     LLVMValueRef v_fcinfo_isnull;
     553             :                     LLVMValueRef v_retval;
     554             : 
     555        1596 :                     if (opcode == EEOP_FUNCEXPR_STRICT)
     556             :                     {
     557             :                         LLVMBasicBlockRef b_nonull;
     558             :                         LLVMBasicBlockRef *b_checkargnulls;
     559             :                         LLVMValueRef v_fcinfo;
     560             : 
     561             :                         /*
     562             :                          * Block for the actual function call, if args are
     563             :                          * non-NULL.
     564             :                          */
     565        1596 :                         b_nonull = l_bb_before_v(opblocks[opno + 1],
     566             :                                                  "b.%d.no-null-args", opno);
     567             : 
     568             :                         /* should make sure they're optimized beforehand */
     569        1596 :                         if (op->d.func.nargs == 0)
     570           0 :                             elog(ERROR, "argumentless strict functions are pointless");
     571             : 
     572             :                         v_fcinfo =
     573        1596 :                             l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
     574             : 
     575             :                         /*
     576             :                          * set resnull to true, if the function is actually
     577             :                          * called, it'll be reset
     578             :                          */
     579        1596 :                         LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
     580             : 
     581             :                         /* create blocks for checking args, one for each */
     582             :                         b_checkargnulls =
     583        1596 :                             palloc(sizeof(LLVMBasicBlockRef *) * op->d.func.nargs);
     584        4604 :                         for (int argno = 0; argno < op->d.func.nargs; argno++)
     585        3008 :                             b_checkargnulls[argno] =
     586        3008 :                                 l_bb_before_v(b_nonull, "b.%d.isnull.%d", opno,
     587             :                                               argno);
     588             : 
     589             :                         /* jump to check of first argument */
     590        1596 :                         LLVMBuildBr(b, b_checkargnulls[0]);
     591             : 
     592             :                         /* check each arg for NULLness */
     593        4604 :                         for (int argno = 0; argno < op->d.func.nargs; argno++)
     594             :                         {
     595             :                             LLVMValueRef v_argisnull;
     596             :                             LLVMBasicBlockRef b_argnotnull;
     597             : 
     598        3008 :                             LLVMPositionBuilderAtEnd(b, b_checkargnulls[argno]);
     599             : 
     600             :                             /*
     601             :                              * Compute block to jump to if argument is not
     602             :                              * null.
     603             :                              */
     604        3008 :                             if (argno + 1 == op->d.func.nargs)
     605        1596 :                                 b_argnotnull = b_nonull;
     606             :                             else
     607        1412 :                                 b_argnotnull = b_checkargnulls[argno + 1];
     608             : 
     609             :                             /* and finally load & check NULLness of arg */
     610        3008 :                             v_argisnull = l_funcnull(b, v_fcinfo, argno);
     611        3008 :                             LLVMBuildCondBr(b,
     612             :                                             LLVMBuildICmp(b, LLVMIntEQ,
     613             :                                                           v_argisnull,
     614             :                                                           l_sbool_const(1),
     615             :                                                           ""),
     616        3008 :                                             opblocks[opno + 1],
     617             :                                             b_argnotnull);
     618             :                         }
     619             : 
     620        1596 :                         LLVMPositionBuilderAtEnd(b, b_nonull);
     621             :                     }
     622             : 
     623        1596 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
     624             :                                            &v_fcinfo_isnull);
     625        1596 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
     626        1596 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
     627             : 
     628        1596 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     629        1596 :                     break;
     630             :                 }
     631             : 
     632           0 :             case EEOP_FUNCEXPR_FUSAGE:
     633           0 :                 build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
     634             :                                 v_state, op, v_econtext);
     635           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
     636           0 :                 break;
     637             : 
     638             : 
     639           0 :             case EEOP_FUNCEXPR_STRICT_FUSAGE:
     640           0 :                 build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
     641             :                                 v_state, op, v_econtext);
     642           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
     643           0 :                 break;
     644             : 
     645             :                 /*
     646             :                  * Treat them the same for now, optimizer can remove
     647             :                  * redundancy. Could be worthwhile to optimize during emission
     648             :                  * though.
     649             :                  */
     650          24 :             case EEOP_BOOL_AND_STEP_FIRST:
     651             :             case EEOP_BOOL_AND_STEP:
     652             :             case EEOP_BOOL_AND_STEP_LAST:
     653             :                 {
     654             :                     LLVMValueRef v_boolvalue;
     655             :                     LLVMValueRef v_boolnull;
     656             :                     LLVMValueRef v_boolanynullp,
     657             :                                 v_boolanynull;
     658             :                     LLVMBasicBlockRef b_boolisnull;
     659             :                     LLVMBasicBlockRef b_boolcheckfalse;
     660             :                     LLVMBasicBlockRef b_boolisfalse;
     661             :                     LLVMBasicBlockRef b_boolcont;
     662             :                     LLVMBasicBlockRef b_boolisanynull;
     663             : 
     664          24 :                     b_boolisnull = l_bb_before_v(opblocks[opno + 1],
     665             :                                                  "b.%d.boolisnull", opno);
     666          24 :                     b_boolcheckfalse = l_bb_before_v(opblocks[opno + 1],
     667             :                                                      "b.%d.boolcheckfalse", opno);
     668          24 :                     b_boolisfalse = l_bb_before_v(opblocks[opno + 1],
     669             :                                                   "b.%d.boolisfalse", opno);
     670          24 :                     b_boolisanynull = l_bb_before_v(opblocks[opno + 1],
     671             :                                                     "b.%d.boolisanynull", opno);
     672          24 :                     b_boolcont = l_bb_before_v(opblocks[opno + 1],
     673             :                                                "b.%d.boolcont", opno);
     674             : 
     675          24 :                     v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
     676             :                                                  l_ptr(TypeStorageBool));
     677             : 
     678          24 :                     if (opcode == EEOP_BOOL_AND_STEP_FIRST)
     679          12 :                         LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
     680             : 
     681          24 :                     v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
     682          24 :                     v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
     683             : 
     684             :                     /* set resnull to boolnull */
     685          24 :                     LLVMBuildStore(b, v_boolnull, v_resnullp);
     686             :                     /* set revalue to boolvalue */
     687          24 :                     LLVMBuildStore(b, v_boolvalue, v_resvaluep);
     688             : 
     689             :                     /* check if current input is NULL */
     690          24 :                     LLVMBuildCondBr(b,
     691             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
     692             :                                                   l_sbool_const(1), ""),
     693             :                                     b_boolisnull,
     694             :                                     b_boolcheckfalse);
     695             : 
     696             :                     /* build block that sets anynull */
     697          24 :                     LLVMPositionBuilderAtEnd(b, b_boolisnull);
     698             :                     /* set boolanynull to true */
     699          24 :                     LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
     700             :                     /* and jump to next block */
     701          24 :                     LLVMBuildBr(b, b_boolcont);
     702             : 
     703             :                     /* build block checking for false */
     704          24 :                     LLVMPositionBuilderAtEnd(b, b_boolcheckfalse);
     705          24 :                     LLVMBuildCondBr(b,
     706             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
     707             :                                                   l_sizet_const(0), ""),
     708             :                                     b_boolisfalse,
     709             :                                     b_boolcont);
     710             : 
     711             :                     /*
     712             :                      * Build block handling FALSE. Value is false, so short
     713             :                      * circuit.
     714             :                      */
     715          24 :                     LLVMPositionBuilderAtEnd(b, b_boolisfalse);
     716             :                     /* result is already set to FALSE, need not change it */
     717             :                     /* and jump to the end of the AND expression */
     718          24 :                     LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]);
     719             : 
     720             :                     /* Build block that continues if bool is TRUE. */
     721          24 :                     LLVMPositionBuilderAtEnd(b, b_boolcont);
     722             : 
     723          24 :                     v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, "");
     724             : 
     725             :                     /* set value to NULL if any previous values were NULL */
     726          24 :                     LLVMBuildCondBr(b,
     727             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
     728             :                                                   l_sbool_const(0), ""),
     729          24 :                                     opblocks[opno + 1], b_boolisanynull);
     730             : 
     731          24 :                     LLVMPositionBuilderAtEnd(b, b_boolisanynull);
     732             :                     /* set resnull to true */
     733          24 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
     734             :                     /* reset resvalue */
     735          24 :                     LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
     736             : 
     737          24 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     738          24 :                     break;
     739             :                 }
     740             : 
     741             :                 /*
     742             :                  * Treat them the same for now, optimizer can remove
     743             :                  * redundancy. Could be worthwhile to optimize during emission
     744             :                  * though.
     745             :                  */
     746          60 :             case EEOP_BOOL_OR_STEP_FIRST:
     747             :             case EEOP_BOOL_OR_STEP:
     748             :             case EEOP_BOOL_OR_STEP_LAST:
     749             :                 {
     750             :                     LLVMValueRef v_boolvalue;
     751             :                     LLVMValueRef v_boolnull;
     752             :                     LLVMValueRef v_boolanynullp,
     753             :                                 v_boolanynull;
     754             : 
     755             :                     LLVMBasicBlockRef b_boolisnull;
     756             :                     LLVMBasicBlockRef b_boolchecktrue;
     757             :                     LLVMBasicBlockRef b_boolistrue;
     758             :                     LLVMBasicBlockRef b_boolcont;
     759             :                     LLVMBasicBlockRef b_boolisanynull;
     760             : 
     761          60 :                     b_boolisnull = l_bb_before_v(opblocks[opno + 1],
     762             :                                                  "b.%d.boolisnull", opno);
     763          60 :                     b_boolchecktrue = l_bb_before_v(opblocks[opno + 1],
     764             :                                                     "b.%d.boolchecktrue", opno);
     765          60 :                     b_boolistrue = l_bb_before_v(opblocks[opno + 1],
     766             :                                                  "b.%d.boolistrue", opno);
     767          60 :                     b_boolisanynull = l_bb_before_v(opblocks[opno + 1],
     768             :                                                     "b.%d.boolisanynull", opno);
     769          60 :                     b_boolcont = l_bb_before_v(opblocks[opno + 1],
     770             :                                                "b.%d.boolcont", opno);
     771             : 
     772          60 :                     v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
     773             :                                                  l_ptr(TypeStorageBool));
     774             : 
     775          60 :                     if (opcode == EEOP_BOOL_OR_STEP_FIRST)
     776          30 :                         LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
     777          60 :                     v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
     778          60 :                     v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
     779             : 
     780             :                     /* set resnull to boolnull */
     781          60 :                     LLVMBuildStore(b, v_boolnull, v_resnullp);
     782             :                     /* set revalue to boolvalue */
     783          60 :                     LLVMBuildStore(b, v_boolvalue, v_resvaluep);
     784             : 
     785          60 :                     LLVMBuildCondBr(b,
     786             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
     787             :                                                   l_sbool_const(1), ""),
     788             :                                     b_boolisnull,
     789             :                                     b_boolchecktrue);
     790             : 
     791             :                     /* build block that sets anynull */
     792          60 :                     LLVMPositionBuilderAtEnd(b, b_boolisnull);
     793             :                     /* set boolanynull to true */
     794          60 :                     LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
     795             :                     /* and jump to next block */
     796          60 :                     LLVMBuildBr(b, b_boolcont);
     797             : 
     798             :                     /* build block checking for true */
     799          60 :                     LLVMPositionBuilderAtEnd(b, b_boolchecktrue);
     800          60 :                     LLVMBuildCondBr(b,
     801             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
     802             :                                                   l_sizet_const(1), ""),
     803             :                                     b_boolistrue,
     804             :                                     b_boolcont);
     805             : 
     806             :                     /*
     807             :                      * Build block handling True. Value is true, so short
     808             :                      * circuit.
     809             :                      */
     810          60 :                     LLVMPositionBuilderAtEnd(b, b_boolistrue);
     811             :                     /* result is already set to TRUE, need not change it */
     812             :                     /* and jump to the end of the OR expression */
     813          60 :                     LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]);
     814             : 
     815             :                     /* build block that continues if bool is FALSE */
     816          60 :                     LLVMPositionBuilderAtEnd(b, b_boolcont);
     817             : 
     818          60 :                     v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, "");
     819             : 
     820             :                     /* set value to NULL if any previous values were NULL */
     821          60 :                     LLVMBuildCondBr(b,
     822             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
     823             :                                                   l_sbool_const(0), ""),
     824          60 :                                     opblocks[opno + 1], b_boolisanynull);
     825             : 
     826          60 :                     LLVMPositionBuilderAtEnd(b, b_boolisanynull);
     827             :                     /* set resnull to true */
     828          60 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
     829             :                     /* reset resvalue */
     830          60 :                     LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
     831             : 
     832          60 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     833          60 :                     break;
     834             :                 }
     835             : 
     836           2 :             case EEOP_BOOL_NOT_STEP:
     837             :                 {
     838             :                     LLVMValueRef v_boolvalue;
     839             :                     LLVMValueRef v_boolnull;
     840             :                     LLVMValueRef v_negbool;
     841             : 
     842           2 :                     v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
     843           2 :                     v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
     844             : 
     845           2 :                     v_negbool = LLVMBuildZExt(b,
     846             :                                               LLVMBuildICmp(b, LLVMIntEQ,
     847             :                                                             v_boolvalue,
     848             :                                                             l_sizet_const(0),
     849             :                                                             ""),
     850             :                                               TypeSizeT, "");
     851             :                     /* set resnull to boolnull */
     852           2 :                     LLVMBuildStore(b, v_boolnull, v_resnullp);
     853             :                     /* set revalue to !boolvalue */
     854           2 :                     LLVMBuildStore(b, v_negbool, v_resvaluep);
     855             : 
     856           2 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     857           2 :                     break;
     858             :                 }
     859             : 
     860        1632 :             case EEOP_QUAL:
     861             :                 {
     862             :                     LLVMValueRef v_resnull;
     863             :                     LLVMValueRef v_resvalue;
     864             :                     LLVMValueRef v_nullorfalse;
     865             :                     LLVMBasicBlockRef b_qualfail;
     866             : 
     867        1632 :                     b_qualfail = l_bb_before_v(opblocks[opno + 1],
     868             :                                                "op.%d.qualfail", opno);
     869             : 
     870        1632 :                     v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
     871        1632 :                     v_resnull = LLVMBuildLoad(b, v_resnullp, "");
     872             : 
     873             :                     v_nullorfalse =
     874        1632 :                         LLVMBuildOr(b,
     875             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     876             :                                                   l_sbool_const(1), ""),
     877             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
     878             :                                                   l_sizet_const(0), ""),
     879             :                                     "");
     880             : 
     881        1632 :                     LLVMBuildCondBr(b,
     882             :                                     v_nullorfalse,
     883             :                                     b_qualfail,
     884        1632 :                                     opblocks[opno + 1]);
     885             : 
     886             :                     /* build block handling NULL or false */
     887        1632 :                     LLVMPositionBuilderAtEnd(b, b_qualfail);
     888             :                     /* set resnull to false */
     889        1632 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
     890             :                     /* set resvalue to false */
     891        1632 :                     LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
     892             :                     /* and jump out */
     893        1632 :                     LLVMBuildBr(b, opblocks[op->d.qualexpr.jumpdone]);
     894        1632 :                     break;
     895             :                 }
     896             : 
     897           0 :             case EEOP_JUMP:
     898             :                 {
     899           0 :                     LLVMBuildBr(b, opblocks[op->d.jump.jumpdone]);
     900           0 :                     break;
     901             :                 }
     902             : 
     903          12 :             case EEOP_JUMP_IF_NULL:
     904             :                 {
     905             :                     LLVMValueRef v_resnull;
     906             : 
     907             :                     /* Transfer control if current result is null */
     908             : 
     909          12 :                     v_resnull = LLVMBuildLoad(b, v_resnullp, "");
     910             : 
     911          12 :                     LLVMBuildCondBr(b,
     912             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     913             :                                                   l_sbool_const(1), ""),
     914          12 :                                     opblocks[op->d.jump.jumpdone],
     915          12 :                                     opblocks[opno + 1]);
     916          12 :                     break;
     917             :                 }
     918             : 
     919           0 :             case EEOP_JUMP_IF_NOT_NULL:
     920             :                 {
     921             :                     LLVMValueRef v_resnull;
     922             : 
     923             :                     /* Transfer control if current result is non-null */
     924             : 
     925           0 :                     v_resnull = LLVMBuildLoad(b, v_resnullp, "");
     926             : 
     927           0 :                     LLVMBuildCondBr(b,
     928             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     929             :                                                   l_sbool_const(0), ""),
     930           0 :                                     opblocks[op->d.jump.jumpdone],
     931           0 :                                     opblocks[opno + 1]);
     932           0 :                     break;
     933             :                 }
     934             : 
     935             : 
     936           0 :             case EEOP_JUMP_IF_NOT_TRUE:
     937             :                 {
     938             :                     LLVMValueRef v_resnull;
     939             :                     LLVMValueRef v_resvalue;
     940             :                     LLVMValueRef v_nullorfalse;
     941             : 
     942             :                     /* Transfer control if current result is null or false */
     943             : 
     944           0 :                     v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
     945           0 :                     v_resnull = LLVMBuildLoad(b, v_resnullp, "");
     946             : 
     947             :                     v_nullorfalse =
     948           0 :                         LLVMBuildOr(b,
     949             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     950             :                                                   l_sbool_const(1), ""),
     951             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
     952             :                                                   l_sizet_const(0), ""),
     953             :                                     "");
     954             : 
     955           0 :                     LLVMBuildCondBr(b,
     956             :                                     v_nullorfalse,
     957           0 :                                     opblocks[op->d.jump.jumpdone],
     958           0 :                                     opblocks[opno + 1]);
     959           0 :                     break;
     960             :                 }
     961             : 
     962          48 :             case EEOP_NULLTEST_ISNULL:
     963             :                 {
     964          48 :                     LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
     965             :                     LLVMValueRef v_resvalue;
     966             : 
     967             :                     v_resvalue =
     968          48 :                         LLVMBuildSelect(b,
     969             :                                         LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     970             :                                                       l_sbool_const(1), ""),
     971             :                                         l_sizet_const(1),
     972             :                                         l_sizet_const(0),
     973             :                                         "");
     974          48 :                     LLVMBuildStore(b, v_resvalue, v_resvaluep);
     975          48 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
     976             : 
     977          48 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     978          48 :                     break;
     979             :                 }
     980             : 
     981          12 :             case EEOP_NULLTEST_ISNOTNULL:
     982             :                 {
     983          12 :                     LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
     984             :                     LLVMValueRef v_resvalue;
     985             : 
     986             :                     v_resvalue =
     987          12 :                         LLVMBuildSelect(b,
     988             :                                         LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     989             :                                                       l_sbool_const(1), ""),
     990             :                                         l_sizet_const(0),
     991             :                                         l_sizet_const(1),
     992             :                                         "");
     993          12 :                     LLVMBuildStore(b, v_resvalue, v_resvaluep);
     994          12 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
     995             : 
     996          12 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     997          12 :                     break;
     998             :                 }
     999             : 
    1000           0 :             case EEOP_NULLTEST_ROWISNULL:
    1001           0 :                 build_EvalXFunc(b, mod, "ExecEvalRowNull",
    1002             :                                 v_state, op, v_econtext);
    1003           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1004           0 :                 break;
    1005             : 
    1006           0 :             case EEOP_NULLTEST_ROWISNOTNULL:
    1007           0 :                 build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
    1008             :                                 v_state, op, v_econtext);
    1009           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1010           0 :                 break;
    1011             : 
    1012           0 :             case EEOP_BOOLTEST_IS_TRUE:
    1013             :             case EEOP_BOOLTEST_IS_NOT_FALSE:
    1014             :             case EEOP_BOOLTEST_IS_FALSE:
    1015             :             case EEOP_BOOLTEST_IS_NOT_TRUE:
    1016             :                 {
    1017             :                     LLVMBasicBlockRef b_isnull,
    1018             :                                 b_notnull;
    1019           0 :                     LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
    1020             : 
    1021           0 :                     b_isnull = l_bb_before_v(opblocks[opno + 1],
    1022             :                                              "op.%d.isnull", opno);
    1023           0 :                     b_notnull = l_bb_before_v(opblocks[opno + 1],
    1024             :                                               "op.%d.isnotnull", opno);
    1025             : 
    1026             :                     /* check if value is NULL */
    1027           0 :                     LLVMBuildCondBr(b,
    1028             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1029             :                                                   l_sbool_const(1), ""),
    1030             :                                     b_isnull, b_notnull);
    1031             : 
    1032             :                     /* if value is NULL, return false */
    1033           0 :                     LLVMPositionBuilderAtEnd(b, b_isnull);
    1034             : 
    1035             :                     /* result is not null */
    1036           0 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1037             : 
    1038           0 :                     if (opcode == EEOP_BOOLTEST_IS_TRUE ||
    1039             :                         opcode == EEOP_BOOLTEST_IS_FALSE)
    1040             :                     {
    1041           0 :                         LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
    1042             :                     }
    1043             :                     else
    1044             :                     {
    1045           0 :                         LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
    1046             :                     }
    1047             : 
    1048           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1049             : 
    1050           0 :                     LLVMPositionBuilderAtEnd(b, b_notnull);
    1051             : 
    1052           0 :                     if (opcode == EEOP_BOOLTEST_IS_TRUE ||
    1053             :                         opcode == EEOP_BOOLTEST_IS_NOT_FALSE)
    1054             :                     {
    1055             :                         /*
    1056             :                          * if value is not null NULL, return value (already
    1057             :                          * set)
    1058             :                          */
    1059             :                     }
    1060             :                     else
    1061             :                     {
    1062             :                         LLVMValueRef v_value =
    1063           0 :                         LLVMBuildLoad(b, v_resvaluep, "");
    1064             : 
    1065           0 :                         v_value = LLVMBuildZExt(b,
    1066             :                                                 LLVMBuildICmp(b, LLVMIntEQ,
    1067             :                                                               v_value,
    1068             :                                                               l_sizet_const(0),
    1069             :                                                               ""),
    1070             :                                                 TypeSizeT, "");
    1071           0 :                         LLVMBuildStore(b, v_value, v_resvaluep);
    1072             :                     }
    1073           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1074           0 :                     break;
    1075             :                 }
    1076             : 
    1077         476 :             case EEOP_PARAM_EXEC:
    1078         476 :                 build_EvalXFunc(b, mod, "ExecEvalParamExec",
    1079             :                                 v_state, op, v_econtext);
    1080         476 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1081         476 :                 break;
    1082             : 
    1083           0 :             case EEOP_PARAM_EXTERN:
    1084           0 :                 build_EvalXFunc(b, mod, "ExecEvalParamExtern",
    1085             :                                 v_state, op, v_econtext);
    1086           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1087           0 :                 break;
    1088             : 
    1089           0 :             case EEOP_PARAM_CALLBACK:
    1090             :                 {
    1091             :                     LLVMTypeRef param_types[3];
    1092             :                     LLVMValueRef v_params[3];
    1093             :                     LLVMTypeRef v_functype;
    1094             :                     LLVMValueRef v_func;
    1095             : 
    1096           0 :                     param_types[0] = l_ptr(StructExprState);
    1097           0 :                     param_types[1] = l_ptr(TypeSizeT);
    1098           0 :                     param_types[2] = l_ptr(StructExprContext);
    1099             : 
    1100           0 :                     v_functype = LLVMFunctionType(LLVMVoidType(),
    1101             :                                                   param_types,
    1102             :                                                   lengthof(param_types),
    1103             :                                                   false);
    1104           0 :                     v_func = l_ptr_const(op->d.cparam.paramfunc,
    1105             :                                          l_ptr(v_functype));
    1106             : 
    1107           0 :                     v_params[0] = v_state;
    1108           0 :                     v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT));
    1109           0 :                     v_params[2] = v_econtext;
    1110           0 :                     LLVMBuildCall(b,
    1111             :                                   v_func,
    1112             :                                   v_params, lengthof(v_params), "");
    1113             : 
    1114           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1115           0 :                     break;
    1116             :                 }
    1117             : 
    1118           0 :             case EEOP_SBSREF_OLD:
    1119           0 :                 build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld",
    1120             :                                 v_state, op);
    1121           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1122           0 :                 break;
    1123             : 
    1124           0 :             case EEOP_SBSREF_ASSIGN:
    1125           0 :                 build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign",
    1126             :                                 v_state, op);
    1127           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1128           0 :                 break;
    1129             : 
    1130          12 :             case EEOP_SBSREF_FETCH:
    1131          12 :                 build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch",
    1132             :                                 v_state, op);
    1133          12 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1134          12 :                 break;
    1135             : 
    1136           0 :             case EEOP_CASE_TESTVAL:
    1137             :                 {
    1138             :                     LLVMBasicBlockRef b_avail,
    1139             :                                 b_notavail;
    1140             :                     LLVMValueRef v_casevaluep,
    1141             :                                 v_casevalue;
    1142             :                     LLVMValueRef v_casenullp,
    1143             :                                 v_casenull;
    1144             :                     LLVMValueRef v_casevaluenull;
    1145             : 
    1146           0 :                     b_avail = l_bb_before_v(opblocks[opno + 1],
    1147             :                                             "op.%d.avail", opno);
    1148           0 :                     b_notavail = l_bb_before_v(opblocks[opno + 1],
    1149             :                                                "op.%d.notavail", opno);
    1150             : 
    1151           0 :                     v_casevaluep = l_ptr_const(op->d.casetest.value,
    1152             :                                                l_ptr(TypeSizeT));
    1153           0 :                     v_casenullp = l_ptr_const(op->d.casetest.isnull,
    1154             :                                               l_ptr(TypeStorageBool));
    1155             : 
    1156             :                     v_casevaluenull =
    1157           0 :                         LLVMBuildICmp(b, LLVMIntEQ,
    1158             :                                       LLVMBuildPtrToInt(b, v_casevaluep,
    1159             :                                                         TypeSizeT, ""),
    1160             :                                       l_sizet_const(0), "");
    1161           0 :                     LLVMBuildCondBr(b, v_casevaluenull, b_notavail, b_avail);
    1162             : 
    1163             :                     /* if casetest != NULL */
    1164           0 :                     LLVMPositionBuilderAtEnd(b, b_avail);
    1165           0 :                     v_casevalue = LLVMBuildLoad(b, v_casevaluep, "");
    1166           0 :                     v_casenull = LLVMBuildLoad(b, v_casenullp, "");
    1167           0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1168           0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1169           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1170             : 
    1171             :                     /* if casetest == NULL */
    1172           0 :                     LLVMPositionBuilderAtEnd(b, b_notavail);
    1173             :                     v_casevalue =
    1174           0 :                         l_load_struct_gep(b, v_econtext,
    1175             :                                           FIELDNO_EXPRCONTEXT_CASEDATUM, "");
    1176             :                     v_casenull =
    1177           0 :                         l_load_struct_gep(b, v_econtext,
    1178             :                                           FIELDNO_EXPRCONTEXT_CASENULL, "");
    1179           0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1180           0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1181             : 
    1182           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1183           0 :                     break;
    1184             :                 }
    1185             : 
    1186           0 :             case EEOP_MAKE_READONLY:
    1187             :                 {
    1188             :                     LLVMBasicBlockRef b_notnull;
    1189             :                     LLVMValueRef v_params[1];
    1190             :                     LLVMValueRef v_ret;
    1191             :                     LLVMValueRef v_nullp;
    1192             :                     LLVMValueRef v_valuep;
    1193             :                     LLVMValueRef v_null;
    1194             :                     LLVMValueRef v_value;
    1195             : 
    1196           0 :                     b_notnull = l_bb_before_v(opblocks[opno + 1],
    1197             :                                               "op.%d.readonly.notnull", opno);
    1198             : 
    1199           0 :                     v_nullp = l_ptr_const(op->d.make_readonly.isnull,
    1200             :                                           l_ptr(TypeStorageBool));
    1201             : 
    1202           0 :                     v_null = LLVMBuildLoad(b, v_nullp, "");
    1203             : 
    1204             :                     /* store null isnull value in result */
    1205           0 :                     LLVMBuildStore(b, v_null, v_resnullp);
    1206             : 
    1207             :                     /* check if value is NULL */
    1208           0 :                     LLVMBuildCondBr(b,
    1209             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_null,
    1210             :                                                   l_sbool_const(1), ""),
    1211           0 :                                     opblocks[opno + 1], b_notnull);
    1212             : 
    1213             :                     /* if value is not null, convert to RO datum */
    1214           0 :                     LLVMPositionBuilderAtEnd(b, b_notnull);
    1215             : 
    1216           0 :                     v_valuep = l_ptr_const(op->d.make_readonly.value,
    1217             :                                            l_ptr(TypeSizeT));
    1218             : 
    1219           0 :                     v_value = LLVMBuildLoad(b, v_valuep, "");
    1220             : 
    1221           0 :                     v_params[0] = v_value;
    1222             :                     v_ret =
    1223           0 :                         LLVMBuildCall(b,
    1224             :                                       llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
    1225             :                                       v_params, lengthof(v_params), "");
    1226           0 :                     LLVMBuildStore(b, v_ret, v_resvaluep);
    1227             : 
    1228           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1229           0 :                     break;
    1230             :                 }
    1231             : 
    1232          56 :             case EEOP_IOCOERCE:
    1233             :                 {
    1234             :                     FunctionCallInfo fcinfo_out,
    1235             :                                 fcinfo_in;
    1236             :                     LLVMValueRef v_fn_out,
    1237             :                                 v_fn_in;
    1238             :                     LLVMValueRef v_fcinfo_out,
    1239             :                                 v_fcinfo_in;
    1240             :                     LLVMValueRef v_fcinfo_in_isnullp;
    1241             :                     LLVMValueRef v_retval;
    1242             :                     LLVMValueRef v_resvalue;
    1243             :                     LLVMValueRef v_resnull;
    1244             : 
    1245             :                     LLVMValueRef v_output_skip;
    1246             :                     LLVMValueRef v_output;
    1247             : 
    1248             :                     LLVMBasicBlockRef b_skipoutput;
    1249             :                     LLVMBasicBlockRef b_calloutput;
    1250             :                     LLVMBasicBlockRef b_input;
    1251             :                     LLVMBasicBlockRef b_inputcall;
    1252             : 
    1253          56 :                     fcinfo_out = op->d.iocoerce.fcinfo_data_out;
    1254          56 :                     fcinfo_in = op->d.iocoerce.fcinfo_data_in;
    1255             : 
    1256          56 :                     b_skipoutput = l_bb_before_v(opblocks[opno + 1],
    1257             :                                                  "op.%d.skipoutputnull", opno);
    1258          56 :                     b_calloutput = l_bb_before_v(opblocks[opno + 1],
    1259             :                                                  "op.%d.calloutput", opno);
    1260          56 :                     b_input = l_bb_before_v(opblocks[opno + 1],
    1261             :                                             "op.%d.input", opno);
    1262          56 :                     b_inputcall = l_bb_before_v(opblocks[opno + 1],
    1263             :                                                 "op.%d.inputcall", opno);
    1264             : 
    1265          56 :                     v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out);
    1266          56 :                     v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in);
    1267          56 :                     v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
    1268          56 :                     v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
    1269             : 
    1270             :                     v_fcinfo_in_isnullp =
    1271          56 :                         LLVMBuildStructGEP(b, v_fcinfo_in,
    1272             :                                            FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
    1273             :                                            "v_fcinfo_in_isnull");
    1274             : 
    1275             :                     /* output functions are not called on nulls */
    1276          56 :                     v_resnull = LLVMBuildLoad(b, v_resnullp, "");
    1277          56 :                     LLVMBuildCondBr(b,
    1278             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1279             :                                                   l_sbool_const(1), ""),
    1280             :                                     b_skipoutput,
    1281             :                                     b_calloutput);
    1282             : 
    1283          56 :                     LLVMPositionBuilderAtEnd(b, b_skipoutput);
    1284          56 :                     v_output_skip = l_sizet_const(0);
    1285          56 :                     LLVMBuildBr(b, b_input);
    1286             : 
    1287          56 :                     LLVMPositionBuilderAtEnd(b, b_calloutput);
    1288          56 :                     v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
    1289             : 
    1290             :                     /* set arg[0] */
    1291          56 :                     LLVMBuildStore(b,
    1292             :                                    v_resvalue,
    1293             :                                    l_funcvaluep(b, v_fcinfo_out, 0));
    1294          56 :                     LLVMBuildStore(b,
    1295             :                                    l_sbool_const(0),
    1296             :                                    l_funcnullp(b, v_fcinfo_out, 0));
    1297             :                     /* and call output function (can never return NULL) */
    1298          56 :                     v_output = LLVMBuildCall(b, v_fn_out, &v_fcinfo_out,
    1299             :                                              1, "funccall_coerce_out");
    1300          56 :                     LLVMBuildBr(b, b_input);
    1301             : 
    1302             :                     /* build block handling input function call */
    1303          56 :                     LLVMPositionBuilderAtEnd(b, b_input);
    1304             : 
    1305             :                     /* phi between resnull and output function call branches */
    1306             :                     {
    1307             :                         LLVMValueRef incoming_values[2];
    1308             :                         LLVMBasicBlockRef incoming_blocks[2];
    1309             : 
    1310          56 :                         incoming_values[0] = v_output_skip;
    1311          56 :                         incoming_blocks[0] = b_skipoutput;
    1312             : 
    1313          56 :                         incoming_values[1] = v_output;
    1314          56 :                         incoming_blocks[1] = b_calloutput;
    1315             : 
    1316          56 :                         v_output = LLVMBuildPhi(b, TypeSizeT, "output");
    1317          56 :                         LLVMAddIncoming(v_output,
    1318             :                                         incoming_values, incoming_blocks,
    1319             :                                         lengthof(incoming_blocks));
    1320             :                     }
    1321             : 
    1322             :                     /*
    1323             :                      * If input function is strict, skip if input string is
    1324             :                      * NULL.
    1325             :                      */
    1326          56 :                     if (op->d.iocoerce.finfo_in->fn_strict)
    1327             :                     {
    1328          56 :                         LLVMBuildCondBr(b,
    1329             :                                         LLVMBuildICmp(b, LLVMIntEQ, v_output,
    1330             :                                                       l_sizet_const(0), ""),
    1331          56 :                                         opblocks[opno + 1],
    1332             :                                         b_inputcall);
    1333             :                     }
    1334             :                     else
    1335             :                     {
    1336           0 :                         LLVMBuildBr(b, b_inputcall);
    1337             :                     }
    1338             : 
    1339          56 :                     LLVMPositionBuilderAtEnd(b, b_inputcall);
    1340             :                     /* set arguments */
    1341             :                     /* arg0: output */
    1342          56 :                     LLVMBuildStore(b, v_output,
    1343             :                                    l_funcvaluep(b, v_fcinfo_in, 0));
    1344          56 :                     LLVMBuildStore(b, v_resnull,
    1345             :                                    l_funcnullp(b, v_fcinfo_in, 0));
    1346             : 
    1347             :                     /* arg1: ioparam: preset in execExpr.c */
    1348             :                     /* arg2: typmod: preset in execExpr.c  */
    1349             : 
    1350             :                     /* reset fcinfo_in->isnull */
    1351          56 :                     LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
    1352             :                     /* and call function */
    1353          56 :                     v_retval = LLVMBuildCall(b, v_fn_in, &v_fcinfo_in, 1,
    1354             :                                              "funccall_iocoerce_in");
    1355             : 
    1356          56 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    1357             : 
    1358          56 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1359          56 :                     break;
    1360             :                 }
    1361             : 
    1362         318 :             case EEOP_DISTINCT:
    1363             :             case EEOP_NOT_DISTINCT:
    1364             :                 {
    1365         318 :                     FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
    1366             : 
    1367             :                     LLVMValueRef v_fcinfo;
    1368             :                     LLVMValueRef v_fcinfo_isnull;
    1369             : 
    1370             :                     LLVMValueRef v_argnull0,
    1371             :                                 v_argisnull0;
    1372             :                     LLVMValueRef v_argnull1,
    1373             :                                 v_argisnull1;
    1374             : 
    1375             :                     LLVMValueRef v_anyargisnull;
    1376             :                     LLVMValueRef v_bothargisnull;
    1377             : 
    1378             :                     LLVMValueRef v_result;
    1379             : 
    1380             :                     LLVMBasicBlockRef b_noargnull;
    1381             :                     LLVMBasicBlockRef b_checkbothargnull;
    1382             :                     LLVMBasicBlockRef b_bothargnull;
    1383             :                     LLVMBasicBlockRef b_anyargnull;
    1384             : 
    1385         318 :                     b_noargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.noargnull", opno);
    1386         318 :                     b_checkbothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.checkbothargnull", opno);
    1387         318 :                     b_bothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.bothargnull", opno);
    1388         318 :                     b_anyargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.anyargnull", opno);
    1389             : 
    1390         318 :                     v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
    1391             : 
    1392             :                     /* load args[0|1].isnull for both arguments */
    1393         318 :                     v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1394         318 :                     v_argisnull0 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
    1395             :                                                  l_sbool_const(1), "");
    1396         318 :                     v_argnull1 = l_funcnull(b, v_fcinfo, 1);
    1397         318 :                     v_argisnull1 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
    1398             :                                                  l_sbool_const(1), "");
    1399             : 
    1400         318 :                     v_anyargisnull = LLVMBuildOr(b, v_argisnull0, v_argisnull1, "");
    1401         318 :                     v_bothargisnull = LLVMBuildAnd(b, v_argisnull0, v_argisnull1, "");
    1402             : 
    1403             :                     /*
    1404             :                      * Check function arguments for NULLness: If either is
    1405             :                      * NULL, we check if both args are NULL. Otherwise call
    1406             :                      * comparator.
    1407             :                      */
    1408         318 :                     LLVMBuildCondBr(b, v_anyargisnull, b_checkbothargnull,
    1409             :                                     b_noargnull);
    1410             : 
    1411             :                     /*
    1412             :                      * build block checking if any arg is null
    1413             :                      */
    1414         318 :                     LLVMPositionBuilderAtEnd(b, b_checkbothargnull);
    1415         318 :                     LLVMBuildCondBr(b, v_bothargisnull, b_bothargnull,
    1416             :                                     b_anyargnull);
    1417             : 
    1418             : 
    1419             :                     /* Both NULL? Then is not distinct... */
    1420         318 :                     LLVMPositionBuilderAtEnd(b, b_bothargnull);
    1421         318 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1422         318 :                     if (opcode == EEOP_NOT_DISTINCT)
    1423         294 :                         LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
    1424             :                     else
    1425          24 :                         LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
    1426             : 
    1427         318 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1428             : 
    1429             :                     /* Only one is NULL? Then is distinct... */
    1430         318 :                     LLVMPositionBuilderAtEnd(b, b_anyargnull);
    1431         318 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1432         318 :                     if (opcode == EEOP_NOT_DISTINCT)
    1433         294 :                         LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
    1434             :                     else
    1435          24 :                         LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
    1436         318 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1437             : 
    1438             :                     /* neither argument is null: compare */
    1439         318 :                     LLVMPositionBuilderAtEnd(b, b_noargnull);
    1440             : 
    1441         318 :                     v_result = BuildV1Call(context, b, mod, fcinfo,
    1442             :                                            &v_fcinfo_isnull);
    1443             : 
    1444         318 :                     if (opcode == EEOP_DISTINCT)
    1445             :                     {
    1446             :                         /* Must invert result of "=" */
    1447             :                         v_result =
    1448          24 :                             LLVMBuildZExt(b,
    1449             :                                           LLVMBuildICmp(b, LLVMIntEQ,
    1450             :                                                         v_result,
    1451             :                                                         l_sizet_const(0), ""),
    1452             :                                           TypeSizeT, "");
    1453             :                     }
    1454             : 
    1455         318 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
    1456         318 :                     LLVMBuildStore(b, v_result, v_resvaluep);
    1457             : 
    1458         318 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1459         318 :                     break;
    1460             :                 }
    1461             : 
    1462           0 :             case EEOP_NULLIF:
    1463             :                 {
    1464           0 :                     FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
    1465             : 
    1466             :                     LLVMValueRef v_fcinfo;
    1467             :                     LLVMValueRef v_fcinfo_isnull;
    1468             :                     LLVMValueRef v_argnull0;
    1469             :                     LLVMValueRef v_argnull1;
    1470             :                     LLVMValueRef v_anyargisnull;
    1471             :                     LLVMValueRef v_arg0;
    1472             :                     LLVMBasicBlockRef b_hasnull;
    1473             :                     LLVMBasicBlockRef b_nonull;
    1474             :                     LLVMBasicBlockRef b_argsequal;
    1475             :                     LLVMValueRef v_retval;
    1476             :                     LLVMValueRef v_argsequal;
    1477             : 
    1478           0 :                     b_hasnull = l_bb_before_v(opblocks[opno + 1],
    1479             :                                               "b.%d.null-args", opno);
    1480           0 :                     b_nonull = l_bb_before_v(opblocks[opno + 1],
    1481             :                                              "b.%d.no-null-args", opno);
    1482           0 :                     b_argsequal = l_bb_before_v(opblocks[opno + 1],
    1483             :                                                 "b.%d.argsequal", opno);
    1484             : 
    1485           0 :                     v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
    1486             : 
    1487             :                     /* if either argument is NULL they can't be equal */
    1488           0 :                     v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1489           0 :                     v_argnull1 = l_funcnull(b, v_fcinfo, 1);
    1490             : 
    1491             :                     v_anyargisnull =
    1492           0 :                         LLVMBuildOr(b,
    1493             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
    1494             :                                                   l_sbool_const(1), ""),
    1495             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
    1496             :                                                   l_sbool_const(1), ""),
    1497             :                                     "");
    1498             : 
    1499           0 :                     LLVMBuildCondBr(b, v_anyargisnull, b_hasnull, b_nonull);
    1500             : 
    1501             :                     /* one (or both) of the arguments are null, return arg[0] */
    1502           0 :                     LLVMPositionBuilderAtEnd(b, b_hasnull);
    1503           0 :                     v_arg0 = l_funcvalue(b, v_fcinfo, 0);
    1504           0 :                     LLVMBuildStore(b, v_argnull0, v_resnullp);
    1505           0 :                     LLVMBuildStore(b, v_arg0, v_resvaluep);
    1506           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1507             : 
    1508             :                     /* build block to invoke function and check result */
    1509           0 :                     LLVMPositionBuilderAtEnd(b, b_nonull);
    1510             : 
    1511           0 :                     v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull);
    1512             : 
    1513             :                     /*
    1514             :                      * If result not null, and arguments are equal return null
    1515             :                      * (same result as if there'd been NULLs, hence reuse
    1516             :                      * b_hasnull).
    1517             :                      */
    1518           0 :                     v_argsequal = LLVMBuildAnd(b,
    1519             :                                                LLVMBuildICmp(b, LLVMIntEQ,
    1520             :                                                              v_fcinfo_isnull,
    1521             :                                                              l_sbool_const(0),
    1522             :                                                              ""),
    1523             :                                                LLVMBuildICmp(b, LLVMIntEQ,
    1524             :                                                              v_retval,
    1525             :                                                              l_sizet_const(1),
    1526             :                                                              ""),
    1527             :                                                "");
    1528           0 :                     LLVMBuildCondBr(b, v_argsequal, b_argsequal, b_hasnull);
    1529             : 
    1530             :                     /* build block setting result to NULL, if args are equal */
    1531           0 :                     LLVMPositionBuilderAtEnd(b, b_argsequal);
    1532           0 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
    1533           0 :                     LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
    1534           0 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    1535             : 
    1536           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1537           0 :                     break;
    1538             :                 }
    1539             : 
    1540           0 :             case EEOP_SQLVALUEFUNCTION:
    1541           0 :                 build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
    1542             :                                 v_state, op);
    1543           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1544           0 :                 break;
    1545             : 
    1546           2 :             case EEOP_CURRENTOFEXPR:
    1547           2 :                 build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
    1548             :                                 v_state, op);
    1549           2 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1550           2 :                 break;
    1551             : 
    1552           0 :             case EEOP_NEXTVALUEEXPR:
    1553           0 :                 build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
    1554             :                                 v_state, op);
    1555           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1556           0 :                 break;
    1557             : 
    1558           0 :             case EEOP_ARRAYEXPR:
    1559           0 :                 build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
    1560             :                                 v_state, op);
    1561           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1562           0 :                 break;
    1563             : 
    1564           0 :             case EEOP_ARRAYCOERCE:
    1565           0 :                 build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
    1566             :                                 v_state, op, v_econtext);
    1567           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1568           0 :                 break;
    1569             : 
    1570           2 :             case EEOP_ROW:
    1571           2 :                 build_EvalXFunc(b, mod, "ExecEvalRow",
    1572             :                                 v_state, op);
    1573           2 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1574           2 :                 break;
    1575             : 
    1576           0 :             case EEOP_ROWCOMPARE_STEP:
    1577             :                 {
    1578           0 :                     FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data;
    1579             :                     LLVMValueRef v_fcinfo_isnull;
    1580             :                     LLVMBasicBlockRef b_null;
    1581             :                     LLVMBasicBlockRef b_compare;
    1582             :                     LLVMBasicBlockRef b_compare_result;
    1583             : 
    1584             :                     LLVMValueRef v_retval;
    1585             : 
    1586           0 :                     b_null = l_bb_before_v(opblocks[opno + 1],
    1587             :                                            "op.%d.row-null", opno);
    1588           0 :                     b_compare = l_bb_before_v(opblocks[opno + 1],
    1589             :                                               "op.%d.row-compare", opno);
    1590             :                     b_compare_result =
    1591           0 :                         l_bb_before_v(opblocks[opno + 1],
    1592             :                                       "op.%d.row-compare-result",
    1593             :                                       opno);
    1594             : 
    1595             :                     /*
    1596             :                      * If function is strict, and either arg is null, we're
    1597             :                      * done.
    1598             :                      */
    1599           0 :                     if (op->d.rowcompare_step.finfo->fn_strict)
    1600             :                     {
    1601             :                         LLVMValueRef v_fcinfo;
    1602             :                         LLVMValueRef v_argnull0;
    1603             :                         LLVMValueRef v_argnull1;
    1604             :                         LLVMValueRef v_anyargisnull;
    1605             : 
    1606           0 :                         v_fcinfo = l_ptr_const(fcinfo,
    1607             :                                                l_ptr(StructFunctionCallInfoData));
    1608             : 
    1609           0 :                         v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1610           0 :                         v_argnull1 = l_funcnull(b, v_fcinfo, 1);
    1611             : 
    1612             :                         v_anyargisnull =
    1613           0 :                             LLVMBuildOr(b,
    1614             :                                         LLVMBuildICmp(b,
    1615             :                                                       LLVMIntEQ,
    1616             :                                                       v_argnull0,
    1617             :                                                       l_sbool_const(1),
    1618             :                                                       ""),
    1619             :                                         LLVMBuildICmp(b, LLVMIntEQ,
    1620             :                                                       v_argnull1,
    1621             :                                                       l_sbool_const(1), ""),
    1622             :                                         "");
    1623             : 
    1624           0 :                         LLVMBuildCondBr(b, v_anyargisnull, b_null, b_compare);
    1625             :                     }
    1626             :                     else
    1627             :                     {
    1628           0 :                         LLVMBuildBr(b, b_compare);
    1629             :                     }
    1630             : 
    1631             :                     /* build block invoking comparison function */
    1632           0 :                     LLVMPositionBuilderAtEnd(b, b_compare);
    1633             : 
    1634             :                     /* call function */
    1635           0 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    1636             :                                            &v_fcinfo_isnull);
    1637           0 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    1638             : 
    1639             :                     /* if result of function is NULL, force NULL result */
    1640           0 :                     LLVMBuildCondBr(b,
    1641             :                                     LLVMBuildICmp(b,
    1642             :                                                   LLVMIntEQ,
    1643             :                                                   v_fcinfo_isnull,
    1644             :                                                   l_sbool_const(0),
    1645             :                                                   ""),
    1646             :                                     b_compare_result,
    1647             :                                     b_null);
    1648             : 
    1649             :                     /* build block analyzing the !NULL comparator result */
    1650           0 :                     LLVMPositionBuilderAtEnd(b, b_compare_result);
    1651             : 
    1652             :                     /* if results equal, compare next, otherwise done */
    1653           0 :                     LLVMBuildCondBr(b,
    1654             :                                     LLVMBuildICmp(b,
    1655             :                                                   LLVMIntEQ,
    1656             :                                                   v_retval,
    1657             :                                                   l_sizet_const(0), ""),
    1658           0 :                                     opblocks[opno + 1],
    1659           0 :                                     opblocks[op->d.rowcompare_step.jumpdone]);
    1660             : 
    1661             :                     /*
    1662             :                      * Build block handling NULL input or NULL comparator
    1663             :                      * result.
    1664             :                      */
    1665           0 :                     LLVMPositionBuilderAtEnd(b, b_null);
    1666           0 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
    1667           0 :                     LLVMBuildBr(b, opblocks[op->d.rowcompare_step.jumpnull]);
    1668             : 
    1669           0 :                     break;
    1670             :                 }
    1671             : 
    1672           0 :             case EEOP_ROWCOMPARE_FINAL:
    1673             :                 {
    1674           0 :                     RowCompareType rctype = op->d.rowcompare_final.rctype;
    1675             : 
    1676             :                     LLVMValueRef v_cmpresult;
    1677             :                     LLVMValueRef v_result;
    1678             :                     LLVMIntPredicate predicate;
    1679             : 
    1680             :                     /*
    1681             :                      * Btree comparators return 32 bit results, need to be
    1682             :                      * careful about sign (used as a 64 bit value it's
    1683             :                      * otherwise wrong).
    1684             :                      */
    1685             :                     v_cmpresult =
    1686           0 :                         LLVMBuildTrunc(b,
    1687             :                                        LLVMBuildLoad(b, v_resvaluep, ""),
    1688             :                                        LLVMInt32Type(), "");
    1689             : 
    1690             :                     switch (rctype)
    1691             :                     {
    1692           0 :                         case ROWCOMPARE_LT:
    1693           0 :                             predicate = LLVMIntSLT;
    1694           0 :                             break;
    1695           0 :                         case ROWCOMPARE_LE:
    1696           0 :                             predicate = LLVMIntSLE;
    1697           0 :                             break;
    1698           0 :                         case ROWCOMPARE_GT:
    1699           0 :                             predicate = LLVMIntSGT;
    1700           0 :                             break;
    1701           0 :                         case ROWCOMPARE_GE:
    1702           0 :                             predicate = LLVMIntSGE;
    1703           0 :                             break;
    1704           0 :                         default:
    1705             :                             /* EQ and NE cases aren't allowed here */
    1706             :                             Assert(false);
    1707           0 :                             predicate = 0;  /* prevent compiler warning */
    1708           0 :                             break;
    1709             :                     }
    1710             : 
    1711           0 :                     v_result = LLVMBuildICmp(b,
    1712             :                                              predicate,
    1713             :                                              v_cmpresult,
    1714             :                                              l_int32_const(0),
    1715             :                                              "");
    1716           0 :                     v_result = LLVMBuildZExt(b, v_result, TypeSizeT, "");
    1717             : 
    1718           0 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1719           0 :                     LLVMBuildStore(b, v_result, v_resvaluep);
    1720             : 
    1721           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1722           0 :                     break;
    1723             :                 }
    1724             : 
    1725           0 :             case EEOP_MINMAX:
    1726           0 :                 build_EvalXFunc(b, mod, "ExecEvalMinMax",
    1727             :                                 v_state, op);
    1728           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1729           0 :                 break;
    1730             : 
    1731          52 :             case EEOP_FIELDSELECT:
    1732          52 :                 build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
    1733             :                                 v_state, op, v_econtext);
    1734          52 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1735          52 :                 break;
    1736             : 
    1737           0 :             case EEOP_FIELDSTORE_DEFORM:
    1738           0 :                 build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
    1739             :                                 v_state, op, v_econtext);
    1740           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1741           0 :                 break;
    1742             : 
    1743           0 :             case EEOP_FIELDSTORE_FORM:
    1744           0 :                 build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
    1745             :                                 v_state, op, v_econtext);
    1746           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1747           0 :                 break;
    1748             : 
    1749          12 :             case EEOP_SBSREF_SUBSCRIPT:
    1750             :                 {
    1751          12 :                     int         jumpdone = op->d.sbsref_subscript.jumpdone;
    1752             :                     LLVMValueRef v_ret;
    1753             : 
    1754          12 :                     v_ret = build_EvalXFunc(b, mod, "ExecEvalSubscriptingRef",
    1755             :                                             v_state, op);
    1756          12 :                     v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
    1757             : 
    1758          12 :                     LLVMBuildCondBr(b,
    1759             :                                     LLVMBuildICmp(b, LLVMIntEQ, v_ret,
    1760             :                                                   l_sbool_const(1), ""),
    1761          12 :                                     opblocks[opno + 1],
    1762          12 :                                     opblocks[jumpdone]);
    1763          12 :                     break;
    1764             :                 }
    1765             : 
    1766           0 :             case EEOP_DOMAIN_TESTVAL:
    1767             :                 {
    1768             :                     LLVMBasicBlockRef b_avail,
    1769             :                                 b_notavail;
    1770             :                     LLVMValueRef v_casevaluep,
    1771             :                                 v_casevalue;
    1772             :                     LLVMValueRef v_casenullp,
    1773             :                                 v_casenull;
    1774             :                     LLVMValueRef v_casevaluenull;
    1775             : 
    1776           0 :                     b_avail = l_bb_before_v(opblocks[opno + 1],
    1777             :                                             "op.%d.avail", opno);
    1778           0 :                     b_notavail = l_bb_before_v(opblocks[opno + 1],
    1779             :                                                "op.%d.notavail", opno);
    1780             : 
    1781           0 :                     v_casevaluep = l_ptr_const(op->d.casetest.value,
    1782             :                                                l_ptr(TypeSizeT));
    1783           0 :                     v_casenullp = l_ptr_const(op->d.casetest.isnull,
    1784             :                                               l_ptr(TypeStorageBool));
    1785             : 
    1786             :                     v_casevaluenull =
    1787           0 :                         LLVMBuildICmp(b, LLVMIntEQ,
    1788             :                                       LLVMBuildPtrToInt(b, v_casevaluep,
    1789             :                                                         TypeSizeT, ""),
    1790             :                                       l_sizet_const(0), "");
    1791           0 :                     LLVMBuildCondBr(b,
    1792             :                                     v_casevaluenull,
    1793             :                                     b_notavail, b_avail);
    1794             : 
    1795             :                     /* if casetest != NULL */
    1796           0 :                     LLVMPositionBuilderAtEnd(b, b_avail);
    1797           0 :                     v_casevalue = LLVMBuildLoad(b, v_casevaluep, "");
    1798           0 :                     v_casenull = LLVMBuildLoad(b, v_casenullp, "");
    1799           0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1800           0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1801           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1802             : 
    1803             :                     /* if casetest == NULL */
    1804           0 :                     LLVMPositionBuilderAtEnd(b, b_notavail);
    1805             :                     v_casevalue =
    1806           0 :                         l_load_struct_gep(b, v_econtext,
    1807             :                                           FIELDNO_EXPRCONTEXT_DOMAINDATUM,
    1808             :                                           "");
    1809             :                     v_casenull =
    1810           0 :                         l_load_struct_gep(b, v_econtext,
    1811             :                                           FIELDNO_EXPRCONTEXT_DOMAINNULL,
    1812             :                                           "");
    1813           0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1814           0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1815             : 
    1816           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1817           0 :                     break;
    1818             :                 }
    1819             : 
    1820           0 :             case EEOP_DOMAIN_NOTNULL:
    1821           0 :                 build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
    1822             :                                 v_state, op);
    1823           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1824           0 :                 break;
    1825             : 
    1826           0 :             case EEOP_DOMAIN_CHECK:
    1827           0 :                 build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
    1828             :                                 v_state, op);
    1829           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1830           0 :                 break;
    1831             : 
    1832          36 :             case EEOP_CONVERT_ROWTYPE:
    1833          36 :                 build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
    1834             :                                 v_state, op, v_econtext);
    1835          36 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1836          36 :                 break;
    1837             : 
    1838          12 :             case EEOP_SCALARARRAYOP:
    1839          12 :                 build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
    1840             :                                 v_state, op);
    1841          12 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1842          12 :                 break;
    1843             : 
    1844           0 :             case EEOP_XMLEXPR:
    1845           0 :                 build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
    1846             :                                 v_state, op);
    1847           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1848           0 :                 break;
    1849             : 
    1850         332 :             case EEOP_AGGREF:
    1851             :                 {
    1852         332 :                     AggrefExprState *aggref = op->d.aggref.astate;
    1853             :                     LLVMValueRef v_aggnop;
    1854             :                     LLVMValueRef v_aggno;
    1855             :                     LLVMValueRef value,
    1856             :                                 isnull;
    1857             : 
    1858             :                     /*
    1859             :                      * At this point aggref->aggno is not yet set (it's set up
    1860             :                      * in ExecInitAgg() after initializing the expression). So
    1861             :                      * load it from memory each time round.
    1862             :                      */
    1863         332 :                     v_aggnop = l_ptr_const(&aggref->aggno,
    1864             :                                            l_ptr(LLVMInt32Type()));
    1865         332 :                     v_aggno = LLVMBuildLoad(b, v_aggnop, "v_aggno");
    1866             : 
    1867             :                     /* load agg value / null */
    1868         332 :                     value = l_load_gep1(b, v_aggvalues, v_aggno, "aggvalue");
    1869         332 :                     isnull = l_load_gep1(b, v_aggnulls, v_aggno, "aggnull");
    1870             : 
    1871             :                     /* and store result */
    1872         332 :                     LLVMBuildStore(b, value, v_resvaluep);
    1873         332 :                     LLVMBuildStore(b, isnull, v_resnullp);
    1874             : 
    1875         332 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1876         332 :                     break;
    1877             :                 }
    1878             : 
    1879           0 :             case EEOP_GROUPING_FUNC:
    1880           0 :                 build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
    1881             :                                 v_state, op);
    1882           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1883           0 :                 break;
    1884             : 
    1885           0 :             case EEOP_WINDOW_FUNC:
    1886             :                 {
    1887           0 :                     WindowFuncExprState *wfunc = op->d.window_func.wfstate;
    1888             :                     LLVMValueRef v_wfuncnop;
    1889             :                     LLVMValueRef v_wfuncno;
    1890             :                     LLVMValueRef value,
    1891             :                                 isnull;
    1892             : 
    1893             :                     /*
    1894             :                      * At this point aggref->wfuncno is not yet set (it's set
    1895             :                      * up in ExecInitWindowAgg() after initializing the
    1896             :                      * expression). So load it from memory each time round.
    1897             :                      */
    1898           0 :                     v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
    1899             :                                              l_ptr(LLVMInt32Type()));
    1900           0 :                     v_wfuncno = LLVMBuildLoad(b, v_wfuncnop, "v_wfuncno");
    1901             : 
    1902             :                     /* load window func value / null */
    1903           0 :                     value = l_load_gep1(b, v_aggvalues, v_wfuncno,
    1904             :                                         "windowvalue");
    1905           0 :                     isnull = l_load_gep1(b, v_aggnulls, v_wfuncno,
    1906             :                                          "windownull");
    1907             : 
    1908           0 :                     LLVMBuildStore(b, value, v_resvaluep);
    1909           0 :                     LLVMBuildStore(b, isnull, v_resnullp);
    1910             : 
    1911           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1912           0 :                     break;
    1913             :                 }
    1914             : 
    1915         232 :             case EEOP_SUBPLAN:
    1916         232 :                 build_EvalXFunc(b, mod, "ExecEvalSubPlan",
    1917             :                                 v_state, op, v_econtext);
    1918         232 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1919         232 :                 break;
    1920             : 
    1921           0 :             case EEOP_ALTERNATIVE_SUBPLAN:
    1922           0 :                 build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan",
    1923             :                                 v_state, op, v_econtext);
    1924           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1925           0 :                 break;
    1926             : 
    1927           0 :             case EEOP_AGG_STRICT_DESERIALIZE:
    1928             :             case EEOP_AGG_DESERIALIZE:
    1929             :                 {
    1930             :                     AggState   *aggstate;
    1931           0 :                     FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data;
    1932             : 
    1933             :                     LLVMValueRef v_retval;
    1934             :                     LLVMValueRef v_fcinfo_isnull;
    1935             :                     LLVMValueRef v_tmpcontext;
    1936             :                     LLVMValueRef v_oldcontext;
    1937             : 
    1938           0 :                     if (opcode == EEOP_AGG_STRICT_DESERIALIZE)
    1939             :                     {
    1940             :                         LLVMValueRef v_fcinfo;
    1941             :                         LLVMValueRef v_argnull0;
    1942             :                         LLVMBasicBlockRef b_deserialize;
    1943             : 
    1944           0 :                         b_deserialize = l_bb_before_v(opblocks[opno + 1],
    1945             :                                                       "op.%d.deserialize", opno);
    1946             : 
    1947           0 :                         v_fcinfo = l_ptr_const(fcinfo,
    1948             :                                                l_ptr(StructFunctionCallInfoData));
    1949           0 :                         v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1950             : 
    1951           0 :                         LLVMBuildCondBr(b,
    1952             :                                         LLVMBuildICmp(b,
    1953             :                                                       LLVMIntEQ,
    1954             :                                                       v_argnull0,
    1955             :                                                       l_sbool_const(1),
    1956             :                                                       ""),
    1957           0 :                                         opblocks[op->d.agg_deserialize.jumpnull],
    1958             :                                         b_deserialize);
    1959           0 :                         LLVMPositionBuilderAtEnd(b, b_deserialize);
    1960             :                     }
    1961             : 
    1962           0 :                     aggstate = castNode(AggState, state->parent);
    1963           0 :                     fcinfo = op->d.agg_deserialize.fcinfo_data;
    1964             : 
    1965             :                     v_tmpcontext =
    1966           0 :                         l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
    1967             :                                     l_ptr(StructMemoryContextData));
    1968           0 :                     v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
    1969           0 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    1970             :                                            &v_fcinfo_isnull);
    1971           0 :                     l_mcxt_switch(mod, b, v_oldcontext);
    1972             : 
    1973           0 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    1974           0 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
    1975             : 
    1976           0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1977           0 :                     break;
    1978             :                 }
    1979             : 
    1980          46 :             case EEOP_AGG_STRICT_INPUT_CHECK_ARGS:
    1981             :             case EEOP_AGG_STRICT_INPUT_CHECK_NULLS:
    1982             :                 {
    1983          46 :                     int         nargs = op->d.agg_strict_input_check.nargs;
    1984          46 :                     NullableDatum *args = op->d.agg_strict_input_check.args;
    1985          46 :                     bool       *nulls = op->d.agg_strict_input_check.nulls;
    1986             :                     int         jumpnull;
    1987             : 
    1988             :                     LLVMValueRef v_argsp;
    1989             :                     LLVMValueRef v_nullsp;
    1990             :                     LLVMBasicBlockRef *b_checknulls;
    1991             : 
    1992             :                     Assert(nargs > 0);
    1993             : 
    1994          46 :                     jumpnull = op->d.agg_strict_input_check.jumpnull;
    1995          46 :                     v_argsp = l_ptr_const(args, l_ptr(StructNullableDatum));
    1996          46 :                     v_nullsp = l_ptr_const(nulls, l_ptr(TypeStorageBool));
    1997             : 
    1998             :                     /* create blocks for checking args */
    1999          46 :                     b_checknulls = palloc(sizeof(LLVMBasicBlockRef *) * nargs);
    2000          92 :                     for (int argno = 0; argno < nargs; argno++)
    2001             :                     {
    2002          46 :                         b_checknulls[argno] =
    2003          46 :                             l_bb_before_v(opblocks[opno + 1],
    2004             :                                           "op.%d.check-null.%d",
    2005             :                                           opno, argno);
    2006             :                     }
    2007             : 
    2008          46 :                     LLVMBuildBr(b, b_checknulls[0]);
    2009             : 
    2010             :                     /* strict function, check for NULL args */
    2011          92 :                     for (int argno = 0; argno < nargs; argno++)
    2012             :                     {
    2013          46 :                         LLVMValueRef v_argno = l_int32_const(argno);
    2014             :                         LLVMValueRef v_argisnull;
    2015             :                         LLVMBasicBlockRef b_argnotnull;
    2016             : 
    2017          46 :                         LLVMPositionBuilderAtEnd(b, b_checknulls[argno]);
    2018             : 
    2019          46 :                         if (argno + 1 == nargs)
    2020          46 :                             b_argnotnull = opblocks[opno + 1];
    2021             :                         else
    2022           0 :                             b_argnotnull = b_checknulls[argno + 1];
    2023             : 
    2024          46 :                         if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
    2025           2 :                             v_argisnull = l_load_gep1(b, v_nullsp, v_argno, "");
    2026             :                         else
    2027             :                         {
    2028             :                             LLVMValueRef v_argn;
    2029             : 
    2030          44 :                             v_argn = LLVMBuildGEP(b, v_argsp, &v_argno, 1, "");
    2031             :                             v_argisnull =
    2032          44 :                                 l_load_struct_gep(b, v_argn,
    2033             :                                                   FIELDNO_NULLABLE_DATUM_ISNULL,
    2034             :                                                   "");
    2035             :                         }
    2036             : 
    2037          46 :                         LLVMBuildCondBr(b,
    2038             :                                         LLVMBuildICmp(b,
    2039             :                                                       LLVMIntEQ,
    2040             :                                                       v_argisnull,
    2041             :                                                       l_sbool_const(1), ""),
    2042          46 :                                         opblocks[jumpnull],
    2043             :                                         b_argnotnull);
    2044             :                     }
    2045             : 
    2046          46 :                     break;
    2047             :                 }
    2048             : 
    2049         248 :             case EEOP_AGG_PLAIN_PERGROUP_NULLCHECK:
    2050             :                 {
    2051             :                     int         jumpnull;
    2052             :                     LLVMValueRef v_aggstatep;
    2053             :                     LLVMValueRef v_allpergroupsp;
    2054             :                     LLVMValueRef v_pergroup_allaggs;
    2055             :                     LLVMValueRef v_setoff;
    2056             : 
    2057         248 :                     jumpnull = op->d.agg_plain_pergroup_nullcheck.jumpnull;
    2058             : 
    2059             :                     /*
    2060             :                      * pergroup_allaggs = aggstate->all_pergroups
    2061             :                      * [op->d.agg_plain_pergroup_nullcheck.setoff];
    2062             :                      */
    2063         248 :                     v_aggstatep = LLVMBuildBitCast(b, v_parent,
    2064             :                                                    l_ptr(StructAggState), "");
    2065             : 
    2066         248 :                     v_allpergroupsp = l_load_struct_gep(b, v_aggstatep,
    2067             :                                                         FIELDNO_AGGSTATE_ALL_PERGROUPS,
    2068             :                                                         "aggstate.all_pergroups");
    2069             : 
    2070         248 :                     v_setoff = l_int32_const(op->d.agg_plain_pergroup_nullcheck.setoff);
    2071             : 
    2072         248 :                     v_pergroup_allaggs = l_load_gep1(b, v_allpergroupsp, v_setoff, "");
    2073             : 
    2074         248 :                     LLVMBuildCondBr(b,
    2075             :                                     LLVMBuildICmp(b, LLVMIntEQ,
    2076             :                                                   LLVMBuildPtrToInt(b, v_pergroup_allaggs, TypeSizeT, ""),
    2077             :                                                   l_sizet_const(0), ""),
    2078         248 :                                     opblocks[jumpnull],
    2079         248 :                                     opblocks[opno + 1]);
    2080         248 :                     break;
    2081             :                 }
    2082             : 
    2083         922 :             case EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL:
    2084             :             case EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL:
    2085             :             case EEOP_AGG_PLAIN_TRANS_BYVAL:
    2086             :             case EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF:
    2087             :             case EEOP_AGG_PLAIN_TRANS_STRICT_BYREF:
    2088             :             case EEOP_AGG_PLAIN_TRANS_BYREF:
    2089             :                 {
    2090             :                     AggState   *aggstate;
    2091             :                     AggStatePerTrans pertrans;
    2092             :                     FunctionCallInfo fcinfo;
    2093             : 
    2094             :                     LLVMValueRef v_aggstatep;
    2095             :                     LLVMValueRef v_fcinfo;
    2096             :                     LLVMValueRef v_fcinfo_isnull;
    2097             : 
    2098             :                     LLVMValueRef v_transvaluep;
    2099             :                     LLVMValueRef v_transnullp;
    2100             : 
    2101             :                     LLVMValueRef v_setoff;
    2102             :                     LLVMValueRef v_transno;
    2103             : 
    2104             :                     LLVMValueRef v_aggcontext;
    2105             : 
    2106             :                     LLVMValueRef v_allpergroupsp;
    2107             :                     LLVMValueRef v_current_setp;
    2108             :                     LLVMValueRef v_current_pertransp;
    2109             :                     LLVMValueRef v_curaggcontext;
    2110             : 
    2111             :                     LLVMValueRef v_pertransp;
    2112             : 
    2113             :                     LLVMValueRef v_pergroupp;
    2114             : 
    2115             :                     LLVMValueRef v_retval;
    2116             : 
    2117             :                     LLVMValueRef v_tmpcontext;
    2118             :                     LLVMValueRef v_oldcontext;
    2119             : 
    2120         922 :                     aggstate = castNode(AggState, state->parent);
    2121         922 :                     pertrans = op->d.agg_trans.pertrans;
    2122             : 
    2123         922 :                     fcinfo = pertrans->transfn_fcinfo;
    2124             : 
    2125             :                     v_aggstatep =
    2126         922 :                         LLVMBuildBitCast(b, v_parent, l_ptr(StructAggState), "");
    2127         922 :                     v_pertransp = l_ptr_const(pertrans,
    2128             :                                               l_ptr(StructAggStatePerTransData));
    2129             : 
    2130             :                     /*
    2131             :                      * pergroup = &aggstate->all_pergroups
    2132             :                      * [op->d.agg_strict_trans_check.setoff]
    2133             :                      * [op->d.agg_init_trans_check.transno];
    2134             :                      */
    2135             :                     v_allpergroupsp =
    2136         922 :                         l_load_struct_gep(b, v_aggstatep,
    2137             :                                           FIELDNO_AGGSTATE_ALL_PERGROUPS,
    2138             :                                           "aggstate.all_pergroups");
    2139         922 :                     v_setoff = l_int32_const(op->d.agg_trans.setoff);
    2140         922 :                     v_transno = l_int32_const(op->d.agg_trans.transno);
    2141             :                     v_pergroupp =
    2142         922 :                         LLVMBuildGEP(b,
    2143             :                                      l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
    2144             :                                      &v_transno, 1, "");
    2145             : 
    2146             : 
    2147         922 :                     if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL ||
    2148             :                         opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF)
    2149             :                     {
    2150             :                         LLVMValueRef v_notransvalue;
    2151             :                         LLVMBasicBlockRef b_init;
    2152             :                         LLVMBasicBlockRef b_no_init;
    2153             : 
    2154             :                         v_notransvalue =
    2155         196 :                             l_load_struct_gep(b, v_pergroupp,
    2156             :                                               FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE,
    2157             :                                               "notransvalue");
    2158             : 
    2159         196 :                         b_init = l_bb_before_v(opblocks[opno + 1],
    2160             :                                                "op.%d.inittrans", opno);
    2161         196 :                         b_no_init = l_bb_before_v(opblocks[opno + 1],
    2162             :                                                   "op.%d.no_inittrans", opno);
    2163             : 
    2164         196 :                         LLVMBuildCondBr(b,
    2165             :                                         LLVMBuildICmp(b, LLVMIntEQ, v_notransvalue,
    2166             :                                                       l_sbool_const(1), ""),
    2167             :                                         b_init,
    2168             :                                         b_no_init);
    2169             : 
    2170             :                         /* block to init the transition value if necessary */
    2171             :                         {
    2172             :                             LLVMValueRef params[4];
    2173             : 
    2174         196 :                             LLVMPositionBuilderAtEnd(b, b_init);
    2175             : 
    2176         196 :                             v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
    2177             :                                                        l_ptr(StructExprContext));
    2178             : 
    2179         196 :                             params[0] = v_aggstatep;
    2180         196 :                             params[1] = v_pertransp;
    2181         196 :                             params[2] = v_pergroupp;
    2182         196 :                             params[3] = v_aggcontext;
    2183             : 
    2184         196 :                             LLVMBuildCall(b,
    2185             :                                           llvm_pg_func(mod, "ExecAggInitGroup"),
    2186             :                                           params, lengthof(params),
    2187             :                                           "");
    2188             : 
    2189         196 :                             LLVMBuildBr(b, opblocks[opno + 1]);
    2190             : 
    2191             :                         }
    2192             : 
    2193         196 :                         LLVMPositionBuilderAtEnd(b, b_no_init);
    2194             :                     }
    2195             : 
    2196         922 :                     if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL ||
    2197         726 :                         opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF ||
    2198         268 :                         opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL ||
    2199             :                         opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYREF)
    2200             :                     {
    2201             :                         LLVMValueRef v_transnull;
    2202             :                         LLVMBasicBlockRef b_strictpass;
    2203             : 
    2204         654 :                         b_strictpass = l_bb_before_v(opblocks[opno + 1],
    2205             :                                                      "op.%d.strictpass", opno);
    2206             :                         v_transnull =
    2207         654 :                             l_load_struct_gep(b, v_pergroupp,
    2208             :                                               FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
    2209             :                                               "transnull");
    2210             : 
    2211         654 :                         LLVMBuildCondBr(b,
    2212             :                                         LLVMBuildICmp(b, LLVMIntEQ, v_transnull,
    2213             :                                                       l_sbool_const(1), ""),
    2214         654 :                                         opblocks[opno + 1],
    2215             :                                         b_strictpass);
    2216             : 
    2217         654 :                         LLVMPositionBuilderAtEnd(b, b_strictpass);
    2218             :                     }
    2219             : 
    2220             : 
    2221         922 :                     v_fcinfo = l_ptr_const(fcinfo,
    2222             :                                            l_ptr(StructFunctionCallInfoData));
    2223         922 :                     v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
    2224             :                                                l_ptr(StructExprContext));
    2225             : 
    2226             :                     v_current_setp =
    2227         922 :                         LLVMBuildStructGEP(b,
    2228             :                                            v_aggstatep,
    2229             :                                            FIELDNO_AGGSTATE_CURRENT_SET,
    2230             :                                            "aggstate.current_set");
    2231             :                     v_curaggcontext =
    2232         922 :                         LLVMBuildStructGEP(b,
    2233             :                                            v_aggstatep,
    2234             :                                            FIELDNO_AGGSTATE_CURAGGCONTEXT,
    2235             :                                            "aggstate.curaggcontext");
    2236             :                     v_current_pertransp =
    2237         922 :                         LLVMBuildStructGEP(b,
    2238             :                                            v_aggstatep,
    2239             :                                            FIELDNO_AGGSTATE_CURPERTRANS,
    2240             :                                            "aggstate.curpertrans");
    2241             : 
    2242             :                     /* set aggstate globals */
    2243         922 :                     LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
    2244         922 :                     LLVMBuildStore(b, l_int32_const(op->d.agg_trans.setno),
    2245             :                                    v_current_setp);
    2246         922 :                     LLVMBuildStore(b, v_pertransp, v_current_pertransp);
    2247             : 
    2248             :                     /* invoke transition function in per-tuple context */
    2249             :                     v_tmpcontext =
    2250         922 :                         l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
    2251             :                                     l_ptr(StructMemoryContextData));
    2252         922 :                     v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
    2253             : 
    2254             :                     /* store transvalue in fcinfo->args[0] */
    2255             :                     v_transvaluep =
    2256         922 :                         LLVMBuildStructGEP(b, v_pergroupp,
    2257             :                                            FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
    2258             :                                            "transvalue");
    2259             :                     v_transnullp =
    2260         922 :                         LLVMBuildStructGEP(b, v_pergroupp,
    2261             :                                            FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
    2262             :                                            "transnullp");
    2263         922 :                     LLVMBuildStore(b,
    2264             :                                    LLVMBuildLoad(b, v_transvaluep,
    2265             :                                                  "transvalue"),
    2266             :                                    l_funcvaluep(b, v_fcinfo, 0));
    2267         922 :                     LLVMBuildStore(b,
    2268             :                                    LLVMBuildLoad(b, v_transnullp, "transnull"),
    2269             :                                    l_funcnullp(b, v_fcinfo, 0));
    2270             : 
    2271             :                     /* and invoke transition function */
    2272         922 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    2273             :                                            &v_fcinfo_isnull);
    2274             : 
    2275             :                     /*
    2276             :                      * For pass-by-ref datatype, must copy the new value into
    2277             :                      * aggcontext and free the prior transValue.  But if
    2278             :                      * transfn returned a pointer to its first input, we don't
    2279             :                      * need to do anything.  Also, if transfn returned a
    2280             :                      * pointer to a R/W expanded object that is already a
    2281             :                      * child of the aggcontext, assume we can adopt that value
    2282             :                      * without copying it.
    2283             :                      */
    2284         922 :                     if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF ||
    2285         730 :                         opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYREF ||
    2286             :                         opcode == EEOP_AGG_PLAIN_TRANS_BYREF)
    2287             :                     {
    2288             :                         LLVMBasicBlockRef b_call;
    2289             :                         LLVMBasicBlockRef b_nocall;
    2290             :                         LLVMValueRef v_fn;
    2291             :                         LLVMValueRef v_transvalue;
    2292             :                         LLVMValueRef v_transnull;
    2293             :                         LLVMValueRef v_newval;
    2294             :                         LLVMValueRef params[6];
    2295             : 
    2296         192 :                         b_call = l_bb_before_v(opblocks[opno + 1],
    2297             :                                                "op.%d.transcall", opno);
    2298         192 :                         b_nocall = l_bb_before_v(opblocks[opno + 1],
    2299             :                                                  "op.%d.transnocall", opno);
    2300             : 
    2301         192 :                         v_transvalue = LLVMBuildLoad(b, v_transvaluep, "");
    2302         192 :                         v_transnull = LLVMBuildLoad(b, v_transnullp, "");
    2303             : 
    2304             :                         /*
    2305             :                          * DatumGetPointer(newVal) !=
    2306             :                          * DatumGetPointer(pergroup->transValue))
    2307             :                          */
    2308         192 :                         LLVMBuildCondBr(b,
    2309             :                                         LLVMBuildICmp(b, LLVMIntEQ,
    2310             :                                                       v_transvalue,
    2311             :                                                       v_retval, ""),
    2312             :                                         b_nocall, b_call);
    2313             : 
    2314             :                         /* returned datum not passed datum, reparent */
    2315         192 :                         LLVMPositionBuilderAtEnd(b, b_call);
    2316             : 
    2317         192 :                         params[0] = v_aggstatep;
    2318         192 :                         params[1] = v_pertransp;
    2319         192 :                         params[2] = v_retval;
    2320         192 :                         params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
    2321             :                                                    TypeParamBool, "");
    2322         192 :                         params[4] = v_transvalue;
    2323         192 :                         params[5] = LLVMBuildTrunc(b, v_transnull,
    2324             :                                                    TypeParamBool, "");
    2325             : 
    2326         192 :                         v_fn = llvm_pg_func(mod, "ExecAggTransReparent");
    2327             :                         v_newval =
    2328         192 :                             LLVMBuildCall(b, v_fn,
    2329             :                                           params, lengthof(params),
    2330             :                                           "");
    2331             : 
    2332             :                         /* store trans value */
    2333         192 :                         LLVMBuildStore(b, v_newval, v_transvaluep);
    2334         192 :                         LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
    2335             : 
    2336         192 :                         l_mcxt_switch(mod, b, v_oldcontext);
    2337         192 :                         LLVMBuildBr(b, opblocks[opno + 1]);
    2338             : 
    2339             :                         /* returned datum passed datum, no need to reparent */
    2340         192 :                         LLVMPositionBuilderAtEnd(b, b_nocall);
    2341             :                     }
    2342             : 
    2343             :                     /* store trans value */
    2344         922 :                     LLVMBuildStore(b, v_retval, v_transvaluep);
    2345         922 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
    2346             : 
    2347         922 :                     l_mcxt_switch(mod, b, v_oldcontext);
    2348             : 
    2349         922 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2350         922 :                     break;
    2351             :                 }
    2352             : 
    2353           2 :             case EEOP_AGG_ORDERED_TRANS_DATUM:
    2354           2 :                 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
    2355             :                                 v_state, op, v_econtext);
    2356           2 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2357           2 :                 break;
    2358             : 
    2359           0 :             case EEOP_AGG_ORDERED_TRANS_TUPLE:
    2360           0 :                 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
    2361             :                                 v_state, op, v_econtext);
    2362           0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2363           0 :                 break;
    2364             : 
    2365           0 :             case EEOP_LAST:
    2366             :                 Assert(false);
    2367           0 :                 break;
    2368             :         }
    2369       23110 :     }
    2370             : 
    2371        5072 :     LLVMDisposeBuilder(b);
    2372             : 
    2373             :     /*
    2374             :      * Don't immediately emit function, instead do so the first time the
    2375             :      * expression is actually evaluated. That allows to emit a lot of
    2376             :      * functions together, avoiding a lot of repeated llvm and memory
    2377             :      * remapping overhead.
    2378             :      */
    2379             :     {
    2380             : 
    2381        5072 :         CompiledExprState *cstate = palloc0(sizeof(CompiledExprState));
    2382             : 
    2383        5072 :         cstate->context = context;
    2384        5072 :         cstate->funcname = funcname;
    2385             : 
    2386        5072 :         state->evalfunc = ExecRunCompiledExpr;
    2387        5072 :         state->evalfunc_private = cstate;
    2388             :     }
    2389             : 
    2390        5072 :     llvm_leave_fatal_on_oom();
    2391             : 
    2392        5072 :     INSTR_TIME_SET_CURRENT(endtime);
    2393        5076 :     INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter,
    2394             :                           endtime, starttime);
    2395             : 
    2396        5072 :     return true;
    2397             : }
    2398             : 
    2399             : /*
    2400             :  * Run compiled expression.
    2401             :  *
    2402             :  * This will only be called the first time a JITed expression is called. We
    2403             :  * first make sure the expression is still up2date, and then get a pointer to
    2404             :  * the emitted function. The latter can be the first thing that triggers
    2405             :  * optimizing and emitting all the generated functions.
    2406             :  */
    2407             : static Datum
    2408        3104 : ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull)
    2409             : {
    2410        3104 :     CompiledExprState *cstate = state->evalfunc_private;
    2411             :     ExprStateEvalFunc func;
    2412             : 
    2413        3104 :     CheckExprStillValid(state, econtext);
    2414             : 
    2415        3104 :     llvm_enter_fatal_on_oom();
    2416        3104 :     func = (ExprStateEvalFunc) llvm_get_function(cstate->context,
    2417             :                                                  cstate->funcname);
    2418        3104 :     llvm_leave_fatal_on_oom();
    2419             :     Assert(func);
    2420             : 
    2421             :     /* remove indirection via this function for future calls */
    2422        3104 :     state->evalfunc = func;
    2423             : 
    2424        3104 :     return func(state, econtext, isNull);
    2425             : }
    2426             : 
    2427             : static LLVMValueRef
    2428        2836 : BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
    2429             :             LLVMModuleRef mod, FunctionCallInfo fcinfo,
    2430             :             LLVMValueRef *v_fcinfo_isnull)
    2431             : {
    2432             :     LLVMValueRef v_fn;
    2433             :     LLVMValueRef v_fcinfo_isnullp;
    2434             :     LLVMValueRef v_retval;
    2435             :     LLVMValueRef v_fcinfo;
    2436             : 
    2437        2836 :     v_fn = llvm_function_reference(context, b, mod, fcinfo);
    2438             : 
    2439        2836 :     v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
    2440        2836 :     v_fcinfo_isnullp = LLVMBuildStructGEP(b, v_fcinfo,
    2441             :                                           FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
    2442             :                                           "v_fcinfo_isnull");
    2443        2836 :     LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
    2444             : 
    2445        2836 :     v_retval = LLVMBuildCall(b, v_fn, &v_fcinfo, 1, "funccall");
    2446             : 
    2447        2836 :     if (v_fcinfo_isnull)
    2448        2836 :         *v_fcinfo_isnull = LLVMBuildLoad(b, v_fcinfo_isnullp, "");
    2449             : 
    2450             :     /*
    2451             :      * Add lifetime-end annotation, signalling that writes to memory don't
    2452             :      * have to be retained (important for inlining potential).
    2453             :      */
    2454             :     {
    2455        2836 :         LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
    2456             :         LLVMValueRef params[2];
    2457             : 
    2458        2836 :         params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs);
    2459        2836 :         params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type()));
    2460        2836 :         LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
    2461             : 
    2462        2836 :         params[0] = l_int64_const(sizeof(fcinfo->isnull));
    2463        2836 :         params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8Type()));
    2464        2836 :         LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
    2465             :     }
    2466             : 
    2467        2836 :     return v_retval;
    2468             : }
    2469             : 
    2470             : /*
    2471             :  * Implement an expression step by calling the function funcname.
    2472             :  */
    2473             : static LLVMValueRef
    2474        1108 : build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
    2475             :                    LLVMValueRef v_state, ExprEvalStep *op,
    2476             :                    int nargs, LLVMValueRef v_args[])
    2477             : {
    2478        1108 :     LLVMValueRef v_fn = llvm_pg_func(mod, funcname);
    2479             :     LLVMValueRef *params;
    2480        1108 :     int         argno = 0;
    2481             :     LLVMValueRef v_ret;
    2482             : 
    2483             :     /* cheap pre-check as llvm just asserts out */
    2484        1108 :     if (LLVMCountParams(v_fn) != (nargs + 2))
    2485           0 :         elog(ERROR, "parameter mismatch: %s expects %d passed %d",
    2486             :              funcname, LLVMCountParams(v_fn), nargs + 2);
    2487             : 
    2488        1108 :     params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
    2489             : 
    2490        1108 :     params[argno++] = v_state;
    2491        1108 :     params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
    2492             : 
    2493        2350 :     for (int i = 0; i < nargs; i++)
    2494        1242 :         params[argno++] = v_args[i];
    2495             : 
    2496        1108 :     v_ret = LLVMBuildCall(b, v_fn, params, argno, "");
    2497             : 
    2498        1108 :     pfree(params);
    2499             : 
    2500        1108 :     return v_ret;
    2501             : }
    2502             : 
    2503             : static LLVMValueRef
    2504        2836 : create_LifetimeEnd(LLVMModuleRef mod)
    2505             : {
    2506             :     LLVMTypeRef sig;
    2507             :     LLVMValueRef fn;
    2508             :     LLVMTypeRef param_types[2];
    2509             : 
    2510             :     /* LLVM 5+ has a variadic pointer argument */
    2511             : #if LLVM_VERSION_MAJOR < 5
    2512             :     const char *nm = "llvm.lifetime.end";
    2513             : #else
    2514        2836 :     const char *nm = "llvm.lifetime.end.p0i8";
    2515             : #endif
    2516             : 
    2517        2836 :     fn = LLVMGetNamedFunction(mod, nm);
    2518        2836 :     if (fn)
    2519        1960 :         return fn;
    2520             : 
    2521         876 :     param_types[0] = LLVMInt64Type();
    2522         876 :     param_types[1] = l_ptr(LLVMInt8Type());
    2523             : 
    2524         876 :     sig = LLVMFunctionType(LLVMVoidType(),
    2525             :                            param_types, lengthof(param_types),
    2526             :                            false);
    2527         876 :     fn = LLVMAddFunction(mod, nm, sig);
    2528             : 
    2529         876 :     LLVMSetFunctionCallConv(fn, LLVMCCallConv);
    2530             : 
    2531             :     Assert(LLVMGetIntrinsicID(fn));
    2532             : 
    2533         876 :     return fn;
    2534             : }

Generated by: LCOV version 1.13