LCOV - code coverage report
Current view: top level - src/backend/jit/llvm - llvmjit_expr.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 68.2 % 1042 711
Test Date: 2026-03-03 09:14:47 Functions: 100.0 % 5 5
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-2026, 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         3510 : llvm_compile_expr(ExprState *state)
      79              : {
      80         3510 :     PlanState  *parent = state->parent;
      81              :     char       *funcname;
      82              : 
      83         3510 :     LLVMJitContext *context = NULL;
      84              : 
      85              :     LLVMBuilderRef b;
      86              :     LLVMModuleRef mod;
      87              :     LLVMContextRef lc;
      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_oldslot;
     109              :     LLVMValueRef v_newslot;
     110              :     LLVMValueRef v_resultslot;
     111              : 
     112              :     /* nulls/values of slots */
     113              :     LLVMValueRef v_innervalues;
     114              :     LLVMValueRef v_innernulls;
     115              :     LLVMValueRef v_outervalues;
     116              :     LLVMValueRef v_outernulls;
     117              :     LLVMValueRef v_scanvalues;
     118              :     LLVMValueRef v_scannulls;
     119              :     LLVMValueRef v_oldvalues;
     120              :     LLVMValueRef v_oldnulls;
     121              :     LLVMValueRef v_newvalues;
     122              :     LLVMValueRef v_newnulls;
     123              :     LLVMValueRef v_resultvalues;
     124              :     LLVMValueRef v_resultnulls;
     125              : 
     126              :     /* stuff in econtext */
     127              :     LLVMValueRef v_aggvalues;
     128              :     LLVMValueRef v_aggnulls;
     129              : 
     130              :     instr_time  starttime;
     131              :     instr_time  deform_starttime;
     132              :     instr_time  endtime;
     133              :     instr_time  deform_endtime;
     134              : 
     135         3510 :     llvm_enter_fatal_on_oom();
     136              : 
     137              :     /*
     138              :      * Right now we don't support compiling expressions without a parent, as
     139              :      * we need access to the EState.
     140              :      */
     141              :     Assert(parent);
     142              : 
     143              :     /* get or create JIT context */
     144         3510 :     if (parent->state->es_jit)
     145         3048 :         context = (LLVMJitContext *) parent->state->es_jit;
     146              :     else
     147              :     {
     148          462 :         context = llvm_create_context(parent->state->es_jit_flags);
     149          462 :         parent->state->es_jit = &context->base;
     150              :     }
     151              : 
     152         3510 :     INSTR_TIME_SET_CURRENT(starttime);
     153              : 
     154         3510 :     mod = llvm_mutable_module(context);
     155         3510 :     lc = LLVMGetModuleContext(mod);
     156              : 
     157         3510 :     b = LLVMCreateBuilderInContext(lc);
     158              : 
     159         3510 :     funcname = llvm_expand_funcname(context, "evalexpr");
     160              : 
     161              :     /* create function */
     162         3510 :     eval_fn = LLVMAddFunction(mod, funcname,
     163              :                               llvm_pg_var_func_type("ExecInterpExprStillValid"));
     164         3510 :     LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
     165         3510 :     LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
     166         3510 :     llvm_copy_attributes(AttributeTemplate, eval_fn);
     167              : 
     168         3510 :     entry = LLVMAppendBasicBlockInContext(lc, eval_fn, "entry");
     169              : 
     170              :     /* build state */
     171         3510 :     v_state = LLVMGetParam(eval_fn, 0);
     172         3510 :     v_econtext = LLVMGetParam(eval_fn, 1);
     173         3510 :     v_isnullp = LLVMGetParam(eval_fn, 2);
     174              : 
     175         3510 :     LLVMPositionBuilderAtEnd(b, entry);
     176              : 
     177         3510 :     v_tmpvaluep = l_struct_gep(b,
     178              :                                StructExprState,
     179              :                                v_state,
     180              :                                FIELDNO_EXPRSTATE_RESVALUE,
     181              :                                "v.state.resvalue");
     182         3510 :     v_tmpisnullp = l_struct_gep(b,
     183              :                                 StructExprState,
     184              :                                 v_state,
     185              :                                 FIELDNO_EXPRSTATE_RESNULL,
     186              :                                 "v.state.resnull");
     187         3510 :     v_parent = l_load_struct_gep(b,
     188              :                                  StructExprState,
     189              :                                  v_state,
     190              :                                  FIELDNO_EXPRSTATE_PARENT,
     191              :                                  "v.state.parent");
     192              : 
     193              :     /* build global slots */
     194         3510 :     v_scanslot = l_load_struct_gep(b,
     195              :                                    StructExprContext,
     196              :                                    v_econtext,
     197              :                                    FIELDNO_EXPRCONTEXT_SCANTUPLE,
     198              :                                    "v_scanslot");
     199         3510 :     v_innerslot = l_load_struct_gep(b,
     200              :                                     StructExprContext,
     201              :                                     v_econtext,
     202              :                                     FIELDNO_EXPRCONTEXT_INNERTUPLE,
     203              :                                     "v_innerslot");
     204         3510 :     v_outerslot = l_load_struct_gep(b,
     205              :                                     StructExprContext,
     206              :                                     v_econtext,
     207              :                                     FIELDNO_EXPRCONTEXT_OUTERTUPLE,
     208              :                                     "v_outerslot");
     209         3510 :     v_oldslot = l_load_struct_gep(b,
     210              :                                   StructExprContext,
     211              :                                   v_econtext,
     212              :                                   FIELDNO_EXPRCONTEXT_OLDTUPLE,
     213              :                                   "v_oldslot");
     214         3510 :     v_newslot = l_load_struct_gep(b,
     215              :                                   StructExprContext,
     216              :                                   v_econtext,
     217              :                                   FIELDNO_EXPRCONTEXT_NEWTUPLE,
     218              :                                   "v_newslot");
     219         3510 :     v_resultslot = l_load_struct_gep(b,
     220              :                                      StructExprState,
     221              :                                      v_state,
     222              :                                      FIELDNO_EXPRSTATE_RESULTSLOT,
     223              :                                      "v_resultslot");
     224              : 
     225              :     /* build global values/isnull pointers */
     226         3510 :     v_scanvalues = l_load_struct_gep(b,
     227              :                                      StructTupleTableSlot,
     228              :                                      v_scanslot,
     229              :                                      FIELDNO_TUPLETABLESLOT_VALUES,
     230              :                                      "v_scanvalues");
     231         3510 :     v_scannulls = l_load_struct_gep(b,
     232              :                                     StructTupleTableSlot,
     233              :                                     v_scanslot,
     234              :                                     FIELDNO_TUPLETABLESLOT_ISNULL,
     235              :                                     "v_scannulls");
     236         3510 :     v_innervalues = l_load_struct_gep(b,
     237              :                                       StructTupleTableSlot,
     238              :                                       v_innerslot,
     239              :                                       FIELDNO_TUPLETABLESLOT_VALUES,
     240              :                                       "v_innervalues");
     241         3510 :     v_innernulls = l_load_struct_gep(b,
     242              :                                      StructTupleTableSlot,
     243              :                                      v_innerslot,
     244              :                                      FIELDNO_TUPLETABLESLOT_ISNULL,
     245              :                                      "v_innernulls");
     246         3510 :     v_outervalues = l_load_struct_gep(b,
     247              :                                       StructTupleTableSlot,
     248              :                                       v_outerslot,
     249              :                                       FIELDNO_TUPLETABLESLOT_VALUES,
     250              :                                       "v_outervalues");
     251         3510 :     v_outernulls = l_load_struct_gep(b,
     252              :                                      StructTupleTableSlot,
     253              :                                      v_outerslot,
     254              :                                      FIELDNO_TUPLETABLESLOT_ISNULL,
     255              :                                      "v_outernulls");
     256         3510 :     v_oldvalues = l_load_struct_gep(b,
     257              :                                     StructTupleTableSlot,
     258              :                                     v_oldslot,
     259              :                                     FIELDNO_TUPLETABLESLOT_VALUES,
     260              :                                     "v_oldvalues");
     261         3510 :     v_oldnulls = l_load_struct_gep(b,
     262              :                                    StructTupleTableSlot,
     263              :                                    v_oldslot,
     264              :                                    FIELDNO_TUPLETABLESLOT_ISNULL,
     265              :                                    "v_oldnulls");
     266         3510 :     v_newvalues = l_load_struct_gep(b,
     267              :                                     StructTupleTableSlot,
     268              :                                     v_newslot,
     269              :                                     FIELDNO_TUPLETABLESLOT_VALUES,
     270              :                                     "v_newvalues");
     271         3510 :     v_newnulls = l_load_struct_gep(b,
     272              :                                    StructTupleTableSlot,
     273              :                                    v_newslot,
     274              :                                    FIELDNO_TUPLETABLESLOT_ISNULL,
     275              :                                    "v_newnulls");
     276         3510 :     v_resultvalues = l_load_struct_gep(b,
     277              :                                        StructTupleTableSlot,
     278              :                                        v_resultslot,
     279              :                                        FIELDNO_TUPLETABLESLOT_VALUES,
     280              :                                        "v_resultvalues");
     281         3510 :     v_resultnulls = l_load_struct_gep(b,
     282              :                                       StructTupleTableSlot,
     283              :                                       v_resultslot,
     284              :                                       FIELDNO_TUPLETABLESLOT_ISNULL,
     285              :                                       "v_resultnulls");
     286              : 
     287              :     /* aggvalues/aggnulls */
     288         3510 :     v_aggvalues = l_load_struct_gep(b,
     289              :                                     StructExprContext,
     290              :                                     v_econtext,
     291              :                                     FIELDNO_EXPRCONTEXT_AGGVALUES,
     292              :                                     "v.econtext.aggvalues");
     293         3510 :     v_aggnulls = l_load_struct_gep(b,
     294              :                                    StructExprContext,
     295              :                                    v_econtext,
     296              :                                    FIELDNO_EXPRCONTEXT_AGGNULLS,
     297              :                                    "v.econtext.aggnulls");
     298              : 
     299              :     /* allocate blocks for each op upfront, so we can do jumps easily */
     300         3510 :     opblocks = palloc_array(LLVMBasicBlockRef, state->steps_len);
     301        23462 :     for (int opno = 0; opno < state->steps_len; opno++)
     302        19952 :         opblocks[opno] = l_bb_append_v(eval_fn, "b.op.%d.start", opno);
     303              : 
     304              :     /* jump from entry to first block */
     305         3510 :     LLVMBuildBr(b, opblocks[0]);
     306              : 
     307        23462 :     for (int opno = 0; opno < state->steps_len; opno++)
     308              :     {
     309              :         ExprEvalStep *op;
     310              :         ExprEvalOp  opcode;
     311              :         LLVMValueRef v_resvaluep;
     312              :         LLVMValueRef v_resnullp;
     313              : 
     314        19952 :         LLVMPositionBuilderAtEnd(b, opblocks[opno]);
     315              : 
     316        19952 :         op = &state->steps[opno];
     317        19952 :         opcode = ExecEvalStepOp(state, op);
     318              : 
     319        19952 :         v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeDatum));
     320        19952 :         v_resnullp = l_ptr_const(op->resnull, l_ptr(TypeStorageBool));
     321              : 
     322        19952 :         switch (opcode)
     323              :         {
     324         1892 :             case EEOP_DONE_RETURN:
     325              :                 {
     326              :                     LLVMValueRef v_tmpisnull;
     327              :                     LLVMValueRef v_tmpvalue;
     328              : 
     329         1892 :                     v_tmpvalue = l_load(b, TypeDatum, v_tmpvaluep, "");
     330         1892 :                     v_tmpisnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
     331              : 
     332         1892 :                     LLVMBuildStore(b, v_tmpisnull, v_isnullp);
     333              : 
     334         1892 :                     LLVMBuildRet(b, v_tmpvalue);
     335         1892 :                     break;
     336              :                 }
     337              : 
     338         1618 :             case EEOP_DONE_NO_RETURN:
     339         1618 :                 LLVMBuildRet(b, l_datum_const(0));
     340         1618 :                 break;
     341              : 
     342         2524 :             case EEOP_INNER_FETCHSOME:
     343              :             case EEOP_OUTER_FETCHSOME:
     344              :             case EEOP_SCAN_FETCHSOME:
     345              :             case EEOP_OLD_FETCHSOME:
     346              :             case EEOP_NEW_FETCHSOME:
     347              :                 {
     348         2524 :                     TupleDesc   desc = NULL;
     349              :                     LLVMValueRef v_slot;
     350              :                     LLVMBasicBlockRef b_fetch;
     351              :                     LLVMValueRef v_nvalid;
     352         2524 :                     LLVMValueRef l_jit_deform = NULL;
     353         2524 :                     const TupleTableSlotOps *tts_ops = NULL;
     354              : 
     355         2524 :                     b_fetch = l_bb_before_v(opblocks[opno + 1],
     356              :                                             "op.%d.fetch", opno);
     357              : 
     358         2524 :                     if (op->d.fetch.known_desc)
     359         2089 :                         desc = op->d.fetch.known_desc;
     360              : 
     361         2524 :                     if (op->d.fetch.fixed)
     362         2089 :                         tts_ops = op->d.fetch.kind;
     363              : 
     364              :                     /* step should not have been generated */
     365              :                     Assert(tts_ops != &TTSOpsVirtual);
     366              : 
     367         2524 :                     if (opcode == EEOP_INNER_FETCHSOME)
     368          873 :                         v_slot = v_innerslot;
     369         1651 :                     else if (opcode == EEOP_OUTER_FETCHSOME)
     370          812 :                         v_slot = v_outerslot;
     371          839 :                     else if (opcode == EEOP_SCAN_FETCHSOME)
     372          833 :                         v_slot = v_scanslot;
     373            6 :                     else if (opcode == EEOP_OLD_FETCHSOME)
     374            3 :                         v_slot = v_oldslot;
     375              :                     else
     376            3 :                         v_slot = v_newslot;
     377              : 
     378              :                     /*
     379              :                      * Check if all required attributes are available, or
     380              :                      * whether deforming is required.
     381              :                      */
     382              :                     v_nvalid =
     383         2524 :                         l_load_struct_gep(b,
     384              :                                           StructTupleTableSlot,
     385              :                                           v_slot,
     386              :                                           FIELDNO_TUPLETABLESLOT_NVALID,
     387              :                                           "");
     388         2524 :                     LLVMBuildCondBr(b,
     389              :                                     LLVMBuildICmp(b, LLVMIntUGE, v_nvalid,
     390         2524 :                                                   l_int16_const(lc, op->d.fetch.last_var),
     391              :                                                   ""),
     392         2524 :                                     opblocks[opno + 1], b_fetch);
     393              : 
     394         2524 :                     LLVMPositionBuilderAtEnd(b, b_fetch);
     395              : 
     396              :                     /*
     397              :                      * If the tupledesc of the to-be-deformed tuple is known,
     398              :                      * and JITing of deforming is enabled, build deform
     399              :                      * function specific to tupledesc and the exact number of
     400              :                      * to-be-extracted attributes.
     401              :                      */
     402         2524 :                     if (tts_ops && desc && (context->base.flags & PGJIT_DEFORM))
     403              :                     {
     404         2089 :                         INSTR_TIME_SET_CURRENT(deform_starttime);
     405              :                         l_jit_deform =
     406         2089 :                             slot_compile_deform(context, desc,
     407              :                                                 tts_ops,
     408              :                                                 op->d.fetch.last_var);
     409         2089 :                         INSTR_TIME_SET_CURRENT(deform_endtime);
     410         2089 :                         INSTR_TIME_ACCUM_DIFF(context->base.instr.deform_counter,
     411              :                                               deform_endtime, deform_starttime);
     412              :                     }
     413              : 
     414         2524 :                     if (l_jit_deform)
     415              :                     {
     416              :                         LLVMValueRef params[1];
     417              : 
     418         2089 :                         params[0] = v_slot;
     419              : 
     420         2089 :                         l_call(b,
     421              :                                LLVMGetFunctionType(l_jit_deform),
     422              :                                l_jit_deform,
     423              :                                params, lengthof(params), "");
     424              :                     }
     425              :                     else
     426              :                     {
     427              :                         LLVMValueRef params[2];
     428              : 
     429          435 :                         params[0] = v_slot;
     430          435 :                         params[1] = l_int32_const(lc, op->d.fetch.last_var);
     431              : 
     432          435 :                         l_call(b,
     433              :                                llvm_pg_var_func_type("slot_getsomeattrs_int"),
     434              :                                llvm_pg_func(mod, "slot_getsomeattrs_int"),
     435              :                                params, lengthof(params), "");
     436              :                     }
     437              : 
     438         2524 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     439         2524 :                     break;
     440              :                 }
     441              : 
     442         3242 :             case EEOP_INNER_VAR:
     443              :             case EEOP_OUTER_VAR:
     444              :             case EEOP_SCAN_VAR:
     445              :             case EEOP_OLD_VAR:
     446              :             case EEOP_NEW_VAR:
     447              :                 {
     448              :                     LLVMValueRef value,
     449              :                                 isnull;
     450              :                     LLVMValueRef v_attnum;
     451              :                     LLVMValueRef v_values;
     452              :                     LLVMValueRef v_nulls;
     453              : 
     454         3242 :                     if (opcode == EEOP_INNER_VAR)
     455              :                     {
     456         1055 :                         v_values = v_innervalues;
     457         1055 :                         v_nulls = v_innernulls;
     458              :                     }
     459         2187 :                     else if (opcode == EEOP_OUTER_VAR)
     460              :                     {
     461         1404 :                         v_values = v_outervalues;
     462         1404 :                         v_nulls = v_outernulls;
     463              :                     }
     464          783 :                     else if (opcode == EEOP_SCAN_VAR)
     465              :                     {
     466          759 :                         v_values = v_scanvalues;
     467          759 :                         v_nulls = v_scannulls;
     468              :                     }
     469           24 :                     else if (opcode == EEOP_OLD_VAR)
     470              :                     {
     471           12 :                         v_values = v_oldvalues;
     472           12 :                         v_nulls = v_oldnulls;
     473              :                     }
     474              :                     else
     475              :                     {
     476           12 :                         v_values = v_newvalues;
     477           12 :                         v_nulls = v_newnulls;
     478              :                     }
     479              : 
     480         3242 :                     v_attnum = l_int32_const(lc, op->d.var.attnum);
     481         3242 :                     value = l_load_gep1(b, TypeDatum, v_values, v_attnum, "");
     482         3242 :                     isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
     483         3242 :                     LLVMBuildStore(b, value, v_resvaluep);
     484         3242 :                     LLVMBuildStore(b, isnull, v_resnullp);
     485              : 
     486         3242 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     487         3242 :                     break;
     488              :                 }
     489              : 
     490          222 :             case EEOP_INNER_SYSVAR:
     491              :             case EEOP_OUTER_SYSVAR:
     492              :             case EEOP_SCAN_SYSVAR:
     493              :             case EEOP_OLD_SYSVAR:
     494              :             case EEOP_NEW_SYSVAR:
     495              :                 {
     496              :                     LLVMValueRef v_slot;
     497              : 
     498          222 :                     if (opcode == EEOP_INNER_SYSVAR)
     499            0 :                         v_slot = v_innerslot;
     500          222 :                     else if (opcode == EEOP_OUTER_SYSVAR)
     501            0 :                         v_slot = v_outerslot;
     502          222 :                     else if (opcode == EEOP_SCAN_SYSVAR)
     503          222 :                         v_slot = v_scanslot;
     504            0 :                     else if (opcode == EEOP_OLD_SYSVAR)
     505            0 :                         v_slot = v_oldslot;
     506              :                     else
     507            0 :                         v_slot = v_newslot;
     508              : 
     509          222 :                     build_EvalXFunc(b, mod, "ExecEvalSysVar",
     510              :                                     v_state, op, v_econtext, v_slot);
     511              : 
     512          222 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     513          222 :                     break;
     514              :                 }
     515              : 
     516           60 :             case EEOP_WHOLEROW:
     517           60 :                 build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
     518              :                                 v_state, op, v_econtext);
     519           60 :                 LLVMBuildBr(b, opblocks[opno + 1]);
     520           60 :                 break;
     521              : 
     522         2790 :             case EEOP_ASSIGN_INNER_VAR:
     523              :             case EEOP_ASSIGN_OUTER_VAR:
     524              :             case EEOP_ASSIGN_SCAN_VAR:
     525              :             case EEOP_ASSIGN_OLD_VAR:
     526              :             case EEOP_ASSIGN_NEW_VAR:
     527              :                 {
     528              :                     LLVMValueRef v_value;
     529              :                     LLVMValueRef v_isnull;
     530              :                     LLVMValueRef v_rvaluep;
     531              :                     LLVMValueRef v_risnullp;
     532              :                     LLVMValueRef v_attnum;
     533              :                     LLVMValueRef v_resultnum;
     534              :                     LLVMValueRef v_values;
     535              :                     LLVMValueRef v_nulls;
     536              : 
     537         2790 :                     if (opcode == EEOP_ASSIGN_INNER_VAR)
     538              :                     {
     539          749 :                         v_values = v_innervalues;
     540          749 :                         v_nulls = v_innernulls;
     541              :                     }
     542         2041 :                     else if (opcode == EEOP_ASSIGN_OUTER_VAR)
     543              :                     {
     544         1352 :                         v_values = v_outervalues;
     545         1352 :                         v_nulls = v_outernulls;
     546              :                     }
     547          689 :                     else if (opcode == EEOP_ASSIGN_SCAN_VAR)
     548              :                     {
     549          677 :                         v_values = v_scanvalues;
     550          677 :                         v_nulls = v_scannulls;
     551              :                     }
     552           12 :                     else if (opcode == EEOP_ASSIGN_OLD_VAR)
     553              :                     {
     554            6 :                         v_values = v_oldvalues;
     555            6 :                         v_nulls = v_oldnulls;
     556              :                     }
     557              :                     else
     558              :                     {
     559            6 :                         v_values = v_newvalues;
     560            6 :                         v_nulls = v_newnulls;
     561              :                     }
     562              : 
     563              :                     /* load data */
     564         2790 :                     v_attnum = l_int32_const(lc, op->d.assign_var.attnum);
     565         2790 :                     v_value = l_load_gep1(b, TypeDatum, v_values, v_attnum, "");
     566         2790 :                     v_isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
     567              : 
     568              :                     /* compute addresses of targets */
     569         2790 :                     v_resultnum = l_int32_const(lc, op->d.assign_var.resultnum);
     570         2790 :                     v_rvaluep = l_gep(b,
     571              :                                       TypeDatum,
     572              :                                       v_resultvalues,
     573              :                                       &v_resultnum, 1, "");
     574         2790 :                     v_risnullp = l_gep(b,
     575              :                                        TypeStorageBool,
     576              :                                        v_resultnulls,
     577              :                                        &v_resultnum, 1, "");
     578              : 
     579              :                     /* and store */
     580         2790 :                     LLVMBuildStore(b, v_value, v_rvaluep);
     581         2790 :                     LLVMBuildStore(b, v_isnull, v_risnullp);
     582              : 
     583         2790 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     584         2790 :                     break;
     585              :                 }
     586              : 
     587         1197 :             case EEOP_ASSIGN_TMP:
     588              :             case EEOP_ASSIGN_TMP_MAKE_RO:
     589              :                 {
     590              :                     LLVMValueRef v_value,
     591              :                                 v_isnull;
     592              :                     LLVMValueRef v_rvaluep,
     593              :                                 v_risnullp;
     594              :                     LLVMValueRef v_resultnum;
     595         1197 :                     size_t      resultnum = op->d.assign_tmp.resultnum;
     596              : 
     597              :                     /* load data */
     598         1197 :                     v_value = l_load(b, TypeDatum, v_tmpvaluep, "");
     599         1197 :                     v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
     600              : 
     601              :                     /* compute addresses of targets */
     602         1197 :                     v_resultnum = l_int32_const(lc, resultnum);
     603              :                     v_rvaluep =
     604         1197 :                         l_gep(b, TypeDatum, v_resultvalues, &v_resultnum, 1, "");
     605              :                     v_risnullp =
     606         1197 :                         l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
     607              : 
     608              :                     /* store nullness */
     609         1197 :                     LLVMBuildStore(b, v_isnull, v_risnullp);
     610              : 
     611              :                     /* make value readonly if necessary */
     612         1197 :                     if (opcode == EEOP_ASSIGN_TMP_MAKE_RO)
     613              :                     {
     614              :                         LLVMBasicBlockRef b_notnull;
     615              :                         LLVMValueRef v_params[1];
     616              : 
     617          459 :                         b_notnull = l_bb_before_v(opblocks[opno + 1],
     618              :                                                   "op.%d.assign_tmp.notnull", opno);
     619              : 
     620              :                         /* check if value is NULL */
     621          459 :                         LLVMBuildCondBr(b,
     622              :                                         LLVMBuildICmp(b, LLVMIntEQ, v_isnull,
     623              :                                                       l_sbool_const(0), ""),
     624          459 :                                         b_notnull, opblocks[opno + 1]);
     625              : 
     626              :                         /* if value is not null, convert to RO datum */
     627          459 :                         LLVMPositionBuilderAtEnd(b, b_notnull);
     628          459 :                         v_params[0] = v_value;
     629              :                         v_value =
     630          459 :                             l_call(b,
     631              :                                    llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
     632              :                                    llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
     633              :                                    v_params, lengthof(v_params), "");
     634              : 
     635              :                         /*
     636              :                          * Falling out of the if () with builder in b_notnull,
     637              :                          * which is fine - the null is already stored above.
     638              :                          */
     639              :                     }
     640              : 
     641              :                     /* and finally store result */
     642         1197 :                     LLVMBuildStore(b, v_value, v_rvaluep);
     643              : 
     644         1197 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     645         1197 :                     break;
     646              :                 }
     647              : 
     648          482 :             case EEOP_CONST:
     649              :                 {
     650              :                     LLVMValueRef v_constvalue,
     651              :                                 v_constnull;
     652              : 
     653          482 :                     v_constvalue = l_datum_const(op->d.constval.value);
     654          482 :                     v_constnull = l_sbool_const(op->d.constval.isnull);
     655              : 
     656          482 :                     LLVMBuildStore(b, v_constvalue, v_resvaluep);
     657          482 :                     LLVMBuildStore(b, v_constnull, v_resnullp);
     658              : 
     659          482 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     660          482 :                     break;
     661              :                 }
     662              : 
     663         1036 :             case EEOP_FUNCEXPR:
     664              :             case EEOP_FUNCEXPR_STRICT:
     665              :             case EEOP_FUNCEXPR_STRICT_1:
     666              :             case EEOP_FUNCEXPR_STRICT_2:
     667              :                 {
     668         1036 :                     FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
     669              :                     LLVMValueRef v_fcinfo_isnull;
     670              :                     LLVMValueRef v_retval;
     671              : 
     672         1036 :                     if (opcode == EEOP_FUNCEXPR_STRICT ||
     673          865 :                         opcode == EEOP_FUNCEXPR_STRICT_1 ||
     674              :                         opcode == EEOP_FUNCEXPR_STRICT_2)
     675              :                     {
     676              :                         LLVMBasicBlockRef b_nonull;
     677              :                         LLVMBasicBlockRef *b_checkargnulls;
     678              :                         LLVMValueRef v_fcinfo;
     679              : 
     680              :                         /*
     681              :                          * Block for the actual function call, if args are
     682              :                          * non-NULL.
     683              :                          */
     684          990 :                         b_nonull = l_bb_before_v(opblocks[opno + 1],
     685              :                                                  "b.%d.no-null-args", opno);
     686              : 
     687              :                         /* should make sure they're optimized beforehand */
     688          990 :                         if (op->d.func.nargs == 0)
     689            0 :                             elog(ERROR, "argumentless strict functions are pointless");
     690              : 
     691              :                         v_fcinfo =
     692          990 :                             l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
     693              : 
     694              :                         /*
     695              :                          * set resnull to true, if the function is actually
     696              :                          * called, it'll be reset
     697              :                          */
     698          990 :                         LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
     699              : 
     700              :                         /* create blocks for checking args, one for each */
     701              :                         b_checkargnulls = (LLVMBasicBlockRef *)
     702          990 :                             palloc(sizeof(LLVMBasicBlockRef) * op->d.func.nargs);
     703         2799 :                         for (int argno = 0; argno < op->d.func.nargs; argno++)
     704         1809 :                             b_checkargnulls[argno] =
     705         1809 :                                 l_bb_before_v(b_nonull, "b.%d.isnull.%d", opno,
     706              :                                               argno);
     707              : 
     708              :                         /* jump to check of first argument */
     709          990 :                         LLVMBuildBr(b, b_checkargnulls[0]);
     710              : 
     711              :                         /* check each arg for NULLness */
     712         2799 :                         for (int argno = 0; argno < op->d.func.nargs; argno++)
     713              :                         {
     714              :                             LLVMValueRef v_argisnull;
     715              :                             LLVMBasicBlockRef b_argnotnull;
     716              : 
     717         1809 :                             LLVMPositionBuilderAtEnd(b, b_checkargnulls[argno]);
     718              : 
     719              :                             /*
     720              :                              * Compute block to jump to if argument is not
     721              :                              * null.
     722              :                              */
     723         1809 :                             if (argno + 1 == op->d.func.nargs)
     724          990 :                                 b_argnotnull = b_nonull;
     725              :                             else
     726          819 :                                 b_argnotnull = b_checkargnulls[argno + 1];
     727              : 
     728              :                             /* and finally load & check NULLness of arg */
     729         1809 :                             v_argisnull = l_funcnull(b, v_fcinfo, argno);
     730         1809 :                             LLVMBuildCondBr(b,
     731              :                                             LLVMBuildICmp(b, LLVMIntEQ,
     732              :                                                           v_argisnull,
     733              :                                                           l_sbool_const(1),
     734              :                                                           ""),
     735         1809 :                                             opblocks[opno + 1],
     736              :                                             b_argnotnull);
     737              :                         }
     738              : 
     739          990 :                         LLVMPositionBuilderAtEnd(b, b_nonull);
     740              :                     }
     741              : 
     742         1036 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
     743              :                                            &v_fcinfo_isnull);
     744         1036 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
     745         1036 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
     746              : 
     747         1036 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     748         1036 :                     break;
     749              :                 }
     750              : 
     751            0 :             case EEOP_FUNCEXPR_FUSAGE:
     752            0 :                 build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
     753              :                                 v_state, op, v_econtext);
     754            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
     755            0 :                 break;
     756              : 
     757              : 
     758            0 :             case EEOP_FUNCEXPR_STRICT_FUSAGE:
     759            0 :                 build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
     760              :                                 v_state, op, v_econtext);
     761            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
     762            0 :                 break;
     763              : 
     764              :                 /*
     765              :                  * Treat them the same for now, optimizer can remove
     766              :                  * redundancy. Could be worthwhile to optimize during emission
     767              :                  * though.
     768              :                  */
     769           20 :             case EEOP_BOOL_AND_STEP_FIRST:
     770              :             case EEOP_BOOL_AND_STEP:
     771              :             case EEOP_BOOL_AND_STEP_LAST:
     772              :                 {
     773              :                     LLVMValueRef v_boolvalue;
     774              :                     LLVMValueRef v_boolnull;
     775              :                     LLVMValueRef v_boolanynullp,
     776              :                                 v_boolanynull;
     777              :                     LLVMBasicBlockRef b_boolisnull;
     778              :                     LLVMBasicBlockRef b_boolcheckfalse;
     779              :                     LLVMBasicBlockRef b_boolisfalse;
     780              :                     LLVMBasicBlockRef b_boolcont;
     781              :                     LLVMBasicBlockRef b_boolisanynull;
     782              : 
     783           20 :                     b_boolisnull = l_bb_before_v(opblocks[opno + 1],
     784              :                                                  "b.%d.boolisnull", opno);
     785           20 :                     b_boolcheckfalse = l_bb_before_v(opblocks[opno + 1],
     786              :                                                      "b.%d.boolcheckfalse", opno);
     787           20 :                     b_boolisfalse = l_bb_before_v(opblocks[opno + 1],
     788              :                                                   "b.%d.boolisfalse", opno);
     789           20 :                     b_boolisanynull = l_bb_before_v(opblocks[opno + 1],
     790              :                                                     "b.%d.boolisanynull", opno);
     791           20 :                     b_boolcont = l_bb_before_v(opblocks[opno + 1],
     792              :                                                "b.%d.boolcont", opno);
     793              : 
     794           20 :                     v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
     795              :                                                  l_ptr(TypeStorageBool));
     796              : 
     797           20 :                     if (opcode == EEOP_BOOL_AND_STEP_FIRST)
     798           10 :                         LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
     799              : 
     800           20 :                     v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
     801           20 :                     v_boolvalue = l_load(b, TypeDatum, v_resvaluep, "");
     802              : 
     803              :                     /* check if current input is NULL */
     804           20 :                     LLVMBuildCondBr(b,
     805              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
     806              :                                                   l_sbool_const(1), ""),
     807              :                                     b_boolisnull,
     808              :                                     b_boolcheckfalse);
     809              : 
     810              :                     /* build block that sets anynull */
     811           20 :                     LLVMPositionBuilderAtEnd(b, b_boolisnull);
     812              :                     /* set boolanynull to true */
     813           20 :                     LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
     814              :                     /* and jump to next block */
     815           20 :                     LLVMBuildBr(b, b_boolcont);
     816              : 
     817              :                     /* build block checking for false */
     818           20 :                     LLVMPositionBuilderAtEnd(b, b_boolcheckfalse);
     819           20 :                     LLVMBuildCondBr(b,
     820              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
     821              :                                                   l_datum_const(0), ""),
     822              :                                     b_boolisfalse,
     823              :                                     b_boolcont);
     824              : 
     825              :                     /*
     826              :                      * Build block handling FALSE. Value is false, so short
     827              :                      * circuit.
     828              :                      */
     829           20 :                     LLVMPositionBuilderAtEnd(b, b_boolisfalse);
     830              :                     /* result is already set to FALSE, need not change it */
     831              :                     /* and jump to the end of the AND expression */
     832           20 :                     LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]);
     833              : 
     834              :                     /* Build block that continues if bool is TRUE. */
     835           20 :                     LLVMPositionBuilderAtEnd(b, b_boolcont);
     836              : 
     837           20 :                     v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
     838              : 
     839              :                     /* set value to NULL if any previous values were NULL */
     840           20 :                     LLVMBuildCondBr(b,
     841              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
     842              :                                                   l_sbool_const(0), ""),
     843           20 :                                     opblocks[opno + 1], b_boolisanynull);
     844              : 
     845           20 :                     LLVMPositionBuilderAtEnd(b, b_boolisanynull);
     846              :                     /* set resnull to true */
     847           20 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
     848              :                     /* reset resvalue */
     849           20 :                     LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
     850              : 
     851           20 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     852           20 :                     break;
     853              :                 }
     854              : 
     855              :                 /*
     856              :                  * Treat them the same for now, optimizer can remove
     857              :                  * redundancy. Could be worthwhile to optimize during emission
     858              :                  * though.
     859              :                  */
     860           38 :             case EEOP_BOOL_OR_STEP_FIRST:
     861              :             case EEOP_BOOL_OR_STEP:
     862              :             case EEOP_BOOL_OR_STEP_LAST:
     863              :                 {
     864              :                     LLVMValueRef v_boolvalue;
     865              :                     LLVMValueRef v_boolnull;
     866              :                     LLVMValueRef v_boolanynullp,
     867              :                                 v_boolanynull;
     868              : 
     869              :                     LLVMBasicBlockRef b_boolisnull;
     870              :                     LLVMBasicBlockRef b_boolchecktrue;
     871              :                     LLVMBasicBlockRef b_boolistrue;
     872              :                     LLVMBasicBlockRef b_boolcont;
     873              :                     LLVMBasicBlockRef b_boolisanynull;
     874              : 
     875           38 :                     b_boolisnull = l_bb_before_v(opblocks[opno + 1],
     876              :                                                  "b.%d.boolisnull", opno);
     877           38 :                     b_boolchecktrue = l_bb_before_v(opblocks[opno + 1],
     878              :                                                     "b.%d.boolchecktrue", opno);
     879           38 :                     b_boolistrue = l_bb_before_v(opblocks[opno + 1],
     880              :                                                  "b.%d.boolistrue", opno);
     881           38 :                     b_boolisanynull = l_bb_before_v(opblocks[opno + 1],
     882              :                                                     "b.%d.boolisanynull", opno);
     883           38 :                     b_boolcont = l_bb_before_v(opblocks[opno + 1],
     884              :                                                "b.%d.boolcont", opno);
     885              : 
     886           38 :                     v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
     887              :                                                  l_ptr(TypeStorageBool));
     888              : 
     889           38 :                     if (opcode == EEOP_BOOL_OR_STEP_FIRST)
     890           18 :                         LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
     891           38 :                     v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
     892           38 :                     v_boolvalue = l_load(b, TypeDatum, v_resvaluep, "");
     893              : 
     894           38 :                     LLVMBuildCondBr(b,
     895              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
     896              :                                                   l_sbool_const(1), ""),
     897              :                                     b_boolisnull,
     898              :                                     b_boolchecktrue);
     899              : 
     900              :                     /* build block that sets anynull */
     901           38 :                     LLVMPositionBuilderAtEnd(b, b_boolisnull);
     902              :                     /* set boolanynull to true */
     903           38 :                     LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
     904              :                     /* and jump to next block */
     905           38 :                     LLVMBuildBr(b, b_boolcont);
     906              : 
     907              :                     /* build block checking for true */
     908           38 :                     LLVMPositionBuilderAtEnd(b, b_boolchecktrue);
     909           38 :                     LLVMBuildCondBr(b,
     910              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
     911              :                                                   l_datum_const(1), ""),
     912              :                                     b_boolistrue,
     913              :                                     b_boolcont);
     914              : 
     915              :                     /*
     916              :                      * Build block handling True. Value is true, so short
     917              :                      * circuit.
     918              :                      */
     919           38 :                     LLVMPositionBuilderAtEnd(b, b_boolistrue);
     920              :                     /* result is already set to TRUE, need not change it */
     921              :                     /* and jump to the end of the OR expression */
     922           38 :                     LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]);
     923              : 
     924              :                     /* build block that continues if bool is FALSE */
     925           38 :                     LLVMPositionBuilderAtEnd(b, b_boolcont);
     926              : 
     927           38 :                     v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
     928              : 
     929              :                     /* set value to NULL if any previous values were NULL */
     930           38 :                     LLVMBuildCondBr(b,
     931              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
     932              :                                                   l_sbool_const(0), ""),
     933           38 :                                     opblocks[opno + 1], b_boolisanynull);
     934              : 
     935           38 :                     LLVMPositionBuilderAtEnd(b, b_boolisanynull);
     936              :                     /* set resnull to true */
     937           38 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
     938              :                     /* reset resvalue */
     939           38 :                     LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
     940              : 
     941           38 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     942           38 :                     break;
     943              :                 }
     944              : 
     945           12 :             case EEOP_BOOL_NOT_STEP:
     946              :                 {
     947              :                     LLVMValueRef v_boolvalue;
     948              :                     LLVMValueRef v_negbool;
     949              : 
     950              :                     /* compute !boolvalue */
     951           12 :                     v_boolvalue = l_load(b, TypeDatum, v_resvaluep, "");
     952           12 :                     v_negbool = LLVMBuildZExt(b,
     953              :                                               LLVMBuildICmp(b, LLVMIntEQ,
     954              :                                                             v_boolvalue,
     955              :                                                             l_datum_const(0),
     956              :                                                             ""),
     957              :                                               TypeDatum, "");
     958              : 
     959              :                     /*
     960              :                      * Store it back in resvalue.  We can ignore resnull here;
     961              :                      * if it was true, it stays true, and the value we store
     962              :                      * in resvalue doesn't matter.
     963              :                      */
     964           12 :                     LLVMBuildStore(b, v_negbool, v_resvaluep);
     965              : 
     966           12 :                     LLVMBuildBr(b, opblocks[opno + 1]);
     967           12 :                     break;
     968              :                 }
     969              : 
     970         1221 :             case EEOP_QUAL:
     971              :                 {
     972              :                     LLVMValueRef v_resnull;
     973              :                     LLVMValueRef v_resvalue;
     974              :                     LLVMValueRef v_nullorfalse;
     975              :                     LLVMBasicBlockRef b_qualfail;
     976              : 
     977         1221 :                     b_qualfail = l_bb_before_v(opblocks[opno + 1],
     978              :                                                "op.%d.qualfail", opno);
     979              : 
     980         1221 :                     v_resvalue = l_load(b, TypeDatum, v_resvaluep, "");
     981         1221 :                     v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
     982              : 
     983              :                     v_nullorfalse =
     984         1221 :                         LLVMBuildOr(b,
     985              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
     986              :                                                   l_sbool_const(1), ""),
     987              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
     988              :                                                   l_datum_const(0), ""),
     989              :                                     "");
     990              : 
     991         1221 :                     LLVMBuildCondBr(b,
     992              :                                     v_nullorfalse,
     993              :                                     b_qualfail,
     994         1221 :                                     opblocks[opno + 1]);
     995              : 
     996              :                     /* build block handling NULL or false */
     997         1221 :                     LLVMPositionBuilderAtEnd(b, b_qualfail);
     998              :                     /* set resnull to false */
     999         1221 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1000              :                     /* set resvalue to false */
    1001         1221 :                     LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    1002              :                     /* and jump out */
    1003         1221 :                     LLVMBuildBr(b, opblocks[op->d.qualexpr.jumpdone]);
    1004         1221 :                     break;
    1005              :                 }
    1006              : 
    1007           21 :             case EEOP_JUMP:
    1008              :                 {
    1009           21 :                     LLVMBuildBr(b, opblocks[op->d.jump.jumpdone]);
    1010           21 :                     break;
    1011              :                 }
    1012              : 
    1013           15 :             case EEOP_JUMP_IF_NULL:
    1014              :                 {
    1015              :                     LLVMValueRef v_resnull;
    1016              : 
    1017              :                     /* Transfer control if current result is null */
    1018              : 
    1019           15 :                     v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1020              : 
    1021           15 :                     LLVMBuildCondBr(b,
    1022              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1023              :                                                   l_sbool_const(1), ""),
    1024           15 :                                     opblocks[op->d.jump.jumpdone],
    1025           15 :                                     opblocks[opno + 1]);
    1026           15 :                     break;
    1027              :                 }
    1028              : 
    1029           44 :             case EEOP_JUMP_IF_NOT_NULL:
    1030              :                 {
    1031              :                     LLVMValueRef v_resnull;
    1032              : 
    1033              :                     /* Transfer control if current result is non-null */
    1034              : 
    1035           44 :                     v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1036              : 
    1037           44 :                     LLVMBuildCondBr(b,
    1038              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1039              :                                                   l_sbool_const(0), ""),
    1040           44 :                                     opblocks[op->d.jump.jumpdone],
    1041           44 :                                     opblocks[opno + 1]);
    1042           44 :                     break;
    1043              :                 }
    1044              : 
    1045              : 
    1046           21 :             case EEOP_JUMP_IF_NOT_TRUE:
    1047              :                 {
    1048              :                     LLVMValueRef v_resnull;
    1049              :                     LLVMValueRef v_resvalue;
    1050              :                     LLVMValueRef v_nullorfalse;
    1051              : 
    1052              :                     /* Transfer control if current result is null or false */
    1053              : 
    1054           21 :                     v_resvalue = l_load(b, TypeDatum, v_resvaluep, "");
    1055           21 :                     v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1056              : 
    1057              :                     v_nullorfalse =
    1058           21 :                         LLVMBuildOr(b,
    1059              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1060              :                                                   l_sbool_const(1), ""),
    1061              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
    1062              :                                                   l_datum_const(0), ""),
    1063              :                                     "");
    1064              : 
    1065           21 :                     LLVMBuildCondBr(b,
    1066              :                                     v_nullorfalse,
    1067           21 :                                     opblocks[op->d.jump.jumpdone],
    1068           21 :                                     opblocks[opno + 1]);
    1069           21 :                     break;
    1070              :                 }
    1071              : 
    1072           17 :             case EEOP_NULLTEST_ISNULL:
    1073              :                 {
    1074           17 :                     LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1075              :                     LLVMValueRef v_resvalue;
    1076              : 
    1077              :                     v_resvalue =
    1078           17 :                         LLVMBuildSelect(b,
    1079              :                                         LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1080              :                                                       l_sbool_const(1), ""),
    1081              :                                         l_datum_const(1),
    1082              :                                         l_datum_const(0),
    1083              :                                         "");
    1084           17 :                     LLVMBuildStore(b, v_resvalue, v_resvaluep);
    1085           17 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1086              : 
    1087           17 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1088           17 :                     break;
    1089              :                 }
    1090              : 
    1091           15 :             case EEOP_NULLTEST_ISNOTNULL:
    1092              :                 {
    1093           15 :                     LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1094              :                     LLVMValueRef v_resvalue;
    1095              : 
    1096              :                     v_resvalue =
    1097           15 :                         LLVMBuildSelect(b,
    1098              :                                         LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1099              :                                                       l_sbool_const(1), ""),
    1100              :                                         l_datum_const(0),
    1101              :                                         l_datum_const(1),
    1102              :                                         "");
    1103           15 :                     LLVMBuildStore(b, v_resvalue, v_resvaluep);
    1104           15 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1105              : 
    1106           15 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1107           15 :                     break;
    1108              :                 }
    1109              : 
    1110            0 :             case EEOP_NULLTEST_ROWISNULL:
    1111            0 :                 build_EvalXFunc(b, mod, "ExecEvalRowNull",
    1112              :                                 v_state, op, v_econtext);
    1113            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1114            0 :                 break;
    1115              : 
    1116            0 :             case EEOP_NULLTEST_ROWISNOTNULL:
    1117            0 :                 build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
    1118              :                                 v_state, op, v_econtext);
    1119            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1120            0 :                 break;
    1121              : 
    1122            0 :             case EEOP_BOOLTEST_IS_TRUE:
    1123              :             case EEOP_BOOLTEST_IS_NOT_FALSE:
    1124              :             case EEOP_BOOLTEST_IS_FALSE:
    1125              :             case EEOP_BOOLTEST_IS_NOT_TRUE:
    1126              :                 {
    1127              :                     LLVMBasicBlockRef b_isnull,
    1128              :                                 b_notnull;
    1129            0 :                     LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1130              : 
    1131            0 :                     b_isnull = l_bb_before_v(opblocks[opno + 1],
    1132              :                                              "op.%d.isnull", opno);
    1133            0 :                     b_notnull = l_bb_before_v(opblocks[opno + 1],
    1134              :                                               "op.%d.isnotnull", opno);
    1135              : 
    1136              :                     /* check if value is NULL */
    1137            0 :                     LLVMBuildCondBr(b,
    1138              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1139              :                                                   l_sbool_const(1), ""),
    1140              :                                     b_isnull, b_notnull);
    1141              : 
    1142              :                     /* if value is NULL, return false */
    1143            0 :                     LLVMPositionBuilderAtEnd(b, b_isnull);
    1144              : 
    1145              :                     /* result is not null */
    1146            0 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1147              : 
    1148            0 :                     if (opcode == EEOP_BOOLTEST_IS_TRUE ||
    1149              :                         opcode == EEOP_BOOLTEST_IS_FALSE)
    1150              :                     {
    1151            0 :                         LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    1152              :                     }
    1153              :                     else
    1154              :                     {
    1155            0 :                         LLVMBuildStore(b, l_datum_const(1), v_resvaluep);
    1156              :                     }
    1157              : 
    1158            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1159              : 
    1160            0 :                     LLVMPositionBuilderAtEnd(b, b_notnull);
    1161              : 
    1162            0 :                     if (opcode == EEOP_BOOLTEST_IS_TRUE ||
    1163              :                         opcode == EEOP_BOOLTEST_IS_NOT_FALSE)
    1164              :                     {
    1165              :                         /*
    1166              :                          * if value is not null NULL, return value (already
    1167              :                          * set)
    1168              :                          */
    1169              :                     }
    1170              :                     else
    1171              :                     {
    1172              :                         LLVMValueRef v_value =
    1173            0 :                             l_load(b, TypeDatum, v_resvaluep, "");
    1174              : 
    1175            0 :                         v_value = LLVMBuildZExt(b,
    1176              :                                                 LLVMBuildICmp(b, LLVMIntEQ,
    1177              :                                                               v_value,
    1178              :                                                               l_datum_const(0),
    1179              :                                                               ""),
    1180              :                                                 TypeDatum, "");
    1181            0 :                         LLVMBuildStore(b, v_value, v_resvaluep);
    1182              :                     }
    1183            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1184            0 :                     break;
    1185              :                 }
    1186              : 
    1187          709 :             case EEOP_PARAM_EXEC:
    1188          709 :                 build_EvalXFunc(b, mod, "ExecEvalParamExec",
    1189              :                                 v_state, op, v_econtext);
    1190          709 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1191          709 :                 break;
    1192              : 
    1193            0 :             case EEOP_PARAM_EXTERN:
    1194            0 :                 build_EvalXFunc(b, mod, "ExecEvalParamExtern",
    1195              :                                 v_state, op, v_econtext);
    1196            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1197            0 :                 break;
    1198              : 
    1199            0 :             case EEOP_PARAM_CALLBACK:
    1200              :                 {
    1201              :                     LLVMValueRef v_func;
    1202              :                     LLVMValueRef v_params[3];
    1203              : 
    1204            0 :                     v_func = l_ptr_const(op->d.cparam.paramfunc,
    1205              :                                          llvm_pg_var_type("TypeExecEvalSubroutine"));
    1206              : 
    1207            0 :                     v_params[0] = v_state;
    1208            0 :                     v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
    1209            0 :                     v_params[2] = v_econtext;
    1210            0 :                     l_call(b,
    1211              :                            LLVMGetFunctionType(ExecEvalSubroutineTemplate),
    1212              :                            v_func,
    1213              :                            v_params, lengthof(v_params), "");
    1214              : 
    1215            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1216            0 :                     break;
    1217              :                 }
    1218              : 
    1219          329 :             case EEOP_PARAM_SET:
    1220          329 :                 build_EvalXFunc(b, mod, "ExecEvalParamSet",
    1221              :                                 v_state, op, v_econtext);
    1222          329 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1223          329 :                 break;
    1224              : 
    1225           15 :             case EEOP_SBSREF_SUBSCRIPTS:
    1226              :                 {
    1227           15 :                     int         jumpdone = op->d.sbsref_subscript.jumpdone;
    1228              :                     LLVMValueRef v_func;
    1229              :                     LLVMValueRef v_params[3];
    1230              :                     LLVMValueRef v_ret;
    1231              : 
    1232           15 :                     v_func = l_ptr_const(op->d.sbsref_subscript.subscriptfunc,
    1233              :                                          llvm_pg_var_type("TypeExecEvalBoolSubroutine"));
    1234              : 
    1235           15 :                     v_params[0] = v_state;
    1236           15 :                     v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
    1237           15 :                     v_params[2] = v_econtext;
    1238           15 :                     v_ret = l_call(b,
    1239              :                                    LLVMGetFunctionType(ExecEvalBoolSubroutineTemplate),
    1240              :                                    v_func,
    1241              :                                    v_params, lengthof(v_params), "");
    1242           15 :                     v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
    1243              : 
    1244           15 :                     LLVMBuildCondBr(b,
    1245              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_ret,
    1246              :                                                   l_sbool_const(1), ""),
    1247           15 :                                     opblocks[opno + 1],
    1248           15 :                                     opblocks[jumpdone]);
    1249           15 :                     break;
    1250              :                 }
    1251              : 
    1252           15 :             case EEOP_SBSREF_OLD:
    1253              :             case EEOP_SBSREF_ASSIGN:
    1254              :             case EEOP_SBSREF_FETCH:
    1255              :                 {
    1256              :                     LLVMValueRef v_func;
    1257              :                     LLVMValueRef v_params[3];
    1258              : 
    1259           15 :                     v_func = l_ptr_const(op->d.sbsref.subscriptfunc,
    1260              :                                          llvm_pg_var_type("TypeExecEvalSubroutine"));
    1261              : 
    1262           15 :                     v_params[0] = v_state;
    1263           15 :                     v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
    1264           15 :                     v_params[2] = v_econtext;
    1265           15 :                     l_call(b,
    1266              :                            LLVMGetFunctionType(ExecEvalSubroutineTemplate),
    1267              :                            v_func,
    1268              :                            v_params, lengthof(v_params), "");
    1269              : 
    1270           15 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1271           15 :                     break;
    1272              :                 }
    1273              : 
    1274            9 :             case EEOP_CASE_TESTVAL:
    1275              :                 {
    1276              :                     LLVMValueRef v_casevaluep,
    1277              :                                 v_casevalue;
    1278              :                     LLVMValueRef v_casenullp,
    1279              :                                 v_casenull;
    1280              : 
    1281            9 :                     v_casevaluep = l_ptr_const(op->d.casetest.value,
    1282              :                                                l_ptr(TypeDatum));
    1283            9 :                     v_casenullp = l_ptr_const(op->d.casetest.isnull,
    1284              :                                               l_ptr(TypeStorageBool));
    1285              : 
    1286            9 :                     v_casevalue = l_load(b, TypeDatum, v_casevaluep, "");
    1287            9 :                     v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
    1288            9 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1289            9 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1290              : 
    1291            9 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1292            9 :                     break;
    1293              :                 }
    1294              : 
    1295            0 :             case EEOP_CASE_TESTVAL_EXT:
    1296              :                 {
    1297              :                     LLVMValueRef v_casevalue;
    1298              :                     LLVMValueRef v_casenull;
    1299              : 
    1300              :                     v_casevalue =
    1301            0 :                         l_load_struct_gep(b,
    1302              :                                           StructExprContext,
    1303              :                                           v_econtext,
    1304              :                                           FIELDNO_EXPRCONTEXT_CASEDATUM, "");
    1305              :                     v_casenull =
    1306            0 :                         l_load_struct_gep(b,
    1307              :                                           StructExprContext,
    1308              :                                           v_econtext,
    1309              :                                           FIELDNO_EXPRCONTEXT_CASENULL, "");
    1310            0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1311            0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1312              : 
    1313            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1314            0 :                     break;
    1315              :                 }
    1316              : 
    1317            0 :             case EEOP_MAKE_READONLY:
    1318              :                 {
    1319              :                     LLVMBasicBlockRef b_notnull;
    1320              :                     LLVMValueRef v_params[1];
    1321              :                     LLVMValueRef v_ret;
    1322              :                     LLVMValueRef v_nullp;
    1323              :                     LLVMValueRef v_valuep;
    1324              :                     LLVMValueRef v_null;
    1325              :                     LLVMValueRef v_value;
    1326              : 
    1327            0 :                     b_notnull = l_bb_before_v(opblocks[opno + 1],
    1328              :                                               "op.%d.readonly.notnull", opno);
    1329              : 
    1330            0 :                     v_nullp = l_ptr_const(op->d.make_readonly.isnull,
    1331              :                                           l_ptr(TypeStorageBool));
    1332              : 
    1333            0 :                     v_null = l_load(b, TypeStorageBool, v_nullp, "");
    1334              : 
    1335              :                     /* store null isnull value in result */
    1336            0 :                     LLVMBuildStore(b, v_null, v_resnullp);
    1337              : 
    1338              :                     /* check if value is NULL */
    1339            0 :                     LLVMBuildCondBr(b,
    1340              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_null,
    1341              :                                                   l_sbool_const(1), ""),
    1342            0 :                                     opblocks[opno + 1], b_notnull);
    1343              : 
    1344              :                     /* if value is not null, convert to RO datum */
    1345            0 :                     LLVMPositionBuilderAtEnd(b, b_notnull);
    1346              : 
    1347            0 :                     v_valuep = l_ptr_const(op->d.make_readonly.value,
    1348              :                                            l_ptr(TypeDatum));
    1349              : 
    1350            0 :                     v_value = l_load(b, TypeDatum, v_valuep, "");
    1351              : 
    1352            0 :                     v_params[0] = v_value;
    1353              :                     v_ret =
    1354            0 :                         l_call(b,
    1355              :                                llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
    1356              :                                llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
    1357              :                                v_params, lengthof(v_params), "");
    1358            0 :                     LLVMBuildStore(b, v_ret, v_resvaluep);
    1359              : 
    1360            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1361            0 :                     break;
    1362              :                 }
    1363              : 
    1364           60 :             case EEOP_IOCOERCE:
    1365              :                 {
    1366              :                     FunctionCallInfo fcinfo_out,
    1367              :                                 fcinfo_in;
    1368              :                     LLVMValueRef v_fn_out,
    1369              :                                 v_fn_in;
    1370              :                     LLVMValueRef v_fcinfo_out,
    1371              :                                 v_fcinfo_in;
    1372              :                     LLVMValueRef v_fcinfo_in_isnullp;
    1373              :                     LLVMValueRef v_retval;
    1374              :                     LLVMValueRef v_resvalue;
    1375              :                     LLVMValueRef v_resnull;
    1376              : 
    1377              :                     LLVMValueRef v_output_skip;
    1378              :                     LLVMValueRef v_output;
    1379              : 
    1380              :                     LLVMBasicBlockRef b_skipoutput;
    1381              :                     LLVMBasicBlockRef b_calloutput;
    1382              :                     LLVMBasicBlockRef b_input;
    1383              :                     LLVMBasicBlockRef b_inputcall;
    1384              : 
    1385           60 :                     fcinfo_out = op->d.iocoerce.fcinfo_data_out;
    1386           60 :                     fcinfo_in = op->d.iocoerce.fcinfo_data_in;
    1387              : 
    1388           60 :                     b_skipoutput = l_bb_before_v(opblocks[opno + 1],
    1389              :                                                  "op.%d.skipoutputnull", opno);
    1390           60 :                     b_calloutput = l_bb_before_v(opblocks[opno + 1],
    1391              :                                                  "op.%d.calloutput", opno);
    1392           60 :                     b_input = l_bb_before_v(opblocks[opno + 1],
    1393              :                                             "op.%d.input", opno);
    1394           60 :                     b_inputcall = l_bb_before_v(opblocks[opno + 1],
    1395              :                                                 "op.%d.inputcall", opno);
    1396              : 
    1397           60 :                     v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out);
    1398           60 :                     v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in);
    1399           60 :                     v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
    1400           60 :                     v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
    1401              : 
    1402              :                     v_fcinfo_in_isnullp =
    1403           60 :                         l_struct_gep(b,
    1404              :                                      StructFunctionCallInfoData,
    1405              :                                      v_fcinfo_in,
    1406              :                                      FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
    1407              :                                      "v_fcinfo_in_isnull");
    1408              : 
    1409              :                     /* output functions are not called on nulls */
    1410           60 :                     v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
    1411           60 :                     LLVMBuildCondBr(b,
    1412              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
    1413              :                                                   l_sbool_const(1), ""),
    1414              :                                     b_skipoutput,
    1415              :                                     b_calloutput);
    1416              : 
    1417           60 :                     LLVMPositionBuilderAtEnd(b, b_skipoutput);
    1418           60 :                     v_output_skip = l_datum_const(0);
    1419           60 :                     LLVMBuildBr(b, b_input);
    1420              : 
    1421           60 :                     LLVMPositionBuilderAtEnd(b, b_calloutput);
    1422           60 :                     v_resvalue = l_load(b, TypeDatum, v_resvaluep, "");
    1423              : 
    1424              :                     /* set arg[0] */
    1425           60 :                     LLVMBuildStore(b,
    1426              :                                    v_resvalue,
    1427              :                                    l_funcvaluep(b, v_fcinfo_out, 0));
    1428           60 :                     LLVMBuildStore(b,
    1429              :                                    l_sbool_const(0),
    1430              :                                    l_funcnullp(b, v_fcinfo_out, 0));
    1431              :                     /* and call output function (can never return NULL) */
    1432           60 :                     v_output = l_call(b,
    1433              :                                       LLVMGetFunctionType(v_fn_out),
    1434              :                                       v_fn_out, &v_fcinfo_out,
    1435              :                                       1, "funccall_coerce_out");
    1436           60 :                     LLVMBuildBr(b, b_input);
    1437              : 
    1438              :                     /* build block handling input function call */
    1439           60 :                     LLVMPositionBuilderAtEnd(b, b_input);
    1440              : 
    1441              :                     /* phi between resnull and output function call branches */
    1442              :                     {
    1443              :                         LLVMValueRef incoming_values[2];
    1444              :                         LLVMBasicBlockRef incoming_blocks[2];
    1445              : 
    1446           60 :                         incoming_values[0] = v_output_skip;
    1447           60 :                         incoming_blocks[0] = b_skipoutput;
    1448              : 
    1449           60 :                         incoming_values[1] = v_output;
    1450           60 :                         incoming_blocks[1] = b_calloutput;
    1451              : 
    1452           60 :                         v_output = LLVMBuildPhi(b, TypeDatum, "output");
    1453           60 :                         LLVMAddIncoming(v_output,
    1454              :                                         incoming_values, incoming_blocks,
    1455              :                                         lengthof(incoming_blocks));
    1456              :                     }
    1457              : 
    1458              :                     /*
    1459              :                      * If input function is strict, skip if input string is
    1460              :                      * NULL.
    1461              :                      */
    1462           60 :                     if (op->d.iocoerce.finfo_in->fn_strict)
    1463              :                     {
    1464           60 :                         LLVMBuildCondBr(b,
    1465              :                                         LLVMBuildICmp(b, LLVMIntEQ, v_output,
    1466              :                                                       l_datum_const(0), ""),
    1467           60 :                                         opblocks[opno + 1],
    1468              :                                         b_inputcall);
    1469              :                     }
    1470              :                     else
    1471              :                     {
    1472            0 :                         LLVMBuildBr(b, b_inputcall);
    1473              :                     }
    1474              : 
    1475           60 :                     LLVMPositionBuilderAtEnd(b, b_inputcall);
    1476              :                     /* set arguments */
    1477              :                     /* arg0: output */
    1478           60 :                     LLVMBuildStore(b, v_output,
    1479              :                                    l_funcvaluep(b, v_fcinfo_in, 0));
    1480           60 :                     LLVMBuildStore(b, v_resnull,
    1481              :                                    l_funcnullp(b, v_fcinfo_in, 0));
    1482              : 
    1483              :                     /* arg1: ioparam: preset in execExpr.c */
    1484              :                     /* arg2: typmod: preset in execExpr.c  */
    1485              : 
    1486              :                     /* reset fcinfo_in->isnull */
    1487           60 :                     LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
    1488              :                     /* and call function */
    1489           60 :                     v_retval = l_call(b,
    1490              :                                       LLVMGetFunctionType(v_fn_in),
    1491              :                                       v_fn_in, &v_fcinfo_in, 1,
    1492              :                                       "funccall_iocoerce_in");
    1493              : 
    1494           60 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    1495              : 
    1496           60 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1497           60 :                     break;
    1498              :                 }
    1499              : 
    1500            0 :             case EEOP_IOCOERCE_SAFE:
    1501            0 :                 build_EvalXFunc(b, mod, "ExecEvalCoerceViaIOSafe",
    1502              :                                 v_state, op);
    1503            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1504            0 :                 break;
    1505              : 
    1506          480 :             case EEOP_DISTINCT:
    1507              :             case EEOP_NOT_DISTINCT:
    1508              :                 {
    1509          480 :                     FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
    1510              : 
    1511              :                     LLVMValueRef v_fcinfo;
    1512              :                     LLVMValueRef v_fcinfo_isnull;
    1513              : 
    1514              :                     LLVMValueRef v_argnull0,
    1515              :                                 v_argisnull0;
    1516              :                     LLVMValueRef v_argnull1,
    1517              :                                 v_argisnull1;
    1518              : 
    1519              :                     LLVMValueRef v_anyargisnull;
    1520              :                     LLVMValueRef v_bothargisnull;
    1521              : 
    1522              :                     LLVMValueRef v_result;
    1523              : 
    1524              :                     LLVMBasicBlockRef b_noargnull;
    1525              :                     LLVMBasicBlockRef b_checkbothargnull;
    1526              :                     LLVMBasicBlockRef b_bothargnull;
    1527              :                     LLVMBasicBlockRef b_anyargnull;
    1528              : 
    1529          480 :                     b_noargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.noargnull", opno);
    1530          480 :                     b_checkbothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.checkbothargnull", opno);
    1531          480 :                     b_bothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.bothargnull", opno);
    1532          480 :                     b_anyargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.anyargnull", opno);
    1533              : 
    1534          480 :                     v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
    1535              : 
    1536              :                     /* load args[0|1].isnull for both arguments */
    1537          480 :                     v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1538          480 :                     v_argisnull0 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
    1539              :                                                  l_sbool_const(1), "");
    1540          480 :                     v_argnull1 = l_funcnull(b, v_fcinfo, 1);
    1541          480 :                     v_argisnull1 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
    1542              :                                                  l_sbool_const(1), "");
    1543              : 
    1544          480 :                     v_anyargisnull = LLVMBuildOr(b, v_argisnull0, v_argisnull1, "");
    1545          480 :                     v_bothargisnull = LLVMBuildAnd(b, v_argisnull0, v_argisnull1, "");
    1546              : 
    1547              :                     /*
    1548              :                      * Check function arguments for NULLness: If either is
    1549              :                      * NULL, we check if both args are NULL. Otherwise call
    1550              :                      * comparator.
    1551              :                      */
    1552          480 :                     LLVMBuildCondBr(b, v_anyargisnull, b_checkbothargnull,
    1553              :                                     b_noargnull);
    1554              : 
    1555              :                     /*
    1556              :                      * build block checking if any arg is null
    1557              :                      */
    1558          480 :                     LLVMPositionBuilderAtEnd(b, b_checkbothargnull);
    1559          480 :                     LLVMBuildCondBr(b, v_bothargisnull, b_bothargnull,
    1560              :                                     b_anyargnull);
    1561              : 
    1562              : 
    1563              :                     /* Both NULL? Then is not distinct... */
    1564          480 :                     LLVMPositionBuilderAtEnd(b, b_bothargnull);
    1565          480 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1566          480 :                     if (opcode == EEOP_NOT_DISTINCT)
    1567          480 :                         LLVMBuildStore(b, l_datum_const(1), v_resvaluep);
    1568              :                     else
    1569            0 :                         LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    1570              : 
    1571          480 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1572              : 
    1573              :                     /* Only one is NULL? Then is distinct... */
    1574          480 :                     LLVMPositionBuilderAtEnd(b, b_anyargnull);
    1575          480 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1576          480 :                     if (opcode == EEOP_NOT_DISTINCT)
    1577          480 :                         LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    1578              :                     else
    1579            0 :                         LLVMBuildStore(b, l_datum_const(1), v_resvaluep);
    1580          480 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1581              : 
    1582              :                     /* neither argument is null: compare */
    1583          480 :                     LLVMPositionBuilderAtEnd(b, b_noargnull);
    1584              : 
    1585          480 :                     v_result = BuildV1Call(context, b, mod, fcinfo,
    1586              :                                            &v_fcinfo_isnull);
    1587              : 
    1588          480 :                     if (opcode == EEOP_DISTINCT)
    1589              :                     {
    1590              :                         /* Must invert result of "=" */
    1591              :                         v_result =
    1592            0 :                             LLVMBuildZExt(b,
    1593              :                                           LLVMBuildICmp(b, LLVMIntEQ,
    1594              :                                                         v_result,
    1595              :                                                         l_datum_const(0), ""),
    1596              :                                           TypeDatum, "");
    1597              :                     }
    1598              : 
    1599          480 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
    1600          480 :                     LLVMBuildStore(b, v_result, v_resvaluep);
    1601              : 
    1602          480 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1603          480 :                     break;
    1604              :                 }
    1605              : 
    1606            0 :             case EEOP_NULLIF:
    1607              :                 {
    1608            0 :                     FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
    1609              : 
    1610              :                     LLVMValueRef v_fcinfo;
    1611              :                     LLVMValueRef v_fcinfo_isnull;
    1612              :                     LLVMValueRef v_argnull0;
    1613              :                     LLVMValueRef v_argnull1;
    1614              :                     LLVMValueRef v_anyargisnull;
    1615              :                     LLVMValueRef v_arg0;
    1616              :                     LLVMBasicBlockRef b_hasnull;
    1617              :                     LLVMBasicBlockRef b_nonull;
    1618              :                     LLVMBasicBlockRef b_argsequal;
    1619              :                     LLVMValueRef v_retval;
    1620              :                     LLVMValueRef v_argsequal;
    1621              : 
    1622            0 :                     b_hasnull = l_bb_before_v(opblocks[opno + 1],
    1623              :                                               "b.%d.null-args", opno);
    1624            0 :                     b_nonull = l_bb_before_v(opblocks[opno + 1],
    1625              :                                              "b.%d.no-null-args", opno);
    1626            0 :                     b_argsequal = l_bb_before_v(opblocks[opno + 1],
    1627              :                                                 "b.%d.argsequal", opno);
    1628              : 
    1629            0 :                     v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
    1630              : 
    1631              :                     /* save original arg[0] */
    1632            0 :                     v_arg0 = l_funcvalue(b, v_fcinfo, 0);
    1633              : 
    1634              :                     /* if either argument is NULL they can't be equal */
    1635            0 :                     v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1636            0 :                     v_argnull1 = l_funcnull(b, v_fcinfo, 1);
    1637              : 
    1638              :                     v_anyargisnull =
    1639            0 :                         LLVMBuildOr(b,
    1640              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
    1641              :                                                   l_sbool_const(1), ""),
    1642              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
    1643              :                                                   l_sbool_const(1), ""),
    1644              :                                     "");
    1645              : 
    1646            0 :                     LLVMBuildCondBr(b, v_anyargisnull, b_hasnull, b_nonull);
    1647              : 
    1648              :                     /* one (or both) of the arguments are null, return arg[0] */
    1649            0 :                     LLVMPositionBuilderAtEnd(b, b_hasnull);
    1650            0 :                     LLVMBuildStore(b, v_argnull0, v_resnullp);
    1651            0 :                     LLVMBuildStore(b, v_arg0, v_resvaluep);
    1652            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1653              : 
    1654              :                     /* build block to invoke function and check result */
    1655            0 :                     LLVMPositionBuilderAtEnd(b, b_nonull);
    1656              : 
    1657              :                     /*
    1658              :                      * If first argument is of varlena type, it might be an
    1659              :                      * expanded datum.  We need to ensure that the value
    1660              :                      * passed to the comparison function is a read-only
    1661              :                      * pointer.  However, if we end by returning the first
    1662              :                      * argument, that will be the original read-write pointer
    1663              :                      * if it was read-write.
    1664              :                      */
    1665            0 :                     if (op->d.func.make_ro)
    1666              :                     {
    1667              :                         LLVMValueRef v_params[1];
    1668              :                         LLVMValueRef v_arg0_ro;
    1669              : 
    1670            0 :                         v_params[0] = v_arg0;
    1671              :                         v_arg0_ro =
    1672            0 :                             l_call(b,
    1673              :                                    llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
    1674              :                                    llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
    1675              :                                    v_params, lengthof(v_params), "");
    1676            0 :                         LLVMBuildStore(b, v_arg0_ro,
    1677              :                                        l_funcvaluep(b, v_fcinfo, 0));
    1678              :                     }
    1679              : 
    1680            0 :                     v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull);
    1681              : 
    1682              :                     /*
    1683              :                      * If result not null and arguments are equal return null,
    1684              :                      * else return arg[0] (same result as if there'd been
    1685              :                      * NULLs, hence reuse b_hasnull).
    1686              :                      */
    1687            0 :                     v_argsequal = LLVMBuildAnd(b,
    1688              :                                                LLVMBuildICmp(b, LLVMIntEQ,
    1689              :                                                              v_fcinfo_isnull,
    1690              :                                                              l_sbool_const(0),
    1691              :                                                              ""),
    1692              :                                                LLVMBuildICmp(b, LLVMIntEQ,
    1693              :                                                              v_retval,
    1694              :                                                              l_datum_const(1),
    1695              :                                                              ""),
    1696              :                                                "");
    1697            0 :                     LLVMBuildCondBr(b, v_argsequal, b_argsequal, b_hasnull);
    1698              : 
    1699              :                     /* build block setting result to NULL, if args are equal */
    1700            0 :                     LLVMPositionBuilderAtEnd(b, b_argsequal);
    1701            0 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
    1702            0 :                     LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    1703              : 
    1704            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1705            0 :                     break;
    1706              :                 }
    1707              : 
    1708            0 :             case EEOP_SQLVALUEFUNCTION:
    1709            0 :                 build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
    1710              :                                 v_state, op);
    1711            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1712            0 :                 break;
    1713              : 
    1714            0 :             case EEOP_CURRENTOFEXPR:
    1715            0 :                 build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
    1716              :                                 v_state, op);
    1717            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1718            0 :                 break;
    1719              : 
    1720            0 :             case EEOP_NEXTVALUEEXPR:
    1721            0 :                 build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
    1722              :                                 v_state, op);
    1723            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1724            0 :                 break;
    1725              : 
    1726           30 :             case EEOP_RETURNINGEXPR:
    1727              :                 {
    1728              :                     LLVMBasicBlockRef b_isnull;
    1729              :                     LLVMValueRef v_flagsp;
    1730              :                     LLVMValueRef v_flags;
    1731              :                     LLVMValueRef v_nullflag;
    1732              : 
    1733           30 :                     b_isnull = l_bb_before_v(opblocks[opno + 1],
    1734              :                                              "op.%d.row.isnull", opno);
    1735              : 
    1736              :                     /*
    1737              :                      * The next op actually evaluates the expression.  If the
    1738              :                      * OLD/NEW row doesn't exist, skip that and return NULL.
    1739              :                      */
    1740           30 :                     v_flagsp = l_struct_gep(b,
    1741              :                                             StructExprState,
    1742              :                                             v_state,
    1743              :                                             FIELDNO_EXPRSTATE_FLAGS,
    1744              :                                             "v.state.flags");
    1745           30 :                     v_flags = l_load(b, TypeStorageBool, v_flagsp, "");
    1746              : 
    1747           30 :                     v_nullflag = l_int8_const(lc, op->d.returningexpr.nullflag);
    1748              : 
    1749           30 :                     LLVMBuildCondBr(b,
    1750              :                                     LLVMBuildICmp(b, LLVMIntEQ,
    1751              :                                                   LLVMBuildAnd(b, v_flags,
    1752              :                                                                v_nullflag, ""),
    1753              :                                                   l_sbool_const(0), ""),
    1754           30 :                                     opblocks[opno + 1], b_isnull);
    1755              : 
    1756           30 :                     LLVMPositionBuilderAtEnd(b, b_isnull);
    1757              : 
    1758           30 :                     LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    1759           30 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
    1760              : 
    1761           30 :                     LLVMBuildBr(b, opblocks[op->d.returningexpr.jumpdone]);
    1762           30 :                     break;
    1763              :                 }
    1764              : 
    1765           41 :             case EEOP_ARRAYEXPR:
    1766           41 :                 build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
    1767              :                                 v_state, op);
    1768           41 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1769           41 :                 break;
    1770              : 
    1771           24 :             case EEOP_ARRAYCOERCE:
    1772           24 :                 build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
    1773              :                                 v_state, op, v_econtext);
    1774           24 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1775           24 :                 break;
    1776              : 
    1777           42 :             case EEOP_ROW:
    1778           42 :                 build_EvalXFunc(b, mod, "ExecEvalRow",
    1779              :                                 v_state, op);
    1780           42 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1781           42 :                 break;
    1782              : 
    1783            0 :             case EEOP_ROWCOMPARE_STEP:
    1784              :                 {
    1785            0 :                     FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data;
    1786              :                     LLVMValueRef v_fcinfo_isnull;
    1787              :                     LLVMBasicBlockRef b_null;
    1788              :                     LLVMBasicBlockRef b_compare;
    1789              :                     LLVMBasicBlockRef b_compare_result;
    1790              : 
    1791              :                     LLVMValueRef v_retval;
    1792              : 
    1793            0 :                     b_null = l_bb_before_v(opblocks[opno + 1],
    1794              :                                            "op.%d.row-null", opno);
    1795            0 :                     b_compare = l_bb_before_v(opblocks[opno + 1],
    1796              :                                               "op.%d.row-compare", opno);
    1797              :                     b_compare_result =
    1798            0 :                         l_bb_before_v(opblocks[opno + 1],
    1799              :                                       "op.%d.row-compare-result",
    1800              :                                       opno);
    1801              : 
    1802              :                     /*
    1803              :                      * If function is strict, and either arg is null, we're
    1804              :                      * done.
    1805              :                      */
    1806            0 :                     if (op->d.rowcompare_step.finfo->fn_strict)
    1807              :                     {
    1808              :                         LLVMValueRef v_fcinfo;
    1809              :                         LLVMValueRef v_argnull0;
    1810              :                         LLVMValueRef v_argnull1;
    1811              :                         LLVMValueRef v_anyargisnull;
    1812              : 
    1813            0 :                         v_fcinfo = l_ptr_const(fcinfo,
    1814              :                                                l_ptr(StructFunctionCallInfoData));
    1815              : 
    1816            0 :                         v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    1817            0 :                         v_argnull1 = l_funcnull(b, v_fcinfo, 1);
    1818              : 
    1819              :                         v_anyargisnull =
    1820            0 :                             LLVMBuildOr(b,
    1821              :                                         LLVMBuildICmp(b,
    1822              :                                                       LLVMIntEQ,
    1823              :                                                       v_argnull0,
    1824              :                                                       l_sbool_const(1),
    1825              :                                                       ""),
    1826              :                                         LLVMBuildICmp(b, LLVMIntEQ,
    1827              :                                                       v_argnull1,
    1828              :                                                       l_sbool_const(1), ""),
    1829              :                                         "");
    1830              : 
    1831            0 :                         LLVMBuildCondBr(b, v_anyargisnull, b_null, b_compare);
    1832              :                     }
    1833              :                     else
    1834              :                     {
    1835            0 :                         LLVMBuildBr(b, b_compare);
    1836              :                     }
    1837              : 
    1838              :                     /* build block invoking comparison function */
    1839            0 :                     LLVMPositionBuilderAtEnd(b, b_compare);
    1840              : 
    1841              :                     /* call function */
    1842            0 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    1843              :                                            &v_fcinfo_isnull);
    1844            0 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    1845              : 
    1846              :                     /* if result of function is NULL, force NULL result */
    1847            0 :                     LLVMBuildCondBr(b,
    1848              :                                     LLVMBuildICmp(b,
    1849              :                                                   LLVMIntEQ,
    1850              :                                                   v_fcinfo_isnull,
    1851              :                                                   l_sbool_const(0),
    1852              :                                                   ""),
    1853              :                                     b_compare_result,
    1854              :                                     b_null);
    1855              : 
    1856              :                     /* build block analyzing the !NULL comparator result */
    1857            0 :                     LLVMPositionBuilderAtEnd(b, b_compare_result);
    1858              : 
    1859              :                     /* if results equal, compare next, otherwise done */
    1860            0 :                     LLVMBuildCondBr(b,
    1861              :                                     LLVMBuildICmp(b,
    1862              :                                                   LLVMIntEQ,
    1863              :                                                   v_retval,
    1864              :                                                   l_datum_const(0), ""),
    1865            0 :                                     opblocks[opno + 1],
    1866            0 :                                     opblocks[op->d.rowcompare_step.jumpdone]);
    1867              : 
    1868              :                     /*
    1869              :                      * Build block handling NULL input or NULL comparator
    1870              :                      * result.
    1871              :                      */
    1872            0 :                     LLVMPositionBuilderAtEnd(b, b_null);
    1873            0 :                     LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
    1874            0 :                     LLVMBuildBr(b, opblocks[op->d.rowcompare_step.jumpnull]);
    1875              : 
    1876            0 :                     break;
    1877              :                 }
    1878              : 
    1879            0 :             case EEOP_ROWCOMPARE_FINAL:
    1880              :                 {
    1881            0 :                     CompareType cmptype = op->d.rowcompare_final.cmptype;
    1882              : 
    1883              :                     LLVMValueRef v_cmpresult;
    1884              :                     LLVMValueRef v_result;
    1885              :                     LLVMIntPredicate predicate;
    1886              : 
    1887              :                     /*
    1888              :                      * Btree comparators return 32 bit results, need to be
    1889              :                      * careful about sign (used as a 64 bit value it's
    1890              :                      * otherwise wrong).
    1891              :                      */
    1892              :                     v_cmpresult =
    1893            0 :                         LLVMBuildTrunc(b,
    1894              :                                        l_load(b, TypeDatum, v_resvaluep, ""),
    1895              :                                        LLVMInt32TypeInContext(lc), "");
    1896              : 
    1897            0 :                     switch (cmptype)
    1898              :                     {
    1899            0 :                         case COMPARE_LT:
    1900            0 :                             predicate = LLVMIntSLT;
    1901            0 :                             break;
    1902            0 :                         case COMPARE_LE:
    1903            0 :                             predicate = LLVMIntSLE;
    1904            0 :                             break;
    1905            0 :                         case COMPARE_GT:
    1906            0 :                             predicate = LLVMIntSGT;
    1907            0 :                             break;
    1908            0 :                         case COMPARE_GE:
    1909            0 :                             predicate = LLVMIntSGE;
    1910            0 :                             break;
    1911            0 :                         default:
    1912              :                             /* EQ and NE cases aren't allowed here */
    1913              :                             Assert(false);
    1914            0 :                             predicate = 0;  /* prevent compiler warning */
    1915            0 :                             break;
    1916              :                     }
    1917              : 
    1918            0 :                     v_result = LLVMBuildICmp(b,
    1919              :                                              predicate,
    1920              :                                              v_cmpresult,
    1921              :                                              l_int32_const(lc, 0),
    1922              :                                              "");
    1923            0 :                     v_result = LLVMBuildZExt(b, v_result, TypeDatum, "");
    1924              : 
    1925            0 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    1926            0 :                     LLVMBuildStore(b, v_result, v_resvaluep);
    1927              : 
    1928            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1929            0 :                     break;
    1930              :                 }
    1931              : 
    1932            0 :             case EEOP_MINMAX:
    1933            0 :                 build_EvalXFunc(b, mod, "ExecEvalMinMax",
    1934              :                                 v_state, op);
    1935            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1936            0 :                 break;
    1937              : 
    1938           57 :             case EEOP_FIELDSELECT:
    1939           57 :                 build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
    1940              :                                 v_state, op, v_econtext);
    1941           57 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1942           57 :                 break;
    1943              : 
    1944            0 :             case EEOP_FIELDSTORE_DEFORM:
    1945            0 :                 build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
    1946              :                                 v_state, op, v_econtext);
    1947            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1948            0 :                 break;
    1949              : 
    1950            0 :             case EEOP_FIELDSTORE_FORM:
    1951            0 :                 build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
    1952              :                                 v_state, op, v_econtext);
    1953            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    1954            0 :                 break;
    1955              : 
    1956            0 :             case EEOP_DOMAIN_TESTVAL:
    1957              :                 {
    1958              :                     LLVMValueRef v_casevaluep,
    1959              :                                 v_casevalue;
    1960              :                     LLVMValueRef v_casenullp,
    1961              :                                 v_casenull;
    1962              : 
    1963            0 :                     v_casevaluep = l_ptr_const(op->d.casetest.value,
    1964              :                                                l_ptr(TypeDatum));
    1965            0 :                     v_casenullp = l_ptr_const(op->d.casetest.isnull,
    1966              :                                               l_ptr(TypeStorageBool));
    1967              : 
    1968            0 :                     v_casevalue = l_load(b, TypeDatum, v_casevaluep, "");
    1969            0 :                     v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
    1970            0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1971            0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1972              : 
    1973            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1974            0 :                     break;
    1975              :                 }
    1976              : 
    1977            0 :             case EEOP_DOMAIN_TESTVAL_EXT:
    1978              :                 {
    1979              :                     LLVMValueRef v_casevalue;
    1980              :                     LLVMValueRef v_casenull;
    1981              : 
    1982              :                     v_casevalue =
    1983            0 :                         l_load_struct_gep(b,
    1984              :                                           StructExprContext,
    1985              :                                           v_econtext,
    1986              :                                           FIELDNO_EXPRCONTEXT_DOMAINDATUM,
    1987              :                                           "");
    1988              :                     v_casenull =
    1989            0 :                         l_load_struct_gep(b,
    1990              :                                           StructExprContext,
    1991              :                                           v_econtext,
    1992              :                                           FIELDNO_EXPRCONTEXT_DOMAINNULL,
    1993              :                                           "");
    1994            0 :                     LLVMBuildStore(b, v_casevalue, v_resvaluep);
    1995            0 :                     LLVMBuildStore(b, v_casenull, v_resnullp);
    1996              : 
    1997            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    1998            0 :                     break;
    1999              :                 }
    2000              : 
    2001            0 :             case EEOP_DOMAIN_NOTNULL:
    2002            0 :                 build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
    2003              :                                 v_state, op);
    2004            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2005            0 :                 break;
    2006              : 
    2007            0 :             case EEOP_DOMAIN_CHECK:
    2008            0 :                 build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
    2009              :                                 v_state, op);
    2010            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2011            0 :                 break;
    2012              : 
    2013            0 :             case EEOP_HASHDATUM_SET_INITVAL:
    2014              :                 {
    2015              :                     LLVMValueRef v_initvalue;
    2016              : 
    2017            0 :                     v_initvalue = l_datum_const(op->d.hashdatum_initvalue.init_value);
    2018              : 
    2019            0 :                     LLVMBuildStore(b, v_initvalue, v_resvaluep);
    2020            0 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    2021            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2022            0 :                     break;
    2023              :                 }
    2024              : 
    2025          374 :             case EEOP_HASHDATUM_FIRST:
    2026              :             case EEOP_HASHDATUM_FIRST_STRICT:
    2027              :             case EEOP_HASHDATUM_NEXT32:
    2028              :             case EEOP_HASHDATUM_NEXT32_STRICT:
    2029              :                 {
    2030          374 :                     FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data;
    2031              :                     LLVMValueRef v_fcinfo;
    2032              :                     LLVMValueRef v_fcinfo_isnull;
    2033              :                     LLVMValueRef v_retval;
    2034              :                     LLVMBasicBlockRef b_checkargnull;
    2035              :                     LLVMBasicBlockRef b_ifnotnull;
    2036              :                     LLVMBasicBlockRef b_ifnullblock;
    2037              :                     LLVMValueRef v_argisnull;
    2038          374 :                     LLVMValueRef v_prevhash = NULL;
    2039              : 
    2040              :                     /*
    2041              :                      * When performing the next hash and not in strict mode we
    2042              :                      * perform a rotation of the previously stored hash value
    2043              :                      * before doing the NULL check.  We want to do this even
    2044              :                      * when we receive a NULL Datum to hash.  In strict mode,
    2045              :                      * we do this after the NULL check so as not to waste the
    2046              :                      * effort of rotating the bits when we're going to throw
    2047              :                      * away the hash value and return NULL.
    2048              :                      */
    2049          374 :                     if (opcode == EEOP_HASHDATUM_NEXT32)
    2050              :                     {
    2051              :                         LLVMValueRef v_tmp1;
    2052              :                         LLVMValueRef v_tmp2;
    2053              :                         LLVMValueRef tmp;
    2054              : 
    2055          109 :                         tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
    2056              :                                           l_ptr(TypeDatum));
    2057              : 
    2058              :                         /*
    2059              :                          * Fetch the previously hashed value from where the
    2060              :                          * previous hash operation stored it.
    2061              :                          */
    2062          109 :                         v_prevhash = l_load(b, TypeDatum, tmp, "prevhash");
    2063              : 
    2064              :                         /*
    2065              :                          * Rotate bits left by 1 bit.  Be careful not to
    2066              :                          * overflow uint32 when working with Datum.
    2067              :                          */
    2068          109 :                         v_tmp1 = LLVMBuildShl(b, v_prevhash, l_datum_const(1),
    2069              :                                               "");
    2070          109 :                         v_tmp1 = LLVMBuildAnd(b, v_tmp1,
    2071              :                                               l_datum_const(0xffffffff), "");
    2072          109 :                         v_tmp2 = LLVMBuildLShr(b, v_prevhash,
    2073              :                                                l_datum_const(31), "");
    2074          109 :                         v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2,
    2075              :                                                  "rotatedhash");
    2076              :                     }
    2077              : 
    2078              :                     /*
    2079              :                      * Block for the actual function call, if args are
    2080              :                      * non-NULL.
    2081              :                      */
    2082          374 :                     b_ifnotnull = l_bb_before_v(opblocks[opno + 1],
    2083              :                                                 "b.%d.ifnotnull",
    2084              :                                                 opno);
    2085              : 
    2086              :                     /* we expect the hash function to have 1 argument */
    2087          374 :                     if (fcinfo->nargs != 1)
    2088            0 :                         elog(ERROR, "incorrect number of function arguments");
    2089              : 
    2090          374 :                     v_fcinfo = l_ptr_const(fcinfo,
    2091              :                                            l_ptr(StructFunctionCallInfoData));
    2092              : 
    2093          374 :                     b_checkargnull = l_bb_before_v(b_ifnotnull,
    2094              :                                                    "b.%d.isnull.0", opno);
    2095              : 
    2096          374 :                     LLVMBuildBr(b, b_checkargnull);
    2097              : 
    2098              :                     /*
    2099              :                      * Determine what to do if we find the argument to be
    2100              :                      * NULL.
    2101              :                      */
    2102          374 :                     if (opcode == EEOP_HASHDATUM_FIRST_STRICT ||
    2103              :                         opcode == EEOP_HASHDATUM_NEXT32_STRICT)
    2104              :                     {
    2105          111 :                         b_ifnullblock = l_bb_before_v(b_ifnotnull,
    2106              :                                                       "b.%d.strictnull",
    2107              :                                                       opno);
    2108              : 
    2109          111 :                         LLVMPositionBuilderAtEnd(b, b_ifnullblock);
    2110              : 
    2111              :                         /*
    2112              :                          * In strict node, NULL inputs result in NULL.  Save
    2113              :                          * the NULL result and goto jumpdone.
    2114              :                          */
    2115          111 :                         LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
    2116          111 :                         LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    2117          111 :                         LLVMBuildBr(b, opblocks[op->d.hashdatum.jumpdone]);
    2118              :                     }
    2119              :                     else
    2120              :                     {
    2121          263 :                         b_ifnullblock = l_bb_before_v(b_ifnotnull,
    2122              :                                                       "b.%d.null",
    2123              :                                                       opno);
    2124              : 
    2125          263 :                         LLVMPositionBuilderAtEnd(b, b_ifnullblock);
    2126              : 
    2127              : 
    2128          263 :                         LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    2129              : 
    2130          263 :                         if (opcode == EEOP_HASHDATUM_NEXT32)
    2131              :                         {
    2132              :                             Assert(v_prevhash != NULL);
    2133              : 
    2134              :                             /*
    2135              :                              * Save the rotated hash value and skip to the
    2136              :                              * next op.
    2137              :                              */
    2138          109 :                             LLVMBuildStore(b, v_prevhash, v_resvaluep);
    2139              :                         }
    2140              :                         else
    2141              :                         {
    2142              :                             Assert(opcode == EEOP_HASHDATUM_FIRST);
    2143              : 
    2144              :                             /*
    2145              :                              * Store a zero Datum when the Datum to hash is
    2146              :                              * NULL
    2147              :                              */
    2148          154 :                             LLVMBuildStore(b, l_datum_const(0), v_resvaluep);
    2149              :                         }
    2150              : 
    2151          263 :                         LLVMBuildBr(b, opblocks[opno + 1]);
    2152              :                     }
    2153              : 
    2154          374 :                     LLVMPositionBuilderAtEnd(b, b_checkargnull);
    2155              : 
    2156              :                     /* emit code to check if the input parameter is NULL */
    2157          374 :                     v_argisnull = l_funcnull(b, v_fcinfo, 0);
    2158          374 :                     LLVMBuildCondBr(b,
    2159              :                                     LLVMBuildICmp(b,
    2160              :                                                   LLVMIntEQ,
    2161              :                                                   v_argisnull,
    2162              :                                                   l_sbool_const(1),
    2163              :                                                   ""),
    2164              :                                     b_ifnullblock,
    2165              :                                     b_ifnotnull);
    2166              : 
    2167          374 :                     LLVMPositionBuilderAtEnd(b, b_ifnotnull);
    2168              : 
    2169              :                     /*
    2170              :                      * Rotate the previously stored hash value when performing
    2171              :                      * NEXT32 in strict mode.  In non-strict mode we already
    2172              :                      * did this before checking for NULLs.
    2173              :                      */
    2174          374 :                     if (opcode == EEOP_HASHDATUM_NEXT32_STRICT)
    2175              :                     {
    2176              :                         LLVMValueRef v_tmp1;
    2177              :                         LLVMValueRef v_tmp2;
    2178              :                         LLVMValueRef tmp;
    2179              : 
    2180            6 :                         tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
    2181              :                                           l_ptr(TypeDatum));
    2182              : 
    2183              :                         /*
    2184              :                          * Fetch the previously hashed value from where the
    2185              :                          * previous hash operation stored it.
    2186              :                          */
    2187            6 :                         v_prevhash = l_load(b, TypeDatum, tmp, "prevhash");
    2188              : 
    2189              :                         /*
    2190              :                          * Rotate bits left by 1 bit.  Be careful not to
    2191              :                          * overflow uint32 when working with Datum.
    2192              :                          */
    2193            6 :                         v_tmp1 = LLVMBuildShl(b, v_prevhash, l_datum_const(1),
    2194              :                                               "");
    2195            6 :                         v_tmp1 = LLVMBuildAnd(b, v_tmp1,
    2196              :                                               l_datum_const(0xffffffff), "");
    2197            6 :                         v_tmp2 = LLVMBuildLShr(b, v_prevhash,
    2198              :                                                l_datum_const(31), "");
    2199            6 :                         v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2,
    2200              :                                                  "rotatedhash");
    2201              :                     }
    2202              : 
    2203              :                     /* call the hash function */
    2204          374 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    2205              :                                            &v_fcinfo_isnull);
    2206              : 
    2207              :                     /*
    2208              :                      * For NEXT32 ops, XOR (^) the returned hash value with
    2209              :                      * the existing hash value.
    2210              :                      */
    2211          374 :                     if (opcode == EEOP_HASHDATUM_NEXT32 ||
    2212              :                         opcode == EEOP_HASHDATUM_NEXT32_STRICT)
    2213          115 :                         v_retval = LLVMBuildXor(b, v_prevhash, v_retval,
    2214              :                                                 "xorhash");
    2215              : 
    2216          374 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    2217          374 :                     LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
    2218              : 
    2219          374 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2220          374 :                     break;
    2221              :                 }
    2222              : 
    2223           27 :             case EEOP_CONVERT_ROWTYPE:
    2224           27 :                 build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
    2225              :                                 v_state, op, v_econtext);
    2226           27 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2227           27 :                 break;
    2228              : 
    2229           26 :             case EEOP_SCALARARRAYOP:
    2230           26 :                 build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
    2231              :                                 v_state, op);
    2232           26 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2233           26 :                 break;
    2234              : 
    2235            0 :             case EEOP_HASHED_SCALARARRAYOP:
    2236            0 :                 build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp",
    2237              :                                 v_state, op, v_econtext);
    2238            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2239            0 :                 break;
    2240              : 
    2241            0 :             case EEOP_XMLEXPR:
    2242            0 :                 build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
    2243              :                                 v_state, op);
    2244            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2245            0 :                 break;
    2246              : 
    2247            0 :             case EEOP_JSON_CONSTRUCTOR:
    2248            0 :                 build_EvalXFunc(b, mod, "ExecEvalJsonConstructor",
    2249              :                                 v_state, op, v_econtext);
    2250            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2251            0 :                 break;
    2252              : 
    2253            0 :             case EEOP_IS_JSON:
    2254            0 :                 build_EvalXFunc(b, mod, "ExecEvalJsonIsPredicate",
    2255              :                                 v_state, op);
    2256            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2257            0 :                 break;
    2258              : 
    2259            0 :             case EEOP_JSONEXPR_PATH:
    2260              :                 {
    2261            0 :                     JsonExprState *jsestate = op->d.jsonexpr.jsestate;
    2262              :                     LLVMValueRef v_ret;
    2263              : 
    2264              :                     /*
    2265              :                      * Call ExecEvalJsonExprPath().  It returns the address of
    2266              :                      * the step to perform next.
    2267              :                      */
    2268            0 :                     v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExprPath",
    2269              :                                             v_state, op, v_econtext);
    2270              : 
    2271              :                     /*
    2272              :                      * Build a switch to map the return value (v_ret above),
    2273              :                      * which is a runtime value of the step address to perform
    2274              :                      * next, to either jump_empty, jump_error,
    2275              :                      * jump_eval_coercion, or jump_end.
    2276              :                      */
    2277            0 :                     if (jsestate->jump_empty >= 0 ||
    2278            0 :                         jsestate->jump_error >= 0 ||
    2279            0 :                         jsestate->jump_eval_coercion >= 0)
    2280              :                     {
    2281              :                         LLVMValueRef v_jump_empty;
    2282              :                         LLVMValueRef v_jump_error;
    2283              :                         LLVMValueRef v_jump_coercion;
    2284              :                         LLVMValueRef v_switch;
    2285              :                         LLVMBasicBlockRef b_done,
    2286              :                                     b_empty,
    2287              :                                     b_error,
    2288              :                                     b_coercion;
    2289              : 
    2290              :                         b_empty =
    2291            0 :                             l_bb_before_v(opblocks[opno + 1],
    2292              :                                           "op.%d.jsonexpr_empty", opno);
    2293              :                         b_error =
    2294            0 :                             l_bb_before_v(opblocks[opno + 1],
    2295              :                                           "op.%d.jsonexpr_error", opno);
    2296              :                         b_coercion =
    2297            0 :                             l_bb_before_v(opblocks[opno + 1],
    2298              :                                           "op.%d.jsonexpr_coercion", opno);
    2299              :                         b_done =
    2300            0 :                             l_bb_before_v(opblocks[opno + 1],
    2301              :                                           "op.%d.jsonexpr_done", opno);
    2302              : 
    2303            0 :                         v_switch = LLVMBuildSwitch(b,
    2304              :                                                    v_ret,
    2305              :                                                    b_done,
    2306              :                                                    3);
    2307              :                         /* Returned jsestate->jump_empty? */
    2308            0 :                         if (jsestate->jump_empty >= 0)
    2309              :                         {
    2310            0 :                             v_jump_empty = l_int32_const(lc, jsestate->jump_empty);
    2311            0 :                             LLVMAddCase(v_switch, v_jump_empty, b_empty);
    2312              :                         }
    2313              :                         /* ON EMPTY code */
    2314            0 :                         LLVMPositionBuilderAtEnd(b, b_empty);
    2315            0 :                         if (jsestate->jump_empty >= 0)
    2316            0 :                             LLVMBuildBr(b, opblocks[jsestate->jump_empty]);
    2317              :                         else
    2318            0 :                             LLVMBuildUnreachable(b);
    2319              : 
    2320              :                         /* Returned jsestate->jump_error? */
    2321            0 :                         if (jsestate->jump_error >= 0)
    2322              :                         {
    2323            0 :                             v_jump_error = l_int32_const(lc, jsestate->jump_error);
    2324            0 :                             LLVMAddCase(v_switch, v_jump_error, b_error);
    2325              :                         }
    2326              :                         /* ON ERROR code */
    2327            0 :                         LLVMPositionBuilderAtEnd(b, b_error);
    2328            0 :                         if (jsestate->jump_error >= 0)
    2329            0 :                             LLVMBuildBr(b, opblocks[jsestate->jump_error]);
    2330              :                         else
    2331            0 :                             LLVMBuildUnreachable(b);
    2332              : 
    2333              :                         /* Returned jsestate->jump_eval_coercion? */
    2334            0 :                         if (jsestate->jump_eval_coercion >= 0)
    2335              :                         {
    2336            0 :                             v_jump_coercion = l_int32_const(lc, jsestate->jump_eval_coercion);
    2337            0 :                             LLVMAddCase(v_switch, v_jump_coercion, b_coercion);
    2338              :                         }
    2339              :                         /* jump_eval_coercion code */
    2340            0 :                         LLVMPositionBuilderAtEnd(b, b_coercion);
    2341            0 :                         if (jsestate->jump_eval_coercion >= 0)
    2342            0 :                             LLVMBuildBr(b, opblocks[jsestate->jump_eval_coercion]);
    2343              :                         else
    2344            0 :                             LLVMBuildUnreachable(b);
    2345              : 
    2346            0 :                         LLVMPositionBuilderAtEnd(b, b_done);
    2347              :                     }
    2348              : 
    2349            0 :                     LLVMBuildBr(b, opblocks[jsestate->jump_end]);
    2350            0 :                     break;
    2351              :                 }
    2352              : 
    2353            0 :             case EEOP_JSONEXPR_COERCION:
    2354            0 :                 build_EvalXFunc(b, mod, "ExecEvalJsonCoercion",
    2355              :                                 v_state, op, v_econtext);
    2356              : 
    2357            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2358            0 :                 break;
    2359              : 
    2360            0 :             case EEOP_JSONEXPR_COERCION_FINISH:
    2361            0 :                 build_EvalXFunc(b, mod, "ExecEvalJsonCoercionFinish",
    2362              :                                 v_state, op);
    2363              : 
    2364            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2365            0 :                 break;
    2366              : 
    2367          152 :             case EEOP_AGGREF:
    2368              :                 {
    2369              :                     LLVMValueRef v_aggno;
    2370              :                     LLVMValueRef value,
    2371              :                                 isnull;
    2372              : 
    2373          152 :                     v_aggno = l_int32_const(lc, op->d.aggref.aggno);
    2374              : 
    2375              :                     /* load agg value / null */
    2376          152 :                     value = l_load_gep1(b, TypeDatum, v_aggvalues, v_aggno, "aggvalue");
    2377          152 :                     isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
    2378              : 
    2379              :                     /* and store result */
    2380          152 :                     LLVMBuildStore(b, value, v_resvaluep);
    2381          152 :                     LLVMBuildStore(b, isnull, v_resnullp);
    2382              : 
    2383          152 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2384          152 :                     break;
    2385              :                 }
    2386              : 
    2387           36 :             case EEOP_GROUPING_FUNC:
    2388           36 :                 build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
    2389              :                                 v_state, op);
    2390           36 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2391           36 :                 break;
    2392              : 
    2393            6 :             case EEOP_WINDOW_FUNC:
    2394              :                 {
    2395            6 :                     WindowFuncExprState *wfunc = op->d.window_func.wfstate;
    2396              :                     LLVMValueRef v_wfuncnop;
    2397              :                     LLVMValueRef v_wfuncno;
    2398              :                     LLVMValueRef value,
    2399              :                                 isnull;
    2400              : 
    2401              :                     /*
    2402              :                      * At this point aggref->wfuncno is not yet set (it's set
    2403              :                      * up in ExecInitWindowAgg() after initializing the
    2404              :                      * expression). So load it from memory each time round.
    2405              :                      */
    2406            6 :                     v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
    2407              :                                              l_ptr(LLVMInt32TypeInContext(lc)));
    2408            6 :                     v_wfuncno = l_load(b, LLVMInt32TypeInContext(lc), v_wfuncnop, "v_wfuncno");
    2409              : 
    2410              :                     /* load window func value / null */
    2411            6 :                     value = l_load_gep1(b, TypeDatum, v_aggvalues, v_wfuncno,
    2412              :                                         "windowvalue");
    2413            6 :                     isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_wfuncno,
    2414              :                                          "windownull");
    2415              : 
    2416            6 :                     LLVMBuildStore(b, value, v_resvaluep);
    2417            6 :                     LLVMBuildStore(b, isnull, v_resnullp);
    2418              : 
    2419            6 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2420            6 :                     break;
    2421              :                 }
    2422              : 
    2423            3 :             case EEOP_MERGE_SUPPORT_FUNC:
    2424            3 :                 build_EvalXFunc(b, mod, "ExecEvalMergeSupportFunc",
    2425              :                                 v_state, op, v_econtext);
    2426            3 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2427            3 :                 break;
    2428              : 
    2429          269 :             case EEOP_SUBPLAN:
    2430          269 :                 build_EvalXFunc(b, mod, "ExecEvalSubPlan",
    2431              :                                 v_state, op, v_econtext);
    2432          269 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2433          269 :                 break;
    2434              : 
    2435            0 :             case EEOP_AGG_STRICT_DESERIALIZE:
    2436              :             case EEOP_AGG_DESERIALIZE:
    2437              :                 {
    2438              :                     AggState   *aggstate;
    2439            0 :                     FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data;
    2440              : 
    2441              :                     LLVMValueRef v_retval;
    2442              :                     LLVMValueRef v_fcinfo_isnull;
    2443              :                     LLVMValueRef v_tmpcontext;
    2444              :                     LLVMValueRef v_oldcontext;
    2445              : 
    2446            0 :                     if (opcode == EEOP_AGG_STRICT_DESERIALIZE)
    2447              :                     {
    2448              :                         LLVMValueRef v_fcinfo;
    2449              :                         LLVMValueRef v_argnull0;
    2450              :                         LLVMBasicBlockRef b_deserialize;
    2451              : 
    2452            0 :                         b_deserialize = l_bb_before_v(opblocks[opno + 1],
    2453              :                                                       "op.%d.deserialize", opno);
    2454              : 
    2455            0 :                         v_fcinfo = l_ptr_const(fcinfo,
    2456              :                                                l_ptr(StructFunctionCallInfoData));
    2457            0 :                         v_argnull0 = l_funcnull(b, v_fcinfo, 0);
    2458              : 
    2459            0 :                         LLVMBuildCondBr(b,
    2460              :                                         LLVMBuildICmp(b,
    2461              :                                                       LLVMIntEQ,
    2462              :                                                       v_argnull0,
    2463              :                                                       l_sbool_const(1),
    2464              :                                                       ""),
    2465            0 :                                         opblocks[op->d.agg_deserialize.jumpnull],
    2466              :                                         b_deserialize);
    2467            0 :                         LLVMPositionBuilderAtEnd(b, b_deserialize);
    2468              :                     }
    2469              : 
    2470            0 :                     aggstate = castNode(AggState, state->parent);
    2471            0 :                     fcinfo = op->d.agg_deserialize.fcinfo_data;
    2472              : 
    2473              :                     v_tmpcontext =
    2474            0 :                         l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
    2475              :                                     l_ptr(StructMemoryContextData));
    2476            0 :                     v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
    2477            0 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    2478              :                                            &v_fcinfo_isnull);
    2479            0 :                     l_mcxt_switch(mod, b, v_oldcontext);
    2480              : 
    2481            0 :                     LLVMBuildStore(b, v_retval, v_resvaluep);
    2482            0 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
    2483              : 
    2484            0 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2485            0 :                     break;
    2486              :                 }
    2487              : 
    2488           33 :             case EEOP_AGG_STRICT_INPUT_CHECK_ARGS:
    2489              :             case EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1:
    2490              :             case EEOP_AGG_STRICT_INPUT_CHECK_NULLS:
    2491              :                 {
    2492           33 :                     int         nargs = op->d.agg_strict_input_check.nargs;
    2493           33 :                     NullableDatum *args = op->d.agg_strict_input_check.args;
    2494           33 :                     bool       *nulls = op->d.agg_strict_input_check.nulls;
    2495              :                     int         jumpnull;
    2496              : 
    2497              :                     LLVMValueRef v_argsp;
    2498              :                     LLVMValueRef v_nullsp;
    2499              :                     LLVMBasicBlockRef *b_checknulls;
    2500              : 
    2501              :                     Assert(nargs > 0);
    2502              : 
    2503           33 :                     jumpnull = op->d.agg_strict_input_check.jumpnull;
    2504           33 :                     v_argsp = l_ptr_const(args, l_ptr(StructNullableDatum));
    2505           33 :                     v_nullsp = l_ptr_const(nulls, l_ptr(TypeStorageBool));
    2506              : 
    2507              :                     /* create blocks for checking args */
    2508           33 :                     b_checknulls = palloc_array(LLVMBasicBlockRef, nargs);
    2509           66 :                     for (int argno = 0; argno < nargs; argno++)
    2510              :                     {
    2511           33 :                         b_checknulls[argno] =
    2512           33 :                             l_bb_before_v(opblocks[opno + 1],
    2513              :                                           "op.%d.check-null.%d",
    2514              :                                           opno, argno);
    2515              :                     }
    2516              : 
    2517           33 :                     LLVMBuildBr(b, b_checknulls[0]);
    2518              : 
    2519              :                     /* strict function, check for NULL args */
    2520           66 :                     for (int argno = 0; argno < nargs; argno++)
    2521              :                     {
    2522           33 :                         LLVMValueRef v_argno = l_int32_const(lc, argno);
    2523              :                         LLVMValueRef v_argisnull;
    2524              :                         LLVMBasicBlockRef b_argnotnull;
    2525              : 
    2526           33 :                         LLVMPositionBuilderAtEnd(b, b_checknulls[argno]);
    2527              : 
    2528           33 :                         if (argno + 1 == nargs)
    2529           33 :                             b_argnotnull = opblocks[opno + 1];
    2530              :                         else
    2531            0 :                             b_argnotnull = b_checknulls[argno + 1];
    2532              : 
    2533           33 :                         if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
    2534            0 :                             v_argisnull = l_load_gep1(b, TypeStorageBool, v_nullsp, v_argno, "");
    2535              :                         else
    2536              :                         {
    2537              :                             LLVMValueRef v_argn;
    2538              : 
    2539           33 :                             v_argn = l_gep(b, StructNullableDatum, v_argsp, &v_argno, 1, "");
    2540              :                             v_argisnull =
    2541           33 :                                 l_load_struct_gep(b, StructNullableDatum, v_argn,
    2542              :                                                   FIELDNO_NULLABLE_DATUM_ISNULL,
    2543              :                                                   "");
    2544              :                         }
    2545              : 
    2546           33 :                         LLVMBuildCondBr(b,
    2547              :                                         LLVMBuildICmp(b,
    2548              :                                                       LLVMIntEQ,
    2549              :                                                       v_argisnull,
    2550              :                                                       l_sbool_const(1), ""),
    2551           33 :                                         opblocks[jumpnull],
    2552              :                                         b_argnotnull);
    2553              :                     }
    2554              : 
    2555           33 :                     break;
    2556              :                 }
    2557              : 
    2558          159 :             case EEOP_AGG_PLAIN_PERGROUP_NULLCHECK:
    2559              :                 {
    2560              :                     int         jumpnull;
    2561              :                     LLVMValueRef v_aggstatep;
    2562              :                     LLVMValueRef v_allpergroupsp;
    2563              :                     LLVMValueRef v_pergroup_allaggs;
    2564              :                     LLVMValueRef v_setoff;
    2565              : 
    2566          159 :                     jumpnull = op->d.agg_plain_pergroup_nullcheck.jumpnull;
    2567              : 
    2568              :                     /*
    2569              :                      * pergroup_allaggs = aggstate->all_pergroups
    2570              :                      * [op->d.agg_plain_pergroup_nullcheck.setoff];
    2571              :                      */
    2572          159 :                     v_aggstatep = LLVMBuildBitCast(b, v_parent,
    2573              :                                                    l_ptr(StructAggState), "");
    2574              : 
    2575          159 :                     v_allpergroupsp = l_load_struct_gep(b,
    2576              :                                                         StructAggState,
    2577              :                                                         v_aggstatep,
    2578              :                                                         FIELDNO_AGGSTATE_ALL_PERGROUPS,
    2579              :                                                         "aggstate.all_pergroups");
    2580              : 
    2581          159 :                     v_setoff = l_int32_const(lc, op->d.agg_plain_pergroup_nullcheck.setoff);
    2582              : 
    2583          159 :                     v_pergroup_allaggs = l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
    2584              :                                                      v_allpergroupsp, v_setoff, "");
    2585              : 
    2586          159 :                     LLVMBuildCondBr(b,
    2587              :                                     LLVMBuildICmp(b, LLVMIntEQ,
    2588              :                                                   LLVMBuildPtrToInt(b, v_pergroup_allaggs, TypeDatum, ""),
    2589              :                                                   l_datum_const(0), ""),
    2590          159 :                                     opblocks[jumpnull],
    2591          159 :                                     opblocks[opno + 1]);
    2592          159 :                     break;
    2593              :                 }
    2594              : 
    2595          569 :             case EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL:
    2596              :             case EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL:
    2597              :             case EEOP_AGG_PLAIN_TRANS_BYVAL:
    2598              :             case EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF:
    2599              :             case EEOP_AGG_PLAIN_TRANS_STRICT_BYREF:
    2600              :             case EEOP_AGG_PLAIN_TRANS_BYREF:
    2601              :                 {
    2602              :                     AggState   *aggstate;
    2603              :                     AggStatePerTrans pertrans;
    2604              :                     FunctionCallInfo fcinfo;
    2605              : 
    2606              :                     LLVMValueRef v_aggstatep;
    2607              :                     LLVMValueRef v_fcinfo;
    2608              :                     LLVMValueRef v_fcinfo_isnull;
    2609              : 
    2610              :                     LLVMValueRef v_transvaluep;
    2611              :                     LLVMValueRef v_transnullp;
    2612              : 
    2613              :                     LLVMValueRef v_setoff;
    2614              :                     LLVMValueRef v_transno;
    2615              : 
    2616              :                     LLVMValueRef v_aggcontext;
    2617              : 
    2618              :                     LLVMValueRef v_allpergroupsp;
    2619              :                     LLVMValueRef v_current_setp;
    2620              :                     LLVMValueRef v_current_pertransp;
    2621              :                     LLVMValueRef v_curaggcontext;
    2622              : 
    2623              :                     LLVMValueRef v_pertransp;
    2624              : 
    2625              :                     LLVMValueRef v_pergroupp;
    2626              : 
    2627              :                     LLVMValueRef v_retval;
    2628              : 
    2629              :                     LLVMValueRef v_tmpcontext;
    2630              :                     LLVMValueRef v_oldcontext;
    2631              : 
    2632          569 :                     aggstate = castNode(AggState, state->parent);
    2633          569 :                     pertrans = op->d.agg_trans.pertrans;
    2634              : 
    2635          569 :                     fcinfo = pertrans->transfn_fcinfo;
    2636              : 
    2637              :                     v_aggstatep =
    2638          569 :                         LLVMBuildBitCast(b, v_parent, l_ptr(StructAggState), "");
    2639          569 :                     v_pertransp = l_ptr_const(pertrans,
    2640              :                                               l_ptr(StructAggStatePerTransData));
    2641              : 
    2642              :                     /*
    2643              :                      * pergroup = &aggstate->all_pergroups
    2644              :                      * [op->d.agg_trans.setoff] [op->d.agg_trans.transno];
    2645              :                      */
    2646              :                     v_allpergroupsp =
    2647          569 :                         l_load_struct_gep(b,
    2648              :                                           StructAggState,
    2649              :                                           v_aggstatep,
    2650              :                                           FIELDNO_AGGSTATE_ALL_PERGROUPS,
    2651              :                                           "aggstate.all_pergroups");
    2652          569 :                     v_setoff = l_int32_const(lc, op->d.agg_trans.setoff);
    2653          569 :                     v_transno = l_int32_const(lc, op->d.agg_trans.transno);
    2654              :                     v_pergroupp =
    2655          569 :                         l_gep(b,
    2656              :                               StructAggStatePerGroupData,
    2657              :                               l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
    2658              :                                           v_allpergroupsp, v_setoff, ""),
    2659              :                               &v_transno, 1, "");
    2660              : 
    2661              : 
    2662          569 :                     if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL ||
    2663              :                         opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF)
    2664              :                     {
    2665              :                         LLVMValueRef v_notransvalue;
    2666              :                         LLVMBasicBlockRef b_init;
    2667              :                         LLVMBasicBlockRef b_no_init;
    2668              : 
    2669              :                         v_notransvalue =
    2670          144 :                             l_load_struct_gep(b,
    2671              :                                               StructAggStatePerGroupData,
    2672              :                                               v_pergroupp,
    2673              :                                               FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE,
    2674              :                                               "notransvalue");
    2675              : 
    2676          144 :                         b_init = l_bb_before_v(opblocks[opno + 1],
    2677              :                                                "op.%d.inittrans", opno);
    2678          144 :                         b_no_init = l_bb_before_v(opblocks[opno + 1],
    2679              :                                                   "op.%d.no_inittrans", opno);
    2680              : 
    2681          144 :                         LLVMBuildCondBr(b,
    2682              :                                         LLVMBuildICmp(b, LLVMIntEQ, v_notransvalue,
    2683              :                                                       l_sbool_const(1), ""),
    2684              :                                         b_init,
    2685              :                                         b_no_init);
    2686              : 
    2687              :                         /* block to init the transition value if necessary */
    2688              :                         {
    2689              :                             LLVMValueRef params[4];
    2690              : 
    2691          144 :                             LLVMPositionBuilderAtEnd(b, b_init);
    2692              : 
    2693          144 :                             v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
    2694              :                                                        l_ptr(StructExprContext));
    2695              : 
    2696          144 :                             params[0] = v_aggstatep;
    2697          144 :                             params[1] = v_pertransp;
    2698          144 :                             params[2] = v_pergroupp;
    2699          144 :                             params[3] = v_aggcontext;
    2700              : 
    2701          144 :                             l_call(b,
    2702              :                                    llvm_pg_var_func_type("ExecAggInitGroup"),
    2703              :                                    llvm_pg_func(mod, "ExecAggInitGroup"),
    2704              :                                    params, lengthof(params),
    2705              :                                    "");
    2706              : 
    2707          144 :                             LLVMBuildBr(b, opblocks[opno + 1]);
    2708              :                         }
    2709              : 
    2710          144 :                         LLVMPositionBuilderAtEnd(b, b_no_init);
    2711              :                     }
    2712              : 
    2713          569 :                     if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL ||
    2714          425 :                         opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF ||
    2715          198 :                         opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL ||
    2716              :                         opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYREF)
    2717              :                     {
    2718              :                         LLVMValueRef v_transnull;
    2719              :                         LLVMBasicBlockRef b_strictpass;
    2720              : 
    2721          371 :                         b_strictpass = l_bb_before_v(opblocks[opno + 1],
    2722              :                                                      "op.%d.strictpass", opno);
    2723              :                         v_transnull =
    2724          371 :                             l_load_struct_gep(b,
    2725              :                                               StructAggStatePerGroupData,
    2726              :                                               v_pergroupp,
    2727              :                                               FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
    2728              :                                               "transnull");
    2729              : 
    2730          371 :                         LLVMBuildCondBr(b,
    2731              :                                         LLVMBuildICmp(b, LLVMIntEQ, v_transnull,
    2732              :                                                       l_sbool_const(1), ""),
    2733          371 :                                         opblocks[opno + 1],
    2734              :                                         b_strictpass);
    2735              : 
    2736          371 :                         LLVMPositionBuilderAtEnd(b, b_strictpass);
    2737              :                     }
    2738              : 
    2739              : 
    2740          569 :                     v_fcinfo = l_ptr_const(fcinfo,
    2741              :                                            l_ptr(StructFunctionCallInfoData));
    2742          569 :                     v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
    2743              :                                                l_ptr(StructExprContext));
    2744              : 
    2745              :                     v_current_setp =
    2746          569 :                         l_struct_gep(b,
    2747              :                                      StructAggState,
    2748              :                                      v_aggstatep,
    2749              :                                      FIELDNO_AGGSTATE_CURRENT_SET,
    2750              :                                      "aggstate.current_set");
    2751              :                     v_curaggcontext =
    2752          569 :                         l_struct_gep(b,
    2753              :                                      StructAggState,
    2754              :                                      v_aggstatep,
    2755              :                                      FIELDNO_AGGSTATE_CURAGGCONTEXT,
    2756              :                                      "aggstate.curaggcontext");
    2757              :                     v_current_pertransp =
    2758          569 :                         l_struct_gep(b,
    2759              :                                      StructAggState,
    2760              :                                      v_aggstatep,
    2761              :                                      FIELDNO_AGGSTATE_CURPERTRANS,
    2762              :                                      "aggstate.curpertrans");
    2763              : 
    2764              :                     /* set aggstate globals */
    2765          569 :                     LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
    2766          569 :                     LLVMBuildStore(b, l_int32_const(lc, op->d.agg_trans.setno),
    2767              :                                    v_current_setp);
    2768          569 :                     LLVMBuildStore(b, v_pertransp, v_current_pertransp);
    2769              : 
    2770              :                     /* invoke transition function in per-tuple context */
    2771              :                     v_tmpcontext =
    2772          569 :                         l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
    2773              :                                     l_ptr(StructMemoryContextData));
    2774          569 :                     v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
    2775              : 
    2776              :                     /* store transvalue in fcinfo->args[0] */
    2777              :                     v_transvaluep =
    2778          569 :                         l_struct_gep(b,
    2779              :                                      StructAggStatePerGroupData,
    2780              :                                      v_pergroupp,
    2781              :                                      FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
    2782              :                                      "transvalue");
    2783              :                     v_transnullp =
    2784          569 :                         l_struct_gep(b,
    2785              :                                      StructAggStatePerGroupData,
    2786              :                                      v_pergroupp,
    2787              :                                      FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
    2788              :                                      "transnullp");
    2789          569 :                     LLVMBuildStore(b,
    2790              :                                    l_load(b,
    2791              :                                           TypeDatum,
    2792              :                                           v_transvaluep,
    2793              :                                           "transvalue"),
    2794              :                                    l_funcvaluep(b, v_fcinfo, 0));
    2795          569 :                     LLVMBuildStore(b,
    2796              :                                    l_load(b, TypeStorageBool, v_transnullp, "transnull"),
    2797              :                                    l_funcnullp(b, v_fcinfo, 0));
    2798              : 
    2799              :                     /* and invoke transition function */
    2800          569 :                     v_retval = BuildV1Call(context, b, mod, fcinfo,
    2801              :                                            &v_fcinfo_isnull);
    2802              : 
    2803              :                     /*
    2804              :                      * For pass-by-ref datatype, must copy the new value into
    2805              :                      * aggcontext and free the prior transValue.  But if
    2806              :                      * transfn returned a pointer to its first input, we don't
    2807              :                      * need to do anything.  Also, if transfn returned a
    2808              :                      * pointer to a R/W expanded object that is already a
    2809              :                      * child of the aggcontext, assume we can adopt that value
    2810              :                      * without copying it.
    2811              :                      */
    2812          569 :                     if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF ||
    2813          428 :                         opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYREF ||
    2814              :                         opcode == EEOP_AGG_PLAIN_TRANS_BYREF)
    2815              :                     {
    2816              :                         LLVMBasicBlockRef b_call;
    2817              :                         LLVMBasicBlockRef b_nocall;
    2818              :                         LLVMValueRef v_fn;
    2819              :                         LLVMValueRef v_transvalue;
    2820              :                         LLVMValueRef v_transnull;
    2821              :                         LLVMValueRef v_newval;
    2822              :                         LLVMValueRef params[6];
    2823              : 
    2824          141 :                         b_call = l_bb_before_v(opblocks[opno + 1],
    2825              :                                                "op.%d.transcall", opno);
    2826          141 :                         b_nocall = l_bb_before_v(opblocks[opno + 1],
    2827              :                                                  "op.%d.transnocall", opno);
    2828              : 
    2829          141 :                         v_transvalue = l_load(b, TypeDatum, v_transvaluep, "");
    2830          141 :                         v_transnull = l_load(b, TypeStorageBool, v_transnullp, "");
    2831              : 
    2832              :                         /*
    2833              :                          * DatumGetPointer(newVal) !=
    2834              :                          * DatumGetPointer(pergroup->transValue))
    2835              :                          */
    2836          141 :                         LLVMBuildCondBr(b,
    2837              :                                         LLVMBuildICmp(b, LLVMIntEQ,
    2838              :                                                       v_transvalue,
    2839              :                                                       v_retval, ""),
    2840              :                                         b_nocall, b_call);
    2841              : 
    2842              :                         /* returned datum not passed datum, reparent */
    2843          141 :                         LLVMPositionBuilderAtEnd(b, b_call);
    2844              : 
    2845          141 :                         params[0] = v_aggstatep;
    2846          141 :                         params[1] = v_pertransp;
    2847          141 :                         params[2] = v_retval;
    2848          141 :                         params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
    2849              :                                                    TypeParamBool, "");
    2850          141 :                         params[4] = v_transvalue;
    2851          141 :                         params[5] = LLVMBuildTrunc(b, v_transnull,
    2852              :                                                    TypeParamBool, "");
    2853              : 
    2854          141 :                         v_fn = llvm_pg_func(mod, "ExecAggCopyTransValue");
    2855              :                         v_newval =
    2856          141 :                             l_call(b,
    2857              :                                    LLVMGetFunctionType(v_fn),
    2858              :                                    v_fn,
    2859              :                                    params, lengthof(params),
    2860              :                                    "");
    2861              : 
    2862              :                         /* store trans value */
    2863          141 :                         LLVMBuildStore(b, v_newval, v_transvaluep);
    2864          141 :                         LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
    2865              : 
    2866          141 :                         l_mcxt_switch(mod, b, v_oldcontext);
    2867          141 :                         LLVMBuildBr(b, opblocks[opno + 1]);
    2868              : 
    2869              :                         /* returned datum passed datum, no need to reparent */
    2870          141 :                         LLVMPositionBuilderAtEnd(b, b_nocall);
    2871              :                     }
    2872              : 
    2873              :                     /* store trans value */
    2874          569 :                     LLVMBuildStore(b, v_retval, v_transvaluep);
    2875          569 :                     LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
    2876              : 
    2877          569 :                     l_mcxt_switch(mod, b, v_oldcontext);
    2878              : 
    2879          569 :                     LLVMBuildBr(b, opblocks[opno + 1]);
    2880          569 :                     break;
    2881              :                 }
    2882              : 
    2883            0 :             case EEOP_AGG_PRESORTED_DISTINCT_SINGLE:
    2884              :                 {
    2885            0 :                     AggState   *aggstate = castNode(AggState, state->parent);
    2886            0 :                     AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
    2887            0 :                     int         jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
    2888              : 
    2889            0 :                     LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctSingle");
    2890              :                     LLVMValueRef v_args[2];
    2891              :                     LLVMValueRef v_ret;
    2892              : 
    2893            0 :                     v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState));
    2894            0 :                     v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData));
    2895              : 
    2896            0 :                     v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, "");
    2897            0 :                     v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
    2898              : 
    2899            0 :                     LLVMBuildCondBr(b,
    2900              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_ret,
    2901              :                                                   l_sbool_const(1), ""),
    2902            0 :                                     opblocks[opno + 1],
    2903            0 :                                     opblocks[jumpdistinct]);
    2904            0 :                     break;
    2905              :                 }
    2906              : 
    2907            0 :             case EEOP_AGG_PRESORTED_DISTINCT_MULTI:
    2908              :                 {
    2909            0 :                     AggState   *aggstate = castNode(AggState, state->parent);
    2910            0 :                     AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
    2911            0 :                     int         jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
    2912              : 
    2913            0 :                     LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctMulti");
    2914              :                     LLVMValueRef v_args[2];
    2915              :                     LLVMValueRef v_ret;
    2916              : 
    2917            0 :                     v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState));
    2918            0 :                     v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData));
    2919              : 
    2920            0 :                     v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, "");
    2921            0 :                     v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
    2922              : 
    2923            0 :                     LLVMBuildCondBr(b,
    2924              :                                     LLVMBuildICmp(b, LLVMIntEQ, v_ret,
    2925              :                                                   l_sbool_const(1), ""),
    2926            0 :                                     opblocks[opno + 1],
    2927            0 :                                     opblocks[jumpdistinct]);
    2928            0 :                     break;
    2929              :                 }
    2930              : 
    2931            0 :             case EEOP_AGG_ORDERED_TRANS_DATUM:
    2932            0 :                 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
    2933              :                                 v_state, op, v_econtext);
    2934            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2935            0 :                 break;
    2936              : 
    2937            0 :             case EEOP_AGG_ORDERED_TRANS_TUPLE:
    2938            0 :                 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
    2939              :                                 v_state, op, v_econtext);
    2940            0 :                 LLVMBuildBr(b, opblocks[opno + 1]);
    2941            0 :                 break;
    2942              : 
    2943            0 :             case EEOP_LAST:
    2944              :                 Assert(false);
    2945            0 :                 break;
    2946              :         }
    2947              :     }
    2948              : 
    2949         3510 :     LLVMDisposeBuilder(b);
    2950              : 
    2951              :     /*
    2952              :      * Don't immediately emit function, instead do so the first time the
    2953              :      * expression is actually evaluated. That allows to emit a lot of
    2954              :      * functions together, avoiding a lot of repeated llvm and memory
    2955              :      * remapping overhead.
    2956              :      */
    2957              :     {
    2958              : 
    2959         3510 :         CompiledExprState *cstate = palloc0_object(CompiledExprState);
    2960              : 
    2961         3510 :         cstate->context = context;
    2962         3510 :         cstate->funcname = funcname;
    2963              : 
    2964         3510 :         state->evalfunc = ExecRunCompiledExpr;
    2965         3510 :         state->evalfunc_private = cstate;
    2966              :     }
    2967              : 
    2968         3510 :     llvm_leave_fatal_on_oom();
    2969              : 
    2970         3510 :     INSTR_TIME_SET_CURRENT(endtime);
    2971         3510 :     INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter,
    2972              :                           endtime, starttime);
    2973              : 
    2974         3510 :     return true;
    2975              : }
    2976              : 
    2977              : /*
    2978              :  * Run compiled expression.
    2979              :  *
    2980              :  * This will only be called the first time a JITed expression is called. We
    2981              :  * first make sure the expression is still up-to-date, and then get a pointer to
    2982              :  * the emitted function. The latter can be the first thing that triggers
    2983              :  * optimizing and emitting all the generated functions.
    2984              :  */
    2985              : static Datum
    2986         1847 : ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull)
    2987              : {
    2988         1847 :     CompiledExprState *cstate = state->evalfunc_private;
    2989              :     ExprStateEvalFunc func;
    2990              : 
    2991         1847 :     CheckExprStillValid(state, econtext);
    2992              : 
    2993         1847 :     llvm_enter_fatal_on_oom();
    2994         1847 :     func = (ExprStateEvalFunc) llvm_get_function(cstate->context,
    2995              :                                                  cstate->funcname);
    2996         1847 :     llvm_leave_fatal_on_oom();
    2997              :     Assert(func);
    2998              : 
    2999              :     /* remove indirection via this function for future calls */
    3000         1847 :     state->evalfunc = func;
    3001              : 
    3002         1847 :     return func(state, econtext, isNull);
    3003              : }
    3004              : 
    3005              : static LLVMValueRef
    3006         2459 : BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
    3007              :             LLVMModuleRef mod, FunctionCallInfo fcinfo,
    3008              :             LLVMValueRef *v_fcinfo_isnull)
    3009              : {
    3010              :     LLVMContextRef lc;
    3011              :     LLVMValueRef v_fn;
    3012              :     LLVMValueRef v_fcinfo_isnullp;
    3013              :     LLVMValueRef v_retval;
    3014              :     LLVMValueRef v_fcinfo;
    3015              : 
    3016         2459 :     lc = LLVMGetModuleContext(mod);
    3017              : 
    3018         2459 :     v_fn = llvm_function_reference(context, b, mod, fcinfo);
    3019              : 
    3020         2459 :     v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
    3021         2459 :     v_fcinfo_isnullp = l_struct_gep(b,
    3022              :                                     StructFunctionCallInfoData,
    3023              :                                     v_fcinfo,
    3024              :                                     FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
    3025              :                                     "v_fcinfo_isnull");
    3026         2459 :     LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
    3027              : 
    3028         2459 :     v_retval = l_call(b, LLVMGetFunctionType(AttributeTemplate), v_fn, &v_fcinfo, 1, "funccall");
    3029              : 
    3030         2459 :     if (v_fcinfo_isnull)
    3031         2459 :         *v_fcinfo_isnull = l_load(b, TypeStorageBool, v_fcinfo_isnullp, "");
    3032              : 
    3033              :     /*
    3034              :      * Add lifetime-end annotation, signaling that writes to memory don't have
    3035              :      * to be retained (important for inlining potential).
    3036              :      */
    3037              :     {
    3038         2459 :         LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
    3039              :         LLVMValueRef params[2];
    3040              : 
    3041         2459 :         params[0] = l_int64_const(lc, sizeof(NullableDatum) * fcinfo->nargs);
    3042         2459 :         params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
    3043         2459 :         l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
    3044              : 
    3045         2459 :         params[0] = l_int64_const(lc, sizeof(fcinfo->isnull));
    3046         2459 :         params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
    3047         2459 :         l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
    3048              :     }
    3049              : 
    3050         2459 :     return v_retval;
    3051              : }
    3052              : 
    3053              : /*
    3054              :  * Implement an expression step by calling the function funcname.
    3055              :  */
    3056              : static LLVMValueRef
    3057         1845 : build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
    3058              :                    LLVMValueRef v_state, ExprEvalStep *op,
    3059              :                    int nargs, LLVMValueRef *v_args)
    3060              : {
    3061         1845 :     LLVMValueRef v_fn = llvm_pg_func(mod, funcname);
    3062              :     LLVMValueRef *params;
    3063         1845 :     int         argno = 0;
    3064              :     LLVMValueRef v_ret;
    3065              : 
    3066              :     /* cheap pre-check as llvm just asserts out */
    3067         1845 :     if (LLVMCountParams(v_fn) != (nargs + 2))
    3068            0 :         elog(ERROR, "parameter mismatch: %s expects %d passed %d",
    3069              :              funcname, LLVMCountParams(v_fn), nargs + 2);
    3070              : 
    3071         1845 :     params = palloc_array(LLVMValueRef, (2 + nargs));
    3072              : 
    3073         1845 :     params[argno++] = v_state;
    3074         1845 :     params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
    3075              : 
    3076         3767 :     for (int i = 0; i < nargs; i++)
    3077         1922 :         params[argno++] = v_args[i];
    3078              : 
    3079         1845 :     v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, argno, "");
    3080              : 
    3081         1845 :     pfree(params);
    3082              : 
    3083         1845 :     return v_ret;
    3084              : }
    3085              : 
    3086              : static LLVMValueRef
    3087         2459 : create_LifetimeEnd(LLVMModuleRef mod)
    3088              : {
    3089              :     LLVMTypeRef sig;
    3090              :     LLVMValueRef fn;
    3091              :     LLVMTypeRef param_types[2];
    3092              :     LLVMContextRef lc;
    3093              : 
    3094              :     /* variadic pointer argument */
    3095         2459 :     const char *nm = "llvm.lifetime.end.p0";
    3096              : 
    3097         2459 :     fn = LLVMGetNamedFunction(mod, nm);
    3098         2459 :     if (fn)
    3099         2065 :         return fn;
    3100              : 
    3101          394 :     lc = LLVMGetModuleContext(mod);
    3102          394 :     param_types[0] = LLVMInt64TypeInContext(lc);
    3103          394 :     param_types[1] = l_ptr(LLVMInt8TypeInContext(lc));
    3104              : 
    3105          394 :     sig = LLVMFunctionType(LLVMVoidTypeInContext(lc), param_types,
    3106              :                            lengthof(param_types), false);
    3107          394 :     fn = LLVMAddFunction(mod, nm, sig);
    3108              : 
    3109          394 :     LLVMSetFunctionCallConv(fn, LLVMCCallConv);
    3110              : 
    3111              :     Assert(LLVMGetIntrinsicID(fn));
    3112              : 
    3113          394 :     return fn;
    3114              : }
        

Generated by: LCOV version 2.0-1