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