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