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

Generated by: LCOV version 1.14