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  LLVMValueRef tmp;
1944 
1945  tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
1946  l_ptr(TypeSizeT));
1947 
1948  /*
1949  * Fetch the previously hashed value from where the
1950  * previous hash operation stored it.
1951  */
1952  v_prevhash = l_load(b, TypeSizeT, tmp, "prevhash");
1953 
1954  /*
1955  * Rotate bits left by 1 bit. Be careful not to
1956  * overflow uint32 when working with size_t.
1957  */
1958  v_tmp1 = LLVMBuildShl(b, v_prevhash, l_sizet_const(1),
1959  "");
1960  v_tmp1 = LLVMBuildAnd(b, v_tmp1,
1961  l_sizet_const(0xffffffff), "");
1962  v_tmp2 = LLVMBuildLShr(b, v_prevhash,
1963  l_sizet_const(31), "");
1964  v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2,
1965  "rotatedhash");
1966  }
1967 
1968  /*
1969  * Block for the actual function call, if args are
1970  * non-NULL.
1971  */
1972  b_ifnotnull = l_bb_before_v(opblocks[opno + 1],
1973  "b.%d.ifnotnull",
1974  opno);
1975 
1976  /* we expect the hash function to have 1 argument */
1977  if (fcinfo->nargs != 1)
1978  elog(ERROR, "incorrect number of function arguments");
1979 
1980  v_fcinfo = l_ptr_const(fcinfo,
1982 
1983  b_checkargnull = l_bb_before_v(b_ifnotnull,
1984  "b.%d.isnull.0", opno);
1985 
1986  LLVMBuildBr(b, b_checkargnull);
1987 
1988  /*
1989  * Determine what to do if we find the argument to be
1990  * NULL.
1991  */
1992  if (opcode == EEOP_HASHDATUM_FIRST_STRICT ||
1993  opcode == EEOP_HASHDATUM_NEXT32_STRICT)
1994  {
1995  b_ifnullblock = l_bb_before_v(b_ifnotnull,
1996  "b.%d.strictnull",
1997  opno);
1998 
1999  LLVMPositionBuilderAtEnd(b, b_ifnullblock);
2000 
2001  /*
2002  * In strict node, NULL inputs result in NULL. Save
2003  * the NULL result and goto jumpdone.
2004  */
2005  LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
2006  LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
2007  LLVMBuildBr(b, opblocks[op->d.hashdatum.jumpdone]);
2008  }
2009  else
2010  {
2011  b_ifnullblock = l_bb_before_v(b_ifnotnull,
2012  "b.%d.null",
2013  opno);
2014 
2015  LLVMPositionBuilderAtEnd(b, b_ifnullblock);
2016 
2017 
2018  LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
2019 
2020  if (opcode == EEOP_HASHDATUM_NEXT32)
2021  {
2022  Assert(v_prevhash != NULL);
2023 
2024  /*
2025  * Save the rotated hash value and skip to the
2026  * next op.
2027  */
2028  LLVMBuildStore(b, v_prevhash, v_resvaluep);
2029  }
2030  else
2031  {
2032  Assert(opcode == EEOP_HASHDATUM_FIRST);
2033 
2034  /*
2035  * Store a zero Datum when the Datum to hash is
2036  * NULL
2037  */
2038  LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
2039  }
2040 
2041  LLVMBuildBr(b, opblocks[opno + 1]);
2042  }
2043 
2044  LLVMPositionBuilderAtEnd(b, b_checkargnull);
2045 
2046  /* emit code to check if the input parameter is NULL */
2047  v_argisnull = l_funcnull(b, v_fcinfo, 0);
2048  LLVMBuildCondBr(b,
2049  LLVMBuildICmp(b,
2050  LLVMIntEQ,
2051  v_argisnull,
2052  l_sbool_const(1),
2053  ""),
2054  b_ifnullblock,
2055  b_ifnotnull);
2056 
2057  LLVMPositionBuilderAtEnd(b, b_ifnotnull);
2058 
2059  /*
2060  * Rotate the previously stored hash value when performing
2061  * NEXT32 in strict mode. In non-strict mode we already
2062  * did this before checking for NULLs.
2063  */
2064  if (opcode == EEOP_HASHDATUM_NEXT32_STRICT)
2065  {
2066  LLVMValueRef v_tmp1;
2067  LLVMValueRef v_tmp2;
2068  LLVMValueRef tmp;
2069 
2070  tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
2071  l_ptr(TypeSizeT));
2072 
2073  /*
2074  * Fetch the previously hashed value from where the
2075  * previous hash operation stored it.
2076  */
2077  v_prevhash = l_load(b, TypeSizeT, tmp, "prevhash");
2078 
2079  /*
2080  * Rotate bits left by 1 bit. Be careful not to
2081  * overflow uint32 when working with size_t.
2082  */
2083  v_tmp1 = LLVMBuildShl(b, v_prevhash, l_sizet_const(1),
2084  "");
2085  v_tmp1 = LLVMBuildAnd(b, v_tmp1,
2086  l_sizet_const(0xffffffff), "");
2087  v_tmp2 = LLVMBuildLShr(b, v_prevhash,
2088  l_sizet_const(31), "");
2089  v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2,
2090  "rotatedhash");
2091  }
2092 
2093  /* call the hash function */
2094  v_retval = BuildV1Call(context, b, mod, fcinfo,
2095  &v_fcinfo_isnull);
2096 
2097  /*
2098  * For NEXT32 ops, XOR (^) the returned hash value with
2099  * the existing hash value.
2100  */
2101  if (opcode == EEOP_HASHDATUM_NEXT32 ||
2102  opcode == EEOP_HASHDATUM_NEXT32_STRICT)
2103  v_retval = LLVMBuildXor(b, v_prevhash, v_retval,
2104  "xorhash");
2105 
2106  LLVMBuildStore(b, v_retval, v_resvaluep);
2107  LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
2108 
2109  LLVMBuildBr(b, opblocks[opno + 1]);
2110  break;
2111  }
2112 
2113  case EEOP_CONVERT_ROWTYPE:
2114  build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
2115  v_state, op, v_econtext);
2116  LLVMBuildBr(b, opblocks[opno + 1]);
2117  break;
2118 
2119  case EEOP_SCALARARRAYOP:
2120  build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
2121  v_state, op);
2122  LLVMBuildBr(b, opblocks[opno + 1]);
2123  break;
2124 
2126  build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp",
2127  v_state, op, v_econtext);
2128  LLVMBuildBr(b, opblocks[opno + 1]);
2129  break;
2130 
2131  case EEOP_XMLEXPR:
2132  build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
2133  v_state, op);
2134  LLVMBuildBr(b, opblocks[opno + 1]);
2135  break;
2136 
2137  case EEOP_JSON_CONSTRUCTOR:
2138  build_EvalXFunc(b, mod, "ExecEvalJsonConstructor",
2139  v_state, op, v_econtext);
2140  LLVMBuildBr(b, opblocks[opno + 1]);
2141  break;
2142 
2143  case EEOP_IS_JSON:
2144  build_EvalXFunc(b, mod, "ExecEvalJsonIsPredicate",
2145  v_state, op);
2146  LLVMBuildBr(b, opblocks[opno + 1]);
2147  break;
2148 
2149  case EEOP_JSONEXPR_PATH:
2150  {
2151  JsonExprState *jsestate = op->d.jsonexpr.jsestate;
2152  LLVMValueRef v_ret;
2153 
2154  /*
2155  * Call ExecEvalJsonExprPath(). It returns the address of
2156  * the step to perform next.
2157  */
2158  v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExprPath",
2159  v_state, op, v_econtext);
2160 
2161  /*
2162  * Build a switch to map the return value (v_ret above),
2163  * which is a runtime value of the step address to perform
2164  * next, to either jump_empty, jump_error,
2165  * jump_eval_coercion, or jump_end.
2166  */
2167  if (jsestate->jump_empty >= 0 ||
2168  jsestate->jump_error >= 0 ||
2169  jsestate->jump_eval_coercion >= 0)
2170  {
2171  LLVMValueRef v_jump_empty;
2172  LLVMValueRef v_jump_error;
2173  LLVMValueRef v_jump_coercion;
2174  LLVMValueRef v_switch;
2175  LLVMBasicBlockRef b_done,
2176  b_empty,
2177  b_error,
2178  b_coercion;
2179 
2180  b_empty =
2181  l_bb_before_v(opblocks[opno + 1],
2182  "op.%d.jsonexpr_empty", opno);
2183  b_error =
2184  l_bb_before_v(opblocks[opno + 1],
2185  "op.%d.jsonexpr_error", opno);
2186  b_coercion =
2187  l_bb_before_v(opblocks[opno + 1],
2188  "op.%d.jsonexpr_coercion", opno);
2189  b_done =
2190  l_bb_before_v(opblocks[opno + 1],
2191  "op.%d.jsonexpr_done", opno);
2192 
2193  v_switch = LLVMBuildSwitch(b,
2194  v_ret,
2195  b_done,
2196  3);
2197  /* Returned jsestate->jump_empty? */
2198  if (jsestate->jump_empty >= 0)
2199  {
2200  v_jump_empty = l_int32_const(lc, jsestate->jump_empty);
2201  LLVMAddCase(v_switch, v_jump_empty, b_empty);
2202  }
2203  /* ON EMPTY code */
2204  LLVMPositionBuilderAtEnd(b, b_empty);
2205  if (jsestate->jump_empty >= 0)
2206  LLVMBuildBr(b, opblocks[jsestate->jump_empty]);
2207  else
2208  LLVMBuildUnreachable(b);
2209 
2210  /* Returned jsestate->jump_error? */
2211  if (jsestate->jump_error >= 0)
2212  {
2213  v_jump_error = l_int32_const(lc, jsestate->jump_error);
2214  LLVMAddCase(v_switch, v_jump_error, b_error);
2215  }
2216  /* ON ERROR code */
2217  LLVMPositionBuilderAtEnd(b, b_error);
2218  if (jsestate->jump_error >= 0)
2219  LLVMBuildBr(b, opblocks[jsestate->jump_error]);
2220  else
2221  LLVMBuildUnreachable(b);
2222 
2223  /* Returned jsestate->jump_eval_coercion? */
2224  if (jsestate->jump_eval_coercion >= 0)
2225  {
2226  v_jump_coercion = l_int32_const(lc, jsestate->jump_eval_coercion);
2227  LLVMAddCase(v_switch, v_jump_coercion, b_coercion);
2228  }
2229  /* jump_eval_coercion code */
2230  LLVMPositionBuilderAtEnd(b, b_coercion);
2231  if (jsestate->jump_eval_coercion >= 0)
2232  LLVMBuildBr(b, opblocks[jsestate->jump_eval_coercion]);
2233  else
2234  LLVMBuildUnreachable(b);
2235 
2236  LLVMPositionBuilderAtEnd(b, b_done);
2237  }
2238 
2239  LLVMBuildBr(b, opblocks[jsestate->jump_end]);
2240  break;
2241  }
2242 
2244  build_EvalXFunc(b, mod, "ExecEvalJsonCoercion",
2245  v_state, op, v_econtext);
2246 
2247  LLVMBuildBr(b, opblocks[opno + 1]);
2248  break;
2249 
2251  build_EvalXFunc(b, mod, "ExecEvalJsonCoercionFinish",
2252  v_state, op);
2253 
2254  LLVMBuildBr(b, opblocks[opno + 1]);
2255  break;
2256 
2257  case EEOP_AGGREF:
2258  {
2259  LLVMValueRef v_aggno;
2260  LLVMValueRef value,
2261  isnull;
2262 
2263  v_aggno = l_int32_const(lc, op->d.aggref.aggno);
2264 
2265  /* load agg value / null */
2266  value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_aggno, "aggvalue");
2267  isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
2268 
2269  /* and store result */
2270  LLVMBuildStore(b, value, v_resvaluep);
2271  LLVMBuildStore(b, isnull, v_resnullp);
2272 
2273  LLVMBuildBr(b, opblocks[opno + 1]);
2274  break;
2275  }
2276 
2277  case EEOP_GROUPING_FUNC:
2278  build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
2279  v_state, op);
2280  LLVMBuildBr(b, opblocks[opno + 1]);
2281  break;
2282 
2283  case EEOP_WINDOW_FUNC:
2284  {
2285  WindowFuncExprState *wfunc = op->d.window_func.wfstate;
2286  LLVMValueRef v_wfuncnop;
2287  LLVMValueRef v_wfuncno;
2288  LLVMValueRef value,
2289  isnull;
2290 
2291  /*
2292  * At this point aggref->wfuncno is not yet set (it's set
2293  * up in ExecInitWindowAgg() after initializing the
2294  * expression). So load it from memory each time round.
2295  */
2296  v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
2297  l_ptr(LLVMInt32TypeInContext(lc)));
2298  v_wfuncno = l_load(b, LLVMInt32TypeInContext(lc), v_wfuncnop, "v_wfuncno");
2299 
2300  /* load window func value / null */
2301  value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_wfuncno,
2302  "windowvalue");
2303  isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_wfuncno,
2304  "windownull");
2305 
2306  LLVMBuildStore(b, value, v_resvaluep);
2307  LLVMBuildStore(b, isnull, v_resnullp);
2308 
2309  LLVMBuildBr(b, opblocks[opno + 1]);
2310  break;
2311  }
2312 
2314  build_EvalXFunc(b, mod, "ExecEvalMergeSupportFunc",
2315  v_state, op, v_econtext);
2316  LLVMBuildBr(b, opblocks[opno + 1]);
2317  break;
2318 
2319  case EEOP_SUBPLAN:
2320  build_EvalXFunc(b, mod, "ExecEvalSubPlan",
2321  v_state, op, v_econtext);
2322  LLVMBuildBr(b, opblocks[opno + 1]);
2323  break;
2324 
2326  case EEOP_AGG_DESERIALIZE:
2327  {
2328  AggState *aggstate;
2329  FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data;
2330 
2331  LLVMValueRef v_retval;
2332  LLVMValueRef v_fcinfo_isnull;
2333  LLVMValueRef v_tmpcontext;
2334  LLVMValueRef v_oldcontext;
2335 
2336  if (opcode == EEOP_AGG_STRICT_DESERIALIZE)
2337  {
2338  LLVMValueRef v_fcinfo;
2339  LLVMValueRef v_argnull0;
2340  LLVMBasicBlockRef b_deserialize;
2341 
2342  b_deserialize = l_bb_before_v(opblocks[opno + 1],
2343  "op.%d.deserialize", opno);
2344 
2345  v_fcinfo = l_ptr_const(fcinfo,
2347  v_argnull0 = l_funcnull(b, v_fcinfo, 0);
2348 
2349  LLVMBuildCondBr(b,
2350  LLVMBuildICmp(b,
2351  LLVMIntEQ,
2352  v_argnull0,
2353  l_sbool_const(1),
2354  ""),
2355  opblocks[op->d.agg_deserialize.jumpnull],
2356  b_deserialize);
2357  LLVMPositionBuilderAtEnd(b, b_deserialize);
2358  }
2359 
2360  aggstate = castNode(AggState, state->parent);
2361  fcinfo = op->d.agg_deserialize.fcinfo_data;
2362 
2363  v_tmpcontext =
2364  l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2365  l_ptr(StructMemoryContextData));
2366  v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
2367  v_retval = BuildV1Call(context, b, mod, fcinfo,
2368  &v_fcinfo_isnull);
2369  l_mcxt_switch(mod, b, v_oldcontext);
2370 
2371  LLVMBuildStore(b, v_retval, v_resvaluep);
2372  LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
2373 
2374  LLVMBuildBr(b, opblocks[opno + 1]);
2375  break;
2376  }
2377 
2380  {
2381  int nargs = op->d.agg_strict_input_check.nargs;
2383  bool *nulls = op->d.agg_strict_input_check.nulls;
2384  int jumpnull;
2385 
2386  LLVMValueRef v_argsp;
2387  LLVMValueRef v_nullsp;
2388  LLVMBasicBlockRef *b_checknulls;
2389 
2390  Assert(nargs > 0);
2391 
2392  jumpnull = op->d.agg_strict_input_check.jumpnull;
2393  v_argsp = l_ptr_const(args, l_ptr(StructNullableDatum));
2394  v_nullsp = l_ptr_const(nulls, l_ptr(TypeStorageBool));
2395 
2396  /* create blocks for checking args */
2397  b_checknulls = palloc(sizeof(LLVMBasicBlockRef *) * nargs);
2398  for (int argno = 0; argno < nargs; argno++)
2399  {
2400  b_checknulls[argno] =
2401  l_bb_before_v(opblocks[opno + 1],
2402  "op.%d.check-null.%d",
2403  opno, argno);
2404  }
2405 
2406  LLVMBuildBr(b, b_checknulls[0]);
2407 
2408  /* strict function, check for NULL args */
2409  for (int argno = 0; argno < nargs; argno++)
2410  {
2411  LLVMValueRef v_argno = l_int32_const(lc, argno);
2412  LLVMValueRef v_argisnull;
2413  LLVMBasicBlockRef b_argnotnull;
2414 
2415  LLVMPositionBuilderAtEnd(b, b_checknulls[argno]);
2416 
2417  if (argno + 1 == nargs)
2418  b_argnotnull = opblocks[opno + 1];
2419  else
2420  b_argnotnull = b_checknulls[argno + 1];
2421 
2422  if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
2423  v_argisnull = l_load_gep1(b, TypeStorageBool, v_nullsp, v_argno, "");
2424  else
2425  {
2426  LLVMValueRef v_argn;
2427 
2428  v_argn = l_gep(b, StructNullableDatum, v_argsp, &v_argno, 1, "");
2429  v_argisnull =
2430  l_load_struct_gep(b, StructNullableDatum, v_argn,
2432  "");
2433  }
2434 
2435  LLVMBuildCondBr(b,
2436  LLVMBuildICmp(b,
2437  LLVMIntEQ,
2438  v_argisnull,
2439  l_sbool_const(1), ""),
2440  opblocks[jumpnull],
2441  b_argnotnull);
2442  }
2443 
2444  break;
2445  }
2446 
2448  {
2449  int jumpnull;
2450  LLVMValueRef v_aggstatep;
2451  LLVMValueRef v_allpergroupsp;
2452  LLVMValueRef v_pergroup_allaggs;
2453  LLVMValueRef v_setoff;
2454 
2455  jumpnull = op->d.agg_plain_pergroup_nullcheck.jumpnull;
2456 
2457  /*
2458  * pergroup_allaggs = aggstate->all_pergroups
2459  * [op->d.agg_plain_pergroup_nullcheck.setoff];
2460  */
2461  v_aggstatep = LLVMBuildBitCast(b, v_parent,
2462  l_ptr(StructAggState), "");
2463 
2464  v_allpergroupsp = l_load_struct_gep(b,
2466  v_aggstatep,
2468  "aggstate.all_pergroups");
2469 
2470  v_setoff = l_int32_const(lc, op->d.agg_plain_pergroup_nullcheck.setoff);
2471 
2472  v_pergroup_allaggs = l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
2473  v_allpergroupsp, v_setoff, "");
2474 
2475  LLVMBuildCondBr(b,
2476  LLVMBuildICmp(b, LLVMIntEQ,
2477  LLVMBuildPtrToInt(b, v_pergroup_allaggs, TypeSizeT, ""),
2478  l_sizet_const(0), ""),
2479  opblocks[jumpnull],
2480  opblocks[opno + 1]);
2481  break;
2482  }
2483 
2490  {
2491  AggState *aggstate;
2492  AggStatePerTrans pertrans;
2493  FunctionCallInfo fcinfo;
2494 
2495  LLVMValueRef v_aggstatep;
2496  LLVMValueRef v_fcinfo;
2497  LLVMValueRef v_fcinfo_isnull;
2498 
2499  LLVMValueRef v_transvaluep;
2500  LLVMValueRef v_transnullp;
2501 
2502  LLVMValueRef v_setoff;
2503  LLVMValueRef v_transno;
2504 
2505  LLVMValueRef v_aggcontext;
2506 
2507  LLVMValueRef v_allpergroupsp;
2508  LLVMValueRef v_current_setp;
2509  LLVMValueRef v_current_pertransp;
2510  LLVMValueRef v_curaggcontext;
2511 
2512  LLVMValueRef v_pertransp;
2513 
2514  LLVMValueRef v_pergroupp;
2515 
2516  LLVMValueRef v_retval;
2517 
2518  LLVMValueRef v_tmpcontext;
2519  LLVMValueRef v_oldcontext;
2520 
2521  aggstate = castNode(AggState, state->parent);
2522  pertrans = op->d.agg_trans.pertrans;
2523 
2524  fcinfo = pertrans->transfn_fcinfo;
2525 
2526  v_aggstatep =
2527  LLVMBuildBitCast(b, v_parent, l_ptr(StructAggState), "");
2528  v_pertransp = l_ptr_const(pertrans,
2530 
2531  /*
2532  * pergroup = &aggstate->all_pergroups
2533  * [op->d.agg_trans.setoff] [op->d.agg_trans.transno];
2534  */
2535  v_allpergroupsp =
2536  l_load_struct_gep(b,
2538  v_aggstatep,
2540  "aggstate.all_pergroups");
2541  v_setoff = l_int32_const(lc, op->d.agg_trans.setoff);
2542  v_transno = l_int32_const(lc, op->d.agg_trans.transno);
2543  v_pergroupp =
2544  l_gep(b,
2546  l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
2547  v_allpergroupsp, v_setoff, ""),
2548  &v_transno, 1, "");
2549 
2550 
2553  {
2554  LLVMValueRef v_notransvalue;
2555  LLVMBasicBlockRef b_init;
2556  LLVMBasicBlockRef b_no_init;
2557 
2558  v_notransvalue =
2559  l_load_struct_gep(b,
2561  v_pergroupp,
2563  "notransvalue");
2564 
2565  b_init = l_bb_before_v(opblocks[opno + 1],
2566  "op.%d.inittrans", opno);
2567  b_no_init = l_bb_before_v(opblocks[opno + 1],
2568  "op.%d.no_inittrans", opno);
2569 
2570  LLVMBuildCondBr(b,
2571  LLVMBuildICmp(b, LLVMIntEQ, v_notransvalue,
2572  l_sbool_const(1), ""),
2573  b_init,
2574  b_no_init);
2575 
2576  /* block to init the transition value if necessary */
2577  {
2578  LLVMValueRef params[4];
2579 
2580  LLVMPositionBuilderAtEnd(b, b_init);
2581 
2582  v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
2583  l_ptr(StructExprContext));
2584 
2585  params[0] = v_aggstatep;
2586  params[1] = v_pertransp;
2587  params[2] = v_pergroupp;
2588  params[3] = v_aggcontext;
2589 
2590  l_call(b,
2591  llvm_pg_var_func_type("ExecAggInitGroup"),
2592  llvm_pg_func(mod, "ExecAggInitGroup"),
2593  params, lengthof(params),
2594  "");
2595 
2596  LLVMBuildBr(b, opblocks[opno + 1]);
2597  }
2598 
2599  LLVMPositionBuilderAtEnd(b, b_no_init);
2600  }
2601 
2606  {
2607  LLVMValueRef v_transnull;
2608  LLVMBasicBlockRef b_strictpass;
2609 
2610  b_strictpass = l_bb_before_v(opblocks[opno + 1],
2611  "op.%d.strictpass", opno);
2612  v_transnull =
2613  l_load_struct_gep(b,
2615  v_pergroupp,
2617  "transnull");
2618 
2619  LLVMBuildCondBr(b,
2620  LLVMBuildICmp(b, LLVMIntEQ, v_transnull,
2621  l_sbool_const(1), ""),
2622  opblocks[opno + 1],
2623  b_strictpass);
2624 
2625  LLVMPositionBuilderAtEnd(b, b_strictpass);
2626  }
2627 
2628 
2629  v_fcinfo = l_ptr_const(fcinfo,
2631  v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
2632  l_ptr(StructExprContext));
2633 
2634  v_current_setp =
2635  l_struct_gep(b,
2637  v_aggstatep,
2639  "aggstate.current_set");
2640  v_curaggcontext =
2641  l_struct_gep(b,
2643  v_aggstatep,
2645  "aggstate.curaggcontext");
2646  v_current_pertransp =
2647  l_struct_gep(b,
2649  v_aggstatep,
2651  "aggstate.curpertrans");
2652 
2653  /* set aggstate globals */
2654  LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
2655  LLVMBuildStore(b, l_int32_const(lc, op->d.agg_trans.setno),
2656  v_current_setp);
2657  LLVMBuildStore(b, v_pertransp, v_current_pertransp);
2658 
2659  /* invoke transition function in per-tuple context */
2660  v_tmpcontext =
2661  l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2662  l_ptr(StructMemoryContextData));
2663  v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
2664 
2665  /* store transvalue in fcinfo->args[0] */
2666  v_transvaluep =
2667  l_struct_gep(b,
2669  v_pergroupp,
2671  "transvalue");
2672  v_transnullp =
2673  l_struct_gep(b,
2675  v_pergroupp,
2677  "transnullp");
2678  LLVMBuildStore(b,
2679  l_load(b,
2680  TypeSizeT,
2681  v_transvaluep,
2682  "transvalue"),
2683  l_funcvaluep(b, v_fcinfo, 0));
2684  LLVMBuildStore(b,
2685  l_load(b, TypeStorageBool, v_transnullp, "transnull"),
2686  l_funcnullp(b, v_fcinfo, 0));
2687 
2688  /* and invoke transition function */
2689  v_retval = BuildV1Call(context, b, mod, fcinfo,
2690  &v_fcinfo_isnull);
2691 
2692  /*
2693  * For pass-by-ref datatype, must copy the new value into
2694  * aggcontext and free the prior transValue. But if
2695  * transfn returned a pointer to its first input, we don't
2696  * need to do anything. Also, if transfn returned a
2697  * pointer to a R/W expanded object that is already a
2698  * child of the aggcontext, assume we can adopt that value
2699  * without copying it.
2700  */
2703  opcode == EEOP_AGG_PLAIN_TRANS_BYREF)
2704  {
2705  LLVMBasicBlockRef b_call;
2706  LLVMBasicBlockRef b_nocall;
2707  LLVMValueRef v_fn;
2708  LLVMValueRef v_transvalue;
2709  LLVMValueRef v_transnull;
2710  LLVMValueRef v_newval;
2711  LLVMValueRef params[6];
2712 
2713  b_call = l_bb_before_v(opblocks[opno + 1],
2714  "op.%d.transcall", opno);
2715  b_nocall = l_bb_before_v(opblocks[opno + 1],
2716  "op.%d.transnocall", opno);
2717 
2718  v_transvalue = l_load(b, TypeSizeT, v_transvaluep, "");
2719  v_transnull = l_load(b, TypeStorageBool, v_transnullp, "");
2720 
2721  /*
2722  * DatumGetPointer(newVal) !=
2723  * DatumGetPointer(pergroup->transValue))
2724  */
2725  LLVMBuildCondBr(b,
2726  LLVMBuildICmp(b, LLVMIntEQ,
2727  v_transvalue,
2728  v_retval, ""),
2729  b_nocall, b_call);
2730 
2731  /* returned datum not passed datum, reparent */
2732  LLVMPositionBuilderAtEnd(b, b_call);
2733 
2734  params[0] = v_aggstatep;
2735  params[1] = v_pertransp;
2736  params[2] = v_retval;
2737  params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
2738  TypeParamBool, "");
2739  params[4] = v_transvalue;
2740  params[5] = LLVMBuildTrunc(b, v_transnull,
2741  TypeParamBool, "");
2742 
2743  v_fn = llvm_pg_func(mod, "ExecAggCopyTransValue");
2744  v_newval =
2745  l_call(b,
2746  LLVMGetFunctionType(v_fn),
2747  v_fn,
2748  params, lengthof(params),
2749  "");
2750 
2751  /* store trans value */
2752  LLVMBuildStore(b, v_newval, v_transvaluep);
2753  LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
2754 
2755  l_mcxt_switch(mod, b, v_oldcontext);
2756  LLVMBuildBr(b, opblocks[opno + 1]);
2757 
2758  /* returned datum passed datum, no need to reparent */
2759  LLVMPositionBuilderAtEnd(b, b_nocall);
2760  }
2761 
2762  /* store trans value */
2763  LLVMBuildStore(b, v_retval, v_transvaluep);
2764  LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
2765 
2766  l_mcxt_switch(mod, b, v_oldcontext);
2767 
2768  LLVMBuildBr(b, opblocks[opno + 1]);
2769  break;
2770  }
2771 
2773  {
2774  AggState *aggstate = castNode(AggState, state->parent);
2775  AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
2776  int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
2777 
2778  LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctSingle");
2779  LLVMValueRef v_args[2];
2780  LLVMValueRef v_ret;
2781 
2782  v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState));
2783  v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData));
2784 
2785  v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, "");
2786  v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
2787 
2788  LLVMBuildCondBr(b,
2789  LLVMBuildICmp(b, LLVMIntEQ, v_ret,
2790  l_sbool_const(1), ""),
2791  opblocks[opno + 1],
2792  opblocks[jumpdistinct]);
2793  break;
2794  }
2795 
2797  {
2798  AggState *aggstate = castNode(AggState, state->parent);
2799  AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans;
2800  int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
2801 
2802  LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctMulti");
2803  LLVMValueRef v_args[2];
2804  LLVMValueRef v_ret;
2805 
2806  v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState));
2807  v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData));
2808 
2809  v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, "");
2810  v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
2811 
2812  LLVMBuildCondBr(b,
2813  LLVMBuildICmp(b, LLVMIntEQ, v_ret,
2814  l_sbool_const(1), ""),
2815  opblocks[opno + 1],
2816  opblocks[jumpdistinct]);
2817  break;
2818  }
2819 
2821  build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
2822  v_state, op, v_econtext);
2823  LLVMBuildBr(b, opblocks[opno + 1]);
2824  break;
2825 
2827  build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
2828  v_state, op, v_econtext);
2829  LLVMBuildBr(b, opblocks[opno + 1]);
2830  break;
2831 
2832  case EEOP_LAST:
2833  Assert(false);
2834  break;
2835  }
2836  }
2837 
2838  LLVMDisposeBuilder(b);
2839 
2840  /*
2841  * Don't immediately emit function, instead do so the first time the
2842  * expression is actually evaluated. That allows to emit a lot of
2843  * functions together, avoiding a lot of repeated llvm and memory
2844  * remapping overhead.
2845  */
2846  {
2847 
2848  CompiledExprState *cstate = palloc0(sizeof(CompiledExprState));
2849 
2850  cstate->context = context;
2851  cstate->funcname = funcname;
2852 
2853  state->evalfunc = ExecRunCompiledExpr;
2854  state->evalfunc_private = cstate;
2855  }
2856 
2858 
2859  INSTR_TIME_SET_CURRENT(endtime);
2860  INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter,
2861  endtime, starttime);
2862 
2863  return true;
2864 }
2865 
2866 /*
2867  * Run compiled expression.
2868  *
2869  * This will only be called the first time a JITed expression is called. We
2870  * first make sure the expression is still up-to-date, and then get a pointer to
2871  * the emitted function. The latter can be the first thing that triggers
2872  * optimizing and emitting all the generated functions.
2873  */
2874 static Datum
2876 {
2877  CompiledExprState *cstate = state->evalfunc_private;
2878  ExprStateEvalFunc func;
2879 
2880  CheckExprStillValid(state, econtext);
2881 
2883  func = (ExprStateEvalFunc) llvm_get_function(cstate->context,
2884  cstate->funcname);
2886  Assert(func);
2887 
2888  /* remove indirection via this function for future calls */
2889  state->evalfunc = func;
2890 
2891  return func(state, econtext, isNull);
2892 }
2893 
2894 static LLVMValueRef
2895 BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
2896  LLVMModuleRef mod, FunctionCallInfo fcinfo,
2897  LLVMValueRef *v_fcinfo_isnull)
2898 {
2899  LLVMContextRef lc;
2900  LLVMValueRef v_fn;
2901  LLVMValueRef v_fcinfo_isnullp;
2902  LLVMValueRef v_retval;
2903  LLVMValueRef v_fcinfo;
2904 
2905  lc = LLVMGetModuleContext(mod);
2906 
2907  v_fn = llvm_function_reference(context, b, mod, fcinfo);
2908 
2909  v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
2910  v_fcinfo_isnullp = l_struct_gep(b,
2912  v_fcinfo,
2914  "v_fcinfo_isnull");
2915  LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
2916 
2917  v_retval = l_call(b, LLVMGetFunctionType(AttributeTemplate), v_fn, &v_fcinfo, 1, "funccall");
2918 
2919  if (v_fcinfo_isnull)
2920  *v_fcinfo_isnull = l_load(b, TypeStorageBool, v_fcinfo_isnullp, "");
2921 
2922  /*
2923  * Add lifetime-end annotation, signaling that writes to memory don't have
2924  * to be retained (important for inlining potential).
2925  */
2926  {
2927  LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
2928  LLVMValueRef params[2];
2929 
2930  params[0] = l_int64_const(lc, sizeof(NullableDatum) * fcinfo->nargs);
2931  params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
2932  l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
2933 
2934  params[0] = l_int64_const(lc, sizeof(fcinfo->isnull));
2935  params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
2936  l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
2937  }
2938 
2939  return v_retval;
2940 }
2941 
2942 /*
2943  * Implement an expression step by calling the function funcname.
2944  */
2945 static LLVMValueRef
2946 build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
2947  LLVMValueRef v_state, ExprEvalStep *op,
2948  int nargs, LLVMValueRef *v_args)
2949 {
2950  LLVMValueRef v_fn = llvm_pg_func(mod, funcname);
2951  LLVMValueRef *params;
2952  int argno = 0;
2953  LLVMValueRef v_ret;
2954 
2955  /* cheap pre-check as llvm just asserts out */
2956  if (LLVMCountParams(v_fn) != (nargs + 2))
2957  elog(ERROR, "parameter mismatch: %s expects %d passed %d",
2958  funcname, LLVMCountParams(v_fn), nargs + 2);
2959 
2960  params = palloc(sizeof(LLVMValueRef) * (2 + nargs));
2961 
2962  params[argno++] = v_state;
2963  params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
2964 
2965  for (int i = 0; i < nargs; i++)
2966  params[argno++] = v_args[i];
2967 
2968  v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, argno, "");
2969 
2970  pfree(params);
2971 
2972  return v_ret;
2973 }
2974 
2975 static LLVMValueRef
2976 create_LifetimeEnd(LLVMModuleRef mod)
2977 {
2978  LLVMTypeRef sig;
2979  LLVMValueRef fn;
2980  LLVMTypeRef param_types[2];
2981  LLVMContextRef lc;
2982 
2983  /* variadic pointer argument */
2984  const char *nm = "llvm.lifetime.end.p0";
2985 
2986  fn = LLVMGetNamedFunction(mod, nm);
2987  if (fn)
2988  return fn;
2989 
2990  lc = LLVMGetModuleContext(mod);
2991  param_types[0] = LLVMInt64TypeInContext(lc);
2992  param_types[1] = l_ptr(LLVMInt8TypeInContext(lc));
2993 
2994  sig = LLVMFunctionType(LLVMVoidTypeInContext(lc), param_types,
2995  lengthof(param_types), false);
2996  fn = LLVMAddFunction(mod, nm, sig);
2997 
2998  LLVMSetFunctionCallConv(fn, LLVMCCallConv);
2999 
3000  Assert(LLVMGetIntrinsicID(fn));
3001 
3002  return fn;
3003 }
#define Assert(condition)
Definition: c.h:849
#define lengthof(array)
Definition: c.h:779
#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:2515
#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:2520
#define FIELDNO_EXPRCONTEXT_AGGVALUES
Definition: execnodes.h:276
#define FIELDNO_EXPRCONTEXT_OUTERTUPLE
Definition: execnodes.h:261
#define FIELDNO_AGGSTATE_ALL_PERGROUPS
Definition: execnodes.h:2566
#define FIELDNO_EXPRSTATE_PARENT
Definition: execnodes.h:124
#define FIELDNO_EXPRCONTEXT_SCANTUPLE
Definition: execnodes.h:257
#define FIELDNO_AGGSTATE_CURAGGCONTEXT
Definition: execnodes.h:2512
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:2511
const char * funcname
Definition: llvmjit_expr.c:51
LLVMJitContext * context
Definition: llvmjit_expr.c:50
struct JitContext * es_jit
Definition: execnodes.h:729
int es_jit_flags
Definition: execnodes.h:728
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:266
struct ExprEvalStep::@52::@62 jump
struct ExprEvalStep::@52::@68 iocoerce
struct ExprEvalStep::@52::@56 assign_var
struct ExprEvalStep::@52::@95 agg_plain_pergroup_nullcheck
struct ExprEvalStep::@52::@97 agg_trans
struct ExprEvalStep::@52::@75 rowcompare_final
struct ExprEvalStep::@52::@96 agg_presorted_distinctcheck
struct ExprEvalStep::@52::@53 fetch
struct ExprEvalStep::@52::@79 sbsref_subscript
struct ExprEvalStep::@52::@59 func
struct ExprEvalStep::@52::@67 make_readonly
struct ExprEvalStep::@52::@80 sbsref
struct ExprEvalStep::@52::@61 qualexpr
struct ExprEvalStep::@52::@91 window_func
Datum * resvalue
Definition: execExpr.h:293
struct ExprEvalStep::@52::@82 hashdatum_initvalue
struct ExprEvalStep::@52::@54 var
struct ExprEvalStep::@52::@65 cparam
union ExprEvalStep::@52 d
struct ExprEvalStep::@52::@57 assign_tmp
struct ExprEvalStep::@52::@58 constval
struct ExprEvalStep::@52::@99 jsonexpr
bool * resnull
Definition: execExpr.h:294
struct ExprEvalStep::@52::@94 agg_strict_input_check
struct ExprEvalStep::@52::@74 rowcompare_step
struct ExprEvalStep::@52::@89 aggref
struct ExprEvalStep::@52::@93 agg_deserialize
struct ExprEvalStep::@52::@66 casetest
struct ExprEvalStep::@52::@83 hashdatum
struct ExprEvalStep::@52::@60 boolexpr
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
int jump_eval_coercion
Definition: execnodes.h:1070
EState * state
Definition: execnodes.h:1130
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