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