LCOV - differential code coverage report
Current view: top level - src/backend/jit/llvm - llvmjit_expr.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 71.2 % 899 640 21 22 70 146 28 119 13 480 85 134 4
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 5 5 4 1 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a