LCOV - code coverage report
Current view: top level - src/backend/jit/llvm - llvmjit_expr.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 719 1046 68.7 %
Date: 2025-01-18 03:14:54 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14