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