79{
82
83 LLVMJitContext *context = NULL;
84
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
134
136
137 /*
138 * Right now we don't support compiling expressions without a parent, as
139 * we need access to the EState.
140 */
142
143 /* get or create JIT context */
145 context = (LLVMJitContext *) parent->
state->
es_jit;
146 else
147 {
150 }
151
153
155 lc = LLVMGetModuleContext(mod);
156
157 b = LLVMCreateBuilderInContext(lc);
158
160
161 /* create function */
162 eval_fn = LLVMAddFunction(mod,
funcname,
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 {
311 LLVMValueRef v_resvaluep;
312 LLVMValueRef v_resnullp;
313
314 LLVMPositionBuilderAtEnd(
b, opblocks[opno]);
315
316 op = &
state->steps[opno];
318
321
322 switch (opcode)
323 {
325 {
326 LLVMValueRef v_tmpisnull;
327 LLVMValueRef v_tmpvalue;
328
329 v_tmpvalue = l_load(
b,
TypeDatum, v_tmpvaluep,
"");
331
332 LLVMBuildStore(
b, v_tmpisnull, v_isnullp);
333
334 LLVMBuildRet(
b, v_tmpvalue);
335 break;
336 }
337
339 LLVMBuildRet(
b, l_datum_const(0));
340 break;
341
347 {
349 LLVMValueRef v_slot;
350 LLVMBasicBlockRef b_fetch;
351 LLVMValueRef v_nvalid;
352 LLVMValueRef l_jit_deform = NULL;
354
355 b_fetch = l_bb_before_v(opblocks[opno + 1],
356 "op.%d.fetch", opno);
357
360
363
364 /* step should not have been generated */
366
368 v_slot = v_innerslot;
370 v_slot = v_outerslot;
372 v_slot = v_scanslot;
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 =
385 v_slot,
387 "");
389 LLVMBuildICmp(
b, LLVMIntUGE, v_nvalid,
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 {
405 l_jit_deform =
407 tts_ops,
411 deform_endtime, deform_starttime);
412 }
413
414 if (l_jit_deform)
415 {
416 LLVMValueRef params[1];
417
418 params[0] = v_slot;
419
422 l_jit_deform,
424 }
425 else
426 {
427 LLVMValueRef params[2];
428
429 params[0] = v_slot;
431
436 }
437
438 LLVMBuildBr(
b, opblocks[opno + 1]);
439 break;
440 }
441
447 {
449 isnull;
450 LLVMValueRef v_attnum;
451 LLVMValueRef v_values;
452 LLVMValueRef v_nulls;
453
455 {
456 v_values = v_innervalues;
457 v_nulls = v_innernulls;
458 }
460 {
461 v_values = v_outervalues;
462 v_nulls = v_outernulls;
463 }
465 {
466 v_values = v_scanvalues;
467 v_nulls = v_scannulls;
468 }
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);
483 LLVMBuildStore(
b,
value, v_resvaluep);
484 LLVMBuildStore(
b, isnull, v_resnullp);
485
486 LLVMBuildBr(
b, opblocks[opno + 1]);
487 break;
488 }
489
495 {
496 LLVMValueRef v_slot;
497
499 v_slot = v_innerslot;
501 v_slot = v_outerslot;
503 v_slot = v_scanslot;
505 v_slot = v_oldslot;
506 else
507 v_slot = v_newslot;
508
510 v_state, op, v_econtext, v_slot);
511
512 LLVMBuildBr(
b, opblocks[opno + 1]);
513 break;
514 }
515
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
538 {
539 v_values = v_innervalues;
540 v_nulls = v_innernulls;
541 }
543 {
544 v_values = v_outervalues;
545 v_nulls = v_outernulls;
546 }
548 {
549 v_values = v_scanvalues;
550 v_nulls = v_scannulls;
551 }
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 */
565 v_value = l_load_gep1(
b,
TypeDatum, v_values, v_attnum,
"");
567
568 /* compute addresses of targets */
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
589 {
590 LLVMValueRef v_value,
591 v_isnull;
592 LLVMValueRef v_rvaluep,
593 v_risnullp;
594 LLVMValueRef v_resultnum;
596
597 /* load data */
598 v_value = l_load(
b,
TypeDatum, v_tmpvaluep,
"");
600
601 /* compute addresses of targets */
602 v_resultnum = l_int32_const(lc, resultnum);
603 v_rvaluep =
604 l_gep(
b,
TypeDatum, v_resultvalues, &v_resultnum, 1,
"");
605 v_risnullp =
607
608 /* store nullness */
609 LLVMBuildStore(
b, v_isnull, v_risnullp);
610
611 /* make value readonly if necessary */
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 */
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 =
632 llvm_pg_func(mod,
"MakeExpandedObjectReadOnlyInternal"),
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
649 {
650 LLVMValueRef v_constvalue,
651 v_constnull;
652
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
667 {
669 LLVMValueRef v_fcinfo_isnull;
670 LLVMValueRef v_retval;
671
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 */
689 elog(
ERROR,
"argumentless strict functions are pointless");
690
691 v_fcinfo =
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 =
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 */
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);
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
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
753 v_state, op, v_econtext);
754 LLVMBuildBr(
b, opblocks[opno + 1]);
755 break;
756
757
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
796
798 LLVMBuildStore(
b, l_sbool_const(0), v_boolanynullp);
799
801 v_boolvalue = l_load(
b,
TypeDatum, v_resvaluep,
"");
802
803 /* check if current input is NULL */
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);
820 LLVMBuildICmp(
b, LLVMIntEQ, v_boolvalue,
821 l_datum_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 */
833
834 /* Build block that continues if bool is TRUE. */
835 LLVMPositionBuilderAtEnd(
b, b_boolcont);
836
838
839 /* set value to NULL if any previous values were NULL */
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_datum_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
888
890 LLVMBuildStore(
b, l_sbool_const(0), v_boolanynullp);
892 v_boolvalue = l_load(
b,
TypeDatum, v_resvaluep,
"");
893
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);
910 LLVMBuildICmp(
b, LLVMIntEQ, v_boolvalue,
911 l_datum_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 */
923
924 /* build block that continues if bool is FALSE */
925 LLVMPositionBuilderAtEnd(
b, b_boolcont);
926
928
929 /* set value to NULL if any previous values were NULL */
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_datum_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,
TypeDatum, v_resvaluep,
"");
952 v_negbool = LLVMBuildZExt(
b,
953 LLVMBuildICmp(
b, LLVMIntEQ,
954 v_boolvalue,
955 l_datum_const(0),
956 ""),
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
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,
TypeDatum, v_resvaluep,
"");
982
983 v_nullorfalse =
985 LLVMBuildICmp(
b, LLVMIntEQ, v_resnull,
986 l_sbool_const(1), ""),
987 LLVMBuildICmp(
b, LLVMIntEQ, v_resvalue,
988 l_datum_const(0), ""),
989 "");
990
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_datum_const(0), v_resvaluep);
1002 /* and jump out */
1004 break;
1005 }
1006
1008 {
1010 break;
1011 }
1012
1014 {
1015 LLVMValueRef v_resnull;
1016
1017 /* Transfer control if current result is null */
1018
1020
1022 LLVMBuildICmp(
b, LLVMIntEQ, v_resnull,
1023 l_sbool_const(1), ""),
1025 opblocks[opno + 1]);
1026 break;
1027 }
1028
1030 {
1031 LLVMValueRef v_resnull;
1032
1033 /* Transfer control if current result is non-null */
1034
1036
1038 LLVMBuildICmp(
b, LLVMIntEQ, v_resnull,
1039 l_sbool_const(0), ""),
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,
TypeDatum, v_resvaluep,
"");
1056
1057 v_nullorfalse =
1059 LLVMBuildICmp(
b, LLVMIntEQ, v_resnull,
1060 l_sbool_const(1), ""),
1061 LLVMBuildICmp(
b, LLVMIntEQ, v_resvalue,
1062 l_datum_const(0), ""),
1063 "");
1064
1066 v_nullorfalse,
1068 opblocks[opno + 1]);
1069 break;
1070 }
1071
1073 {
1075 LLVMValueRef v_resvalue;
1076
1077 v_resvalue =
1079 LLVMBuildICmp(
b, LLVMIntEQ, v_resnull,
1080 l_sbool_const(1), ""),
1081 l_datum_const(1),
1082 l_datum_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 {
1094 LLVMValueRef v_resvalue;
1095
1096 v_resvalue =
1098 LLVMBuildICmp(
b, LLVMIntEQ, v_resnull,
1099 l_sbool_const(1), ""),
1100 l_datum_const(0),
1101 l_datum_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
1112 v_state, op, v_econtext);
1113 LLVMBuildBr(
b, opblocks[opno + 1]);
1114 break;
1115
1118 v_state, op, v_econtext);
1119 LLVMBuildBr(
b, opblocks[opno + 1]);
1120 break;
1121
1126 {
1127 LLVMBasicBlockRef b_isnull,
1128 b_notnull;
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 */
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
1150 {
1151 LLVMBuildStore(
b, l_datum_const(0), v_resvaluep);
1152 }
1153 else
1154 {
1155 LLVMBuildStore(
b, l_datum_const(1), v_resvaluep);
1156 }
1157
1158 LLVMBuildBr(
b, opblocks[opno + 1]);
1159
1160 LLVMPositionBuilderAtEnd(
b, b_notnull);
1161
1164 {
1165 /*
1166 * if value is not null NULL, return value (already
1167 * set)
1168 */
1169 }
1170 else
1171 {
1172 LLVMValueRef v_value =
1174
1175 v_value = LLVMBuildZExt(
b,
1176 LLVMBuildICmp(
b, LLVMIntEQ,
1177 v_value,
1178 l_datum_const(0),
1179 ""),
1181 LLVMBuildStore(
b, v_value, v_resvaluep);
1182 }
1183 LLVMBuildBr(
b, opblocks[opno + 1]);
1184 break;
1185 }
1186
1189 v_state, op, v_econtext);
1190 LLVMBuildBr(
b, opblocks[opno + 1]);
1191 break;
1192
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
1206
1207 v_params[0] = v_state;
1209 v_params[2] = v_econtext;
1212 v_func,
1214
1215 LLVMBuildBr(
b, opblocks[opno + 1]);
1216 break;
1217 }
1218
1221 v_state, op, v_econtext);
1222 LLVMBuildBr(
b, opblocks[opno + 1]);
1223 break;
1224
1226 {
1228 LLVMValueRef v_func;
1229 LLVMValueRef v_params[3];
1230 LLVMValueRef v_ret;
1231
1234
1235 v_params[0] = v_state;
1237 v_params[2] = v_econtext;
1240 v_func,
1243
1245 LLVMBuildICmp(
b, LLVMIntEQ, v_ret,
1246 l_sbool_const(1), ""),
1247 opblocks[opno + 1],
1248 opblocks[jumpdone]);
1249 break;
1250 }
1251
1255 {
1256 LLVMValueRef v_func;
1257 LLVMValueRef v_params[3];
1258
1261
1262 v_params[0] = v_state;
1264 v_params[2] = v_econtext;
1267 v_func,
1269
1270 LLVMBuildBr(
b, opblocks[opno + 1]);
1271 break;
1272 }
1273
1275 {
1276 LLVMValueRef v_casevaluep,
1277 v_casevalue;
1278 LLVMValueRef v_casenullp,
1279 v_casenull;
1280
1285
1286 v_casevalue = l_load(
b,
TypeDatum, v_casevaluep,
"");
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
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
1332
1334
1335 /* store null isnull value in result */
1336 LLVMBuildStore(
b, v_null, v_resnullp);
1337
1338 /* check if value is NULL */
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
1349
1350 v_value = l_load(
b,
TypeDatum, v_valuep,
"");
1351
1352 v_params[0] = v_value;
1353 v_ret =
1356 llvm_pg_func(mod,
"MakeExpandedObjectReadOnlyInternal"),
1358 LLVMBuildStore(
b, v_ret, v_resvaluep);
1359
1360 LLVMBuildBr(
b, opblocks[opno + 1]);
1361 break;
1362 }
1363
1365 {
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
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
1401
1402 v_fcinfo_in_isnullp =
1405 v_fcinfo_in,
1407 "v_fcinfo_in_isnull");
1408
1409 /* output functions are not called on nulls */
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_datum_const(0);
1419 LLVMBuildBr(
b, b_input);
1420
1421 LLVMPositionBuilderAtEnd(
b, b_calloutput);
1422 v_resvalue = l_load(
b,
TypeDatum, v_resvaluep,
"");
1423
1424 /* set arg[0] */
1426 v_resvalue,
1427 l_funcvaluep(
b, v_fcinfo_out, 0));
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,
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,
TypeDatum,
"output");
1453 LLVMAddIncoming(v_output,
1454 incoming_values, incoming_blocks,
1456 }
1457
1458 /*
1459 * If input function is strict, skip if input string is
1460 * NULL.
1461 */
1463 {
1465 LLVMBuildICmp(
b, LLVMIntEQ, v_output,
1466 l_datum_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,
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
1502 v_state, op);
1503 LLVMBuildBr(
b, opblocks[opno + 1]);
1504 break;
1505
1508 {
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
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);
1567 LLVMBuildStore(
b, l_datum_const(1), v_resvaluep);
1568 else
1569 LLVMBuildStore(
b, l_datum_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);
1577 LLVMBuildStore(
b, l_datum_const(0), v_resvaluep);
1578 else
1579 LLVMBuildStore(
b, l_datum_const(1), v_resvaluep);
1580 LLVMBuildBr(
b, opblocks[opno + 1]);
1581
1582 /* neither argument is null: compare */
1583 LLVMPositionBuilderAtEnd(
b, b_noargnull);
1584
1586 &v_fcinfo_isnull);
1587
1589 {
1590 /* Must invert result of "=" */
1591 v_result =
1593 LLVMBuildICmp(
b, LLVMIntEQ,
1594 v_result,
1595 l_datum_const(0), ""),
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
1607 {
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
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 =
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 */
1666 {
1667 LLVMValueRef v_params[1];
1668 LLVMValueRef v_arg0_ro;
1669
1670 v_params[0] = v_arg0;
1671 v_arg0_ro =
1674 llvm_pg_func(mod,
"MakeExpandedObjectReadOnlyInternal"),
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_datum_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_datum_const(0), v_resvaluep);
1703
1704 LLVMBuildBr(
b, opblocks[opno + 1]);
1705 break;
1706 }
1707
1710 v_state, op);
1711 LLVMBuildBr(
b, opblocks[opno + 1]);
1712 break;
1713
1716 v_state, op);
1717 LLVMBuildBr(
b, opblocks[opno + 1]);
1718 break;
1719
1722 v_state, op);
1723 LLVMBuildBr(
b, opblocks[opno + 1]);
1724 break;
1725
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");
1746
1748
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_datum_const(0), v_resvaluep);
1759 LLVMBuildStore(
b, l_sbool_const(1), v_resnullp);
1760
1762 break;
1763 }
1764
1767 v_state, op);
1768 LLVMBuildBr(
b, opblocks[opno + 1]);
1769 break;
1770
1773 v_state, op, v_econtext);
1774 LLVMBuildBr(
b, opblocks[opno + 1]);
1775 break;
1776
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 =
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 */
1843 &v_fcinfo_isnull);
1844 LLVMBuildStore(
b, v_retval, v_resvaluep);
1845
1846 /* if result of function is NULL, force NULL result */
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 */
1862 LLVMIntEQ,
1863 v_retval,
1864 l_datum_const(0), ""),
1865 opblocks[opno + 1],
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);
1875
1876 break;
1877 }
1878
1880 {
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 =
1895 LLVMInt32TypeInContext(lc), "");
1896
1897 switch (cmptype)
1898 {
1900 predicate = LLVMIntSLT;
1901 break;
1903 predicate = LLVMIntSLE;
1904 break;
1906 predicate = LLVMIntSGT;
1907 break;
1909 predicate = LLVMIntSGE;
1910 break;
1911 default:
1912 /* EQ and NE cases aren't allowed here */
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,
TypeDatum,
"");
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
1934 v_state, op);
1935 LLVMBuildBr(
b, opblocks[opno + 1]);
1936 break;
1937
1940 v_state, op, v_econtext);
1941 LLVMBuildBr(
b, opblocks[opno + 1]);
1942 break;
1943
1946 v_state, op, v_econtext);
1947 LLVMBuildBr(
b, opblocks[opno + 1]);
1948 break;
1949
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
1967
1968 v_casevalue = l_load(
b,
TypeDatum, v_casevaluep,
"");
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
2003 v_state, op);
2004 LLVMBuildBr(
b, opblocks[opno + 1]);
2005 break;
2006
2009 v_state, op);
2010 LLVMBuildBr(
b, opblocks[opno + 1]);
2011 break;
2012
2014 {
2015 LLVMValueRef v_initvalue;
2016
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 */
2050 {
2051 LLVMValueRef v_tmp1;
2052 LLVMValueRef v_tmp2;
2053 LLVMValueRef tmp;
2054
2057
2058 /*
2059 * Fetch the previously hashed value from where the
2060 * previous hash operation stored it.
2061 */
2062 v_prevhash = l_load(
b,
TypeDatum, tmp,
"prevhash");
2063
2064 /*
2065 * Rotate bits left by 1 bit. Be careful not to
2066 * overflow uint32 when working with Datum.
2067 */
2068 v_tmp1 = LLVMBuildShl(
b, v_prevhash, l_datum_const(1),
2069 "");
2070 v_tmp1 = LLVMBuildAnd(
b, v_tmp1,
2071 l_datum_const(0xffffffff), "");
2072 v_tmp2 = LLVMBuildLShr(
b, v_prevhash,
2073 l_datum_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 */
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_datum_const(0), v_resvaluep);
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
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 {
2143
2144 /*
2145 * Store a zero Datum when the Datum to hash is
2146 * NULL
2147 */
2148 LLVMBuildStore(
b, l_datum_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);
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 */
2175 {
2176 LLVMValueRef v_tmp1;
2177 LLVMValueRef v_tmp2;
2178 LLVMValueRef tmp;
2179
2182
2183 /*
2184 * Fetch the previously hashed value from where the
2185 * previous hash operation stored it.
2186 */
2187 v_prevhash = l_load(
b,
TypeDatum, tmp,
"prevhash");
2188
2189 /*
2190 * Rotate bits left by 1 bit. Be careful not to
2191 * overflow uint32 when working with Datum.
2192 */
2193 v_tmp1 = LLVMBuildShl(
b, v_prevhash, l_datum_const(1),
2194 "");
2195 v_tmp1 = LLVMBuildAnd(
b, v_tmp1,
2196 l_datum_const(0xffffffff), "");
2197 v_tmp2 = LLVMBuildLShr(
b, v_prevhash,
2198 l_datum_const(31), "");
2199 v_prevhash = LLVMBuildOr(
b, v_tmp1, v_tmp2,
2200 "rotatedhash");
2201 }
2202
2203 /* call the hash function */
2205 &v_fcinfo_isnull);
2206
2207 /*
2208 * For NEXT32 ops, XOR (^) the returned hash value with
2209 * the existing hash value.
2210 */
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
2225 v_state, op, v_econtext);
2226 LLVMBuildBr(
b, opblocks[opno + 1]);
2227 break;
2228
2231 v_state, op);
2232 LLVMBuildBr(
b, opblocks[opno + 1]);
2233 break;
2234
2237 v_state, op, v_econtext);
2238 LLVMBuildBr(
b, opblocks[opno + 1]);
2239 break;
2240
2243 v_state, op);
2244 LLVMBuildBr(
b, opblocks[opno + 1]);
2245 break;
2246
2249 v_state, op, v_econtext);
2250 LLVMBuildBr(
b, opblocks[opno + 1]);
2251 break;
2252
2255 v_state, op);
2256 LLVMBuildBr(
b, opblocks[opno + 1]);
2257 break;
2258
2260 {
2262 LLVMValueRef v_ret;
2263
2264 /*
2265 * Call ExecEvalJsonExprPath(). It returns the address of
2266 * the step to perform next.
2267 */
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 */
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? */
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);
2317 else
2318 LLVMBuildUnreachable(
b);
2319
2320 /* Returned jsestate->jump_error? */
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);
2330 else
2331 LLVMBuildUnreachable(
b);
2332
2333 /* Returned jsestate->jump_eval_coercion? */
2335 {
2337 LLVMAddCase(v_switch, v_jump_coercion, b_coercion);
2338 }
2339 /* jump_eval_coercion code */
2340 LLVMPositionBuilderAtEnd(
b, b_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
2355 v_state, op, v_econtext);
2356
2357 LLVMBuildBr(
b, opblocks[opno + 1]);
2358 break;
2359
2362 v_state, op);
2363
2364 LLVMBuildBr(
b, opblocks[opno + 1]);
2365 break;
2366
2368 {
2369 LLVMValueRef v_aggno;
2371 isnull;
2372
2374
2375 /* load agg value / null */
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
2389 v_state, op);
2390 LLVMBuildBr(
b, opblocks[opno + 1]);
2391 break;
2392
2394 {
2396 LLVMValueRef v_wfuncnop;
2397 LLVMValueRef v_wfuncno;
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 */
2412 "windowvalue");
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
2425 v_state, op, v_econtext);
2426 LLVMBuildBr(
b, opblocks[opno + 1]);
2427 break;
2428
2431 v_state, op, v_econtext);
2432 LLVMBuildBr(
b, opblocks[opno + 1]);
2433 break;
2434
2437 {
2440
2441 LLVMValueRef v_retval;
2442 LLVMValueRef v_fcinfo_isnull;
2443 LLVMValueRef v_tmpcontext;
2444 LLVMValueRef v_oldcontext;
2445
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
2461 LLVMIntEQ,
2462 v_argnull0,
2463 l_sbool_const(1),
2464 ""),
2466 b_deserialize);
2467 LLVMPositionBuilderAtEnd(
b, b_deserialize);
2468 }
2469
2472
2473 v_tmpcontext =
2476 v_oldcontext = l_mcxt_switch(mod,
b, v_tmpcontext);
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 {
2495 int jumpnull;
2496
2497 LLVMValueRef v_argsp;
2498 LLVMValueRef v_nullsp;
2499 LLVMBasicBlockRef *b_checknulls;
2500
2502
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
2535 else
2536 {
2537 LLVMValueRef v_argn;
2538
2540 v_argisnull =
2543 "");
2544 }
2545
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,
2574
2575 v_allpergroupsp = l_load_struct_gep(
b,
2577 v_aggstatep,
2579 "aggstate.all_pergroups");
2580
2582
2584 v_allpergroupsp, v_setoff, "");
2585
2587 LLVMBuildICmp(
b, LLVMIntEQ,
2588 LLVMBuildPtrToInt(
b, v_pergroup_allaggs,
TypeDatum,
""),
2589 l_datum_const(0), ""),
2590 opblocks[jumpnull],
2591 opblocks[opno + 1]);
2592 break;
2593 }
2594
2601 {
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
2634
2636
2637 v_aggstatep =
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");
2654 v_pergroupp =
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
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
2695
2696 params[0] = v_aggstatep;
2697 params[1] = v_pertransp;
2698 params[2] = v_pergroupp;
2699 params[3] = v_aggcontext;
2700
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
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,
2744
2745 v_current_setp =
2748 v_aggstatep,
2750 "aggstate.current_set");
2751 v_curaggcontext =
2754 v_aggstatep,
2756 "aggstate.curaggcontext");
2757 v_current_pertransp =
2760 v_aggstatep,
2762 "aggstate.curpertrans");
2763
2764 /* set aggstate globals */
2765 LLVMBuildStore(
b, v_aggcontext, v_curaggcontext);
2767 v_current_setp);
2768 LLVMBuildStore(
b, v_pertransp, v_current_pertransp);
2769
2770 /* invoke transition function in per-tuple context */
2771 v_tmpcontext =
2774 v_oldcontext = l_mcxt_switch(mod,
b, v_tmpcontext);
2775
2776 /* store transvalue in fcinfo->args[0] */
2777 v_transvaluep =
2780 v_pergroupp,
2782 "transvalue");
2783 v_transnullp =
2786 v_pergroupp,
2788 "transnullp");
2792 v_transvaluep,
2793 "transvalue"),
2794 l_funcvaluep(
b, v_fcinfo, 0));
2797 l_funcnullp(
b, v_fcinfo, 0));
2798
2799 /* and invoke transition function */
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,
TypeDatum, v_transvaluep,
"");
2831
2832 /*
2833 * DatumGetPointer(newVal) !=
2834 * DatumGetPointer(pergroup->transValue))
2835 */
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,
2850 params[4] = v_transvalue;
2851 params[5] = LLVMBuildTrunc(
b, v_transnull,
2853
2855 v_newval =
2858 v_fn,
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 {
2888
2889 LLVMValueRef v_fn =
llvm_pg_func(mod,
"ExecEvalPreOrderedDistinctSingle");
2890 LLVMValueRef v_args[2];
2891 LLVMValueRef v_ret;
2892
2895
2898
2900 LLVMBuildICmp(
b, LLVMIntEQ, v_ret,
2901 l_sbool_const(1), ""),
2902 opblocks[opno + 1],
2903 opblocks[jumpdistinct]);
2904 break;
2905 }
2906
2908 {
2912
2913 LLVMValueRef v_fn =
llvm_pg_func(mod,
"ExecEvalPreOrderedDistinctMulti");
2914 LLVMValueRef v_args[2];
2915 LLVMValueRef v_ret;
2916
2919
2922
2924 LLVMBuildICmp(
b, LLVMIntEQ, v_ret,
2925 l_sbool_const(1), ""),
2926 opblocks[opno + 1],
2927 opblocks[jumpdistinct]);
2928 break;
2929 }
2930
2933 v_state, op, v_econtext);
2934 LLVMBuildBr(
b, opblocks[opno + 1]);
2935 break;
2936
2939 v_state, op, v_econtext);
2940 LLVMBuildBr(
b, opblocks[opno + 1]);
2941 break;
2942
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
2960
2963
2965 state->evalfunc_private = cstate;
2966 }
2967
2969
2972 endtime, starttime);
2973
2974 return true;
2975}
ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op)
@ EEOP_FUNCEXPR_STRICT_FUSAGE
@ EEOP_HASHDATUM_NEXT32_STRICT
@ EEOP_JSONEXPR_COERCION_FINISH
@ EEOP_HASHDATUM_FIRST_STRICT
@ EEOP_AGG_PLAIN_PERGROUP_NULLCHECK
@ EEOP_AGG_STRICT_DESERIALIZE
@ EEOP_BOOLTEST_IS_NOT_FALSE
@ EEOP_AGG_PLAIN_TRANS_BYREF
@ EEOP_AGG_PRESORTED_DISTINCT_MULTI
@ EEOP_AGG_PLAIN_TRANS_BYVAL
@ EEOP_NULLTEST_ROWISNOTNULL
@ EEOP_ASSIGN_TMP_MAKE_RO
@ EEOP_BOOL_OR_STEP_FIRST
@ EEOP_AGG_STRICT_INPUT_CHECK_NULLS
@ EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1
@ EEOP_AGG_STRICT_INPUT_CHECK_ARGS
@ EEOP_NULLTEST_ROWISNULL
@ EEOP_NULLTEST_ISNOTNULL
@ EEOP_MERGE_SUPPORT_FUNC
@ EEOP_AGG_PRESORTED_DISTINCT_SINGLE
@ EEOP_BOOL_AND_STEP_FIRST
@ EEOP_DOMAIN_TESTVAL_EXT
@ EEOP_BOOL_AND_STEP_LAST
@ EEOP_AGG_ORDERED_TRANS_DATUM
@ EEOP_HASHDATUM_SET_INITVAL
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYREF
@ EEOP_BOOLTEST_IS_NOT_TRUE
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF
@ EEOP_HASHED_SCALARARRAYOP
@ EEOP_AGG_ORDERED_TRANS_TUPLE
const TupleTableSlotOps TTSOpsVirtual
#define FIELDNO_EXPRSTATE_RESULTSLOT
#define FIELDNO_EXPRCONTEXT_CASENULL
#define FIELDNO_EXPRCONTEXT_INNERTUPLE
#define FIELDNO_EXPRSTATE_FLAGS
#define FIELDNO_EXPRCONTEXT_DOMAINNULL
#define FIELDNO_EXPRCONTEXT_DOMAINDATUM
#define FIELDNO_EXPRCONTEXT_CASEDATUM
#define FIELDNO_EXPRCONTEXT_OLDTUPLE
#define FIELDNO_AGGSTATE_CURPERTRANS
#define FIELDNO_EXPRSTATE_RESNULL
#define FIELDNO_EXPRCONTEXT_NEWTUPLE
#define FIELDNO_EXPRCONTEXT_AGGNULLS
#define FIELDNO_EXPRSTATE_RESVALUE
#define FIELDNO_AGGSTATE_CURRENT_SET
#define FIELDNO_EXPRCONTEXT_AGGVALUES
#define FIELDNO_EXPRCONTEXT_OUTERTUPLE
#define FIELDNO_AGGSTATE_ALL_PERGROUPS
#define FIELDNO_EXPRSTATE_PARENT
#define FIELDNO_EXPRCONTEXT_SCANTUPLE
#define FIELDNO_AGGSTATE_CURAGGCONTEXT
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
LLVMJitContext * llvm_create_context(int jitFlags)
LLVMTypeRef StructExprState
LLVMTypeRef TypeParamBool
LLVMTypeRef StructMemoryContextData
LLVMTypeRef StructAggStatePerGroupData
LLVMTypeRef llvm_pg_var_type(const char *varname)
char * llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
LLVMTypeRef llvm_pg_var_func_type(const char *varname)
LLVMTypeRef StructTupleTableSlot
LLVMModuleRef llvm_mutable_module(LLVMJitContext *context)
LLVMTypeRef StructAggState
LLVMTypeRef StructExprContext
LLVMTypeRef StructNullableDatum
LLVMValueRef ExecEvalSubroutineTemplate
LLVMValueRef ExecEvalBoolSubroutineTemplate
LLVMTypeRef StructAggStatePerTransData
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull)
#define build_EvalXFunc(b, mod, funcname, v_state, op,...)
static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, LLVMModuleRef mod, FunctionCallInfo fcinfo, LLVMValueRef *v_fcinfo_isnull)
void * palloc0(Size size)
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL
#define FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE
#define castNode(_type_, nodeptr)
#define FIELDNO_NULLABLE_DATUM_ISNULL
FunctionCallInfo transfn_fcinfo
struct JitContext * es_jit
MemoryContext ecxt_per_tuple_memory
struct ExprEvalStep::@57::@66 boolexpr
struct ExprEvalStep::@57::@88 hashdatum_initvalue
struct ExprEvalStep::@57::@74 iocoerce
struct ExprEvalStep::@57::@62 assign_tmp
WindowFuncExprState * wfstate
struct ExprEvalStep::@57::@97 window_func
struct ExprEvalStep::@57::@100 agg_strict_input_check
ExecEvalBoolSubroutine subscriptfunc
struct ExprEvalStep::@57::@85 sbsref_subscript
struct ExprEvalStep::@57::@80 rowcompare_step
struct ExprEvalStep::@57::@103 agg_trans
struct ExprEvalStep::@57::@95 aggref
struct ExprEvalStep::@57::@86 sbsref
struct ExprEvalStep::@57::@59 var
struct ExprEvalStep::@57::@71 cparam
struct ExprEvalStep::@57::@101 agg_plain_pergroup_nullcheck
struct ExprEvalStep::@57::@72 casetest
AggStatePerTrans pertrans
struct JsonExprState * jsestate
struct ExprEvalStep::@57::@68 jump
ExecEvalSubroutine paramfunc
struct ExprEvalStep::@57::@105 jsonexpr
struct ExprEvalStep::@57::@64 constval
FunctionCallInfo fcinfo_data_in
struct ExprEvalStep::@57::@89 hashdatum
const TupleTableSlotOps * kind
struct ExprEvalStep::@57::@102 agg_presorted_distinctcheck
struct ExprEvalStep::@57::@65 func
FunctionCallInfo fcinfo_data
struct ExprEvalStep::@57::@67 qualexpr
struct ExprEvalStep::@57::@61 assign_var
union ExprEvalStep::@57 d
struct ExprEvalStep::@57::@58 fetch
struct ExprEvalStep::@57::@63 returningexpr
FunctionCallInfo fcinfo_data_out
struct ExprEvalStep::@57::@81 rowcompare_final
struct ExprEvalStep::@57::@73 make_readonly
struct ExprEvalStep::@57::@99 agg_deserialize
#define FIELDNO_TUPLETABLESLOT_ISNULL
#define FIELDNO_TUPLETABLESLOT_VALUES
#define FIELDNO_TUPLETABLESLOT_NVALID