@@ -471,6 +471,7 @@ llvm_compile_expr(ExprState *state)
471
471
}
472
472
473
473
case EEOP_ASSIGN_TMP :
474
+ case EEOP_ASSIGN_TMP_MAKE_RO :
474
475
{
475
476
LLVMValueRef v_value ,
476
477
v_isnull ;
@@ -490,59 +491,40 @@ llvm_compile_expr(ExprState *state)
490
491
v_risnullp =
491
492
LLVMBuildGEP (b , v_resultnulls , & v_resultnum , 1 , "" );
492
493
493
- /* and store */
494
- LLVMBuildStore (b , v_value , v_rvaluep );
494
+ /* store nullness */
495
495
LLVMBuildStore (b , v_isnull , v_risnullp );
496
496
497
- LLVMBuildBr (b , opblocks [opno + 1 ]);
498
- break ;
499
- }
500
-
501
- case EEOP_ASSIGN_TMP_MAKE_RO :
502
- {
503
- LLVMBasicBlockRef b_notnull ;
504
- LLVMValueRef v_params [1 ];
505
- LLVMValueRef v_ret ;
506
- LLVMValueRef v_value ,
507
- v_isnull ;
508
- LLVMValueRef v_rvaluep ,
509
- v_risnullp ;
510
- LLVMValueRef v_resultnum ;
511
- size_t resultnum = op -> d .assign_tmp .resultnum ;
512
-
513
- b_notnull = l_bb_before_v (opblocks [opno + 1 ],
514
- "op.%d.assign_tmp.notnull" , opno );
515
-
516
- /* load data */
517
- v_value = LLVMBuildLoad (b , v_tmpvaluep , "" );
518
- v_isnull = LLVMBuildLoad (b , v_tmpisnullp , "" );
519
-
520
- /* compute addresses of targets */
521
- v_resultnum = l_int32_const (resultnum );
522
- v_rvaluep = LLVMBuildGEP (b , v_resultvalues ,
523
- & v_resultnum , 1 , "" );
524
- v_risnullp = LLVMBuildGEP (b , v_resultnulls ,
525
- & v_resultnum , 1 , "" );
497
+ /* make value readonly if necessary */
498
+ if (opcode == EEOP_ASSIGN_TMP_MAKE_RO )
499
+ {
500
+ LLVMBasicBlockRef b_notnull ;
501
+ LLVMValueRef v_params [1 ];
526
502
527
- /* store nullness */
528
- LLVMBuildStore ( b , v_isnull , v_risnullp );
503
+ b_notnull = l_bb_before_v ( opblocks [ opno + 1 ],
504
+ "op.%d.assign_tmp.notnull" , opno );
529
505
530
- /* check if value is NULL */
531
- LLVMBuildCondBr (b ,
532
- LLVMBuildICmp (b , LLVMIntEQ , v_isnull ,
533
- l_sbool_const (0 ), "" ),
534
- b_notnull , opblocks [opno + 1 ]);
506
+ /* check if value is NULL */
507
+ LLVMBuildCondBr (b ,
508
+ LLVMBuildICmp (b , LLVMIntEQ , v_isnull ,
509
+ l_sbool_const (0 ), "" ),
510
+ b_notnull , opblocks [opno + 1 ]);
511
+
512
+ /* if value is not null, convert to RO datum */
513
+ LLVMPositionBuilderAtEnd (b , b_notnull );
514
+ v_params [0 ] = v_value ;
515
+ v_value =
516
+ LLVMBuildCall (b ,
517
+ llvm_get_decl (mod , FuncMakeExpandedObjectReadOnlyInternal ),
518
+ v_params , lengthof (v_params ), "" );
535
519
536
- /* if value is not null, convert to RO datum */
537
- LLVMPositionBuilderAtEnd (b , b_notnull );
538
- v_params [0 ] = v_value ;
539
- v_ret =
540
- LLVMBuildCall (b ,
541
- llvm_get_decl (mod , FuncMakeExpandedObjectReadOnlyInternal ),
542
- v_params , lengthof (v_params ), "" );
520
+ /*
521
+ * Falling out of the if () with builder in b_notnull,
522
+ * which is fine - the null is already stored above.
523
+ */
524
+ }
543
525
544
- /* store value */
545
- LLVMBuildStore (b , v_ret , v_rvaluep );
526
+ /* and finally store result */
527
+ LLVMBuildStore (b , v_value , v_rvaluep );
546
528
547
529
LLVMBuildBr (b , opblocks [opno + 1 ]);
548
530
break ;
@@ -563,78 +545,81 @@ llvm_compile_expr(ExprState *state)
563
545
break ;
564
546
}
565
547
548
+ case EEOP_FUNCEXPR :
566
549
case EEOP_FUNCEXPR_STRICT :
567
550
{
568
551
FunctionCallInfo fcinfo = op -> d .func .fcinfo_data ;
569
- LLVMBasicBlockRef b_nonull ;
570
- LLVMValueRef v_fcinfo ;
571
- LLVMBasicBlockRef * b_checkargnulls ;
572
-
573
- /*
574
- * Block for the actual function call, if args are
575
- * non-NULL.
576
- */
577
- b_nonull = l_bb_before_v (opblocks [opno + 1 ],
578
- "b.%d.no-null-args" , opno );
552
+ LLVMValueRef v_fcinfo_isnull ;
553
+ LLVMValueRef v_retval ;
579
554
580
- /* should make sure they're optimized beforehand */
581
- if (op -> d .func .nargs == 0 )
582
- elog (ERROR , "argumentless strict functions are pointless" );
555
+ if (opcode == EEOP_FUNCEXPR_STRICT )
556
+ {
557
+ LLVMBasicBlockRef b_nonull ;
558
+ LLVMBasicBlockRef * b_checkargnulls ;
559
+ LLVMValueRef v_fcinfo ;
583
560
584
- v_fcinfo =
585
- l_ptr_const (fcinfo , l_ptr (StructFunctionCallInfoData ));
561
+ /*
562
+ * Block for the actual function call, if args are
563
+ * non-NULL.
564
+ */
565
+ b_nonull = l_bb_before_v (opblocks [opno + 1 ],
566
+ "b.%d.no-null-args" , opno );
586
567
587
- /*
588
- * set resnull to true, if the function is actually
589
- * called, it'll be reset
590
- */
591
- LLVMBuildStore (b , l_sbool_const (1 ), v_resnullp );
568
+ /* should make sure they're optimized beforehand */
569
+ if (op -> d .func .nargs == 0 )
570
+ elog (ERROR , "argumentless strict functions are pointless" );
592
571
593
- /* create blocks for checking args, one for each */
594
- b_checkargnulls =
595
- palloc (sizeof (LLVMBasicBlockRef * ) * op -> d .func .nargs );
596
- for (int argno = 0 ; argno < op -> d .func .nargs ; argno ++ )
597
- b_checkargnulls [argno ] =
598
- l_bb_before_v (b_nonull , "b.%d.isnull.%d" , opno , argno );
572
+ v_fcinfo =
573
+ l_ptr_const (fcinfo , l_ptr (StructFunctionCallInfoData ));
599
574
600
- /* jump to check of first argument */
601
- LLVMBuildBr (b , b_checkargnulls [0 ]);
575
+ /*
576
+ * set resnull to true, if the function is actually
577
+ * called, it'll be reset
578
+ */
579
+ LLVMBuildStore (b , l_sbool_const (1 ), v_resnullp );
602
580
603
- /* check each arg for NULLness */
604
- for (int argno = 0 ; argno < op -> d .func .nargs ; argno ++ )
605
- {
606
- LLVMValueRef v_argisnull ;
607
- LLVMBasicBlockRef b_argnotnull ;
581
+ /* create blocks for checking args, one for each */
582
+ b_checkargnulls =
583
+ palloc (sizeof (LLVMBasicBlockRef * ) * op -> d .func .nargs );
584
+ for (int argno = 0 ; argno < op -> d .func .nargs ; argno ++ )
585
+ b_checkargnulls [argno ] =
586
+ l_bb_before_v (b_nonull , "b.%d.isnull.%d" , opno ,
587
+ argno );
608
588
609
- LLVMPositionBuilderAtEnd (b , b_checkargnulls [argno ]);
589
+ /* jump to check of first argument */
590
+ LLVMBuildBr (b , b_checkargnulls [0 ]);
610
591
611
- /* compute block to jump to if argument is not null */
612
- if (argno + 1 == op -> d .func .nargs )
613
- b_argnotnull = b_nonull ;
614
- else
615
- b_argnotnull = b_checkargnulls [argno + 1 ];
592
+ /* check each arg for NULLness */
593
+ for (int argno = 0 ; argno < op -> d .func .nargs ; argno ++ )
594
+ {
595
+ LLVMValueRef v_argisnull ;
596
+ LLVMBasicBlockRef b_argnotnull ;
597
+
598
+ LLVMPositionBuilderAtEnd (b , b_checkargnulls [argno ]);
599
+
600
+ /*
601
+ * Compute block to jump to if argument is not
602
+ * null.
603
+ */
604
+ if (argno + 1 == op -> d .func .nargs )
605
+ b_argnotnull = b_nonull ;
606
+ else
607
+ b_argnotnull = b_checkargnulls [argno + 1 ];
608
+
609
+ /* and finally load & check NULLness of arg */
610
+ v_argisnull = l_funcnull (b , v_fcinfo , argno );
611
+ LLVMBuildCondBr (b ,
612
+ LLVMBuildICmp (b , LLVMIntEQ ,
613
+ v_argisnull ,
614
+ l_sbool_const (1 ),
615
+ "" ),
616
+ opblocks [opno + 1 ],
617
+ b_argnotnull );
618
+ }
616
619
617
- /* and finally load & check NULLness of arg */
618
- v_argisnull = l_funcnull (b , v_fcinfo , argno );
619
- LLVMBuildCondBr (b ,
620
- LLVMBuildICmp (b , LLVMIntEQ ,
621
- v_argisnull ,
622
- l_sbool_const (1 ),
623
- "" ),
624
- opblocks [opno + 1 ],
625
- b_argnotnull );
620
+ LLVMPositionBuilderAtEnd (b , b_nonull );
626
621
}
627
622
628
- LLVMPositionBuilderAtEnd (b , b_nonull );
629
- }
630
- /* FALLTHROUGH */
631
-
632
- case EEOP_FUNCEXPR :
633
- {
634
- FunctionCallInfo fcinfo = op -> d .func .fcinfo_data ;
635
- LLVMValueRef v_fcinfo_isnull ;
636
- LLVMValueRef v_retval ;
637
-
638
623
v_retval = BuildV1Call (context , b , mod , fcinfo ,
639
624
& v_fcinfo_isnull );
640
625
LLVMBuildStore (b , v_retval , v_resvaluep );
@@ -657,24 +642,14 @@ llvm_compile_expr(ExprState *state)
657
642
LLVMBuildBr (b , opblocks [opno + 1 ]);
658
643
break ;
659
644
660
- case EEOP_BOOL_AND_STEP_FIRST :
661
- {
662
- LLVMValueRef v_boolanynullp ;
663
-
664
- v_boolanynullp = l_ptr_const (op -> d .boolexpr .anynull ,
665
- l_ptr (TypeStorageBool ));
666
- LLVMBuildStore (b , l_sbool_const (0 ), v_boolanynullp );
667
-
668
- }
669
- /* FALLTHROUGH */
670
-
671
645
/*
672
646
* Treat them the same for now, optimizer can remove
673
647
* redundancy. Could be worthwhile to optimize during emission
674
648
* though.
675
649
*/
676
- case EEOP_BOOL_AND_STEP_LAST :
650
+ case EEOP_BOOL_AND_STEP_FIRST :
677
651
case EEOP_BOOL_AND_STEP :
652
+ case EEOP_BOOL_AND_STEP_LAST :
678
653
{
679
654
LLVMValueRef v_boolvalue ;
680
655
LLVMValueRef v_boolnull ;
@@ -700,6 +675,9 @@ llvm_compile_expr(ExprState *state)
700
675
v_boolanynullp = l_ptr_const (op -> d .boolexpr .anynull ,
701
676
l_ptr (TypeStorageBool ));
702
677
678
+ if (opcode == EEOP_BOOL_AND_STEP_FIRST )
679
+ LLVMBuildStore (b , l_sbool_const (0 ), v_boolanynullp );
680
+
703
681
v_boolnull = LLVMBuildLoad (b , v_resnullp , "" );
704
682
v_boolvalue = LLVMBuildLoad (b , v_resvaluep , "" );
705
683
@@ -759,23 +737,15 @@ llvm_compile_expr(ExprState *state)
759
737
LLVMBuildBr (b , opblocks [opno + 1 ]);
760
738
break ;
761
739
}
762
- case EEOP_BOOL_OR_STEP_FIRST :
763
- {
764
- LLVMValueRef v_boolanynullp ;
765
-
766
- v_boolanynullp = l_ptr_const (op -> d .boolexpr .anynull ,
767
- l_ptr (TypeStorageBool ));
768
- LLVMBuildStore (b , l_sbool_const (0 ), v_boolanynullp );
769
- }
770
- /* FALLTHROUGH */
771
740
772
741
/*
773
742
* Treat them the same for now, optimizer can remove
774
743
* redundancy. Could be worthwhile to optimize during emission
775
744
* though.
776
745
*/
777
- case EEOP_BOOL_OR_STEP_LAST :
746
+ case EEOP_BOOL_OR_STEP_FIRST :
778
747
case EEOP_BOOL_OR_STEP :
748
+ case EEOP_BOOL_OR_STEP_LAST :
779
749
{
780
750
LLVMValueRef v_boolvalue ;
781
751
LLVMValueRef v_boolnull ;
@@ -802,6 +772,8 @@ llvm_compile_expr(ExprState *state)
802
772
v_boolanynullp = l_ptr_const (op -> d .boolexpr .anynull ,
803
773
l_ptr (TypeStorageBool ));
804
774
775
+ if (opcode == EEOP_BOOL_OR_STEP_FIRST )
776
+ LLVMBuildStore (b , l_sbool_const (0 ), v_boolanynullp );
805
777
v_boolnull = LLVMBuildLoad (b , v_resnullp , "" );
806
778
v_boolvalue = LLVMBuildLoad (b , v_resvaluep , "" );
807
779
@@ -1958,41 +1930,40 @@ llvm_compile_expr(ExprState *state)
1958
1930
break ;
1959
1931
1960
1932
case EEOP_AGG_STRICT_DESERIALIZE :
1961
- {
1962
- FunctionCallInfo fcinfo = op -> d .agg_deserialize .fcinfo_data ;
1963
- LLVMValueRef v_fcinfo ;
1964
- LLVMValueRef v_argnull0 ;
1965
- LLVMBasicBlockRef b_deserialize ;
1966
-
1967
- b_deserialize = l_bb_before_v (opblocks [opno + 1 ],
1968
- "op.%d.deserialize" , opno );
1969
-
1970
- v_fcinfo = l_ptr_const (fcinfo ,
1971
- l_ptr (StructFunctionCallInfoData ));
1972
- v_argnull0 = l_funcnull (b , v_fcinfo , 0 );
1973
-
1974
- LLVMBuildCondBr (b ,
1975
- LLVMBuildICmp (b ,
1976
- LLVMIntEQ ,
1977
- v_argnull0 ,
1978
- l_sbool_const (1 ),
1979
- "" ),
1980
- opblocks [op -> d .agg_deserialize .jumpnull ],
1981
- b_deserialize );
1982
- LLVMPositionBuilderAtEnd (b , b_deserialize );
1983
- }
1984
- /* FALLTHROUGH */
1985
-
1986
1933
case EEOP_AGG_DESERIALIZE :
1987
1934
{
1988
1935
AggState * aggstate ;
1989
- FunctionCallInfo fcinfo ;
1936
+ FunctionCallInfo fcinfo = op -> d . agg_deserialize . fcinfo_data ;
1990
1937
1991
1938
LLVMValueRef v_retval ;
1992
1939
LLVMValueRef v_fcinfo_isnull ;
1993
1940
LLVMValueRef v_tmpcontext ;
1994
1941
LLVMValueRef v_oldcontext ;
1995
1942
1943
+ if (opcode == EEOP_AGG_STRICT_DESERIALIZE )
1944
+ {
1945
+ LLVMValueRef v_fcinfo ;
1946
+ LLVMValueRef v_argnull0 ;
1947
+ LLVMBasicBlockRef b_deserialize ;
1948
+
1949
+ b_deserialize = l_bb_before_v (opblocks [opno + 1 ],
1950
+ "op.%d.deserialize" , opno );
1951
+
1952
+ v_fcinfo = l_ptr_const (fcinfo ,
1953
+ l_ptr (StructFunctionCallInfoData ));
1954
+ v_argnull0 = l_funcnull (b , v_fcinfo , 0 );
1955
+
1956
+ LLVMBuildCondBr (b ,
1957
+ LLVMBuildICmp (b ,
1958
+ LLVMIntEQ ,
1959
+ v_argnull0 ,
1960
+ l_sbool_const (1 ),
1961
+ "" ),
1962
+ opblocks [op -> d .agg_deserialize .jumpnull ],
1963
+ b_deserialize );
1964
+ LLVMPositionBuilderAtEnd (b , b_deserialize );
1965
+ }
1966
+
1996
1967
aggstate = castNode (AggState , state -> parent );
1997
1968
fcinfo = op -> d .agg_deserialize .fcinfo_data ;
1998
1969
0 commit comments