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

Generated by: LCOV version 1.13