Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite6f86f8

Browse files
committed
jit: Remove redundancies in expression evaluation code generation.
This merges the code emission for a number of opcodes by handling thebehavioural difference more locally. This reduces code, and alsoimproves the generated code a bit in some cases, by removing redundantconstants.Author: Andres FreundDiscussion:https://postgr.es/m/20191023163849.sosqbfs5yenocez3@alap3.anarazel.de
1 parent8c27694 commite6f86f8

File tree

1 file changed

+124
-153
lines changed

1 file changed

+124
-153
lines changed

‎src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 124 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ llvm_compile_expr(ExprState *state)
471471
}
472472

473473
caseEEOP_ASSIGN_TMP:
474+
caseEEOP_ASSIGN_TMP_MAKE_RO:
474475
{
475476
LLVMValueRefv_value,
476477
v_isnull;
@@ -490,59 +491,40 @@ llvm_compile_expr(ExprState *state)
490491
v_risnullp=
491492
LLVMBuildGEP(b,v_resultnulls,&v_resultnum,1,"");
492493

493-
/* and store */
494-
LLVMBuildStore(b,v_value,v_rvaluep);
494+
/* store nullness */
495495
LLVMBuildStore(b,v_isnull,v_risnullp);
496496

497-
LLVMBuildBr(b,opblocks[opno+1]);
498-
break;
499-
}
500-
501-
caseEEOP_ASSIGN_TMP_MAKE_RO:
502-
{
503-
LLVMBasicBlockRefb_notnull;
504-
LLVMValueRefv_params[1];
505-
LLVMValueRefv_ret;
506-
LLVMValueRefv_value,
507-
v_isnull;
508-
LLVMValueRefv_rvaluep,
509-
v_risnullp;
510-
LLVMValueRefv_resultnum;
511-
size_tresultnum=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+
LLVMBasicBlockRefb_notnull;
501+
LLVMValueRefv_params[1];
526502

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);
529505

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),"");
535519

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+
}
543525

544-
/* storevalue */
545-
LLVMBuildStore(b,v_ret,v_rvaluep);
526+
/*and finallystoreresult */
527+
LLVMBuildStore(b,v_value,v_rvaluep);
546528

547529
LLVMBuildBr(b,opblocks[opno+1]);
548530
break;
@@ -563,78 +545,81 @@ llvm_compile_expr(ExprState *state)
563545
break;
564546
}
565547

548+
caseEEOP_FUNCEXPR:
566549
caseEEOP_FUNCEXPR_STRICT:
567550
{
568551
FunctionCallInfofcinfo=op->d.func.fcinfo_data;
569-
LLVMBasicBlockRefb_nonull;
570-
LLVMValueRefv_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+
LLVMValueRefv_fcinfo_isnull;
553+
LLVMValueRefv_retval;
579554

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+
LLVMBasicBlockRefb_nonull;
558+
LLVMBasicBlockRef*b_checkargnulls;
559+
LLVMValueRefv_fcinfo;
583560

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);
586567

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");
592571

593-
/* create blocks for checking args, one for each */
594-
b_checkargnulls=
595-
palloc(sizeof(LLVMBasicBlockRef*)*op->d.func.nargs);
596-
for (intargno=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));
599574

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);
602580

603-
/* check each arg for NULLness */
604-
for (intargno=0;argno<op->d.func.nargs;argno++)
605-
{
606-
LLVMValueRefv_argisnull;
607-
LLVMBasicBlockRefb_argnotnull;
581+
/* create blocks for checking args, one for each */
582+
b_checkargnulls=
583+
palloc(sizeof(LLVMBasicBlockRef*)*op->d.func.nargs);
584+
for (intargno=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);
608588

609-
LLVMPositionBuilderAtEnd(b,b_checkargnulls[argno]);
589+
/* jump to check of first argument */
590+
LLVMBuildBr(b,b_checkargnulls[0]);
610591

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 (intargno=0;argno<op->d.func.nargs;argno++)
594+
{
595+
LLVMValueRefv_argisnull;
596+
LLVMBasicBlockRefb_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+
}
616619

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);
626621
}
627622

628-
LLVMPositionBuilderAtEnd(b,b_nonull);
629-
}
630-
/* FALLTHROUGH */
631-
632-
caseEEOP_FUNCEXPR:
633-
{
634-
FunctionCallInfofcinfo=op->d.func.fcinfo_data;
635-
LLVMValueRefv_fcinfo_isnull;
636-
LLVMValueRefv_retval;
637-
638623
v_retval=BuildV1Call(context,b,mod,fcinfo,
639624
&v_fcinfo_isnull);
640625
LLVMBuildStore(b,v_retval,v_resvaluep);
@@ -657,24 +642,14 @@ llvm_compile_expr(ExprState *state)
657642
LLVMBuildBr(b,opblocks[opno+1]);
658643
break;
659644

660-
caseEEOP_BOOL_AND_STEP_FIRST:
661-
{
662-
LLVMValueRefv_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-
671645
/*
672646
* Treat them the same for now, optimizer can remove
673647
* redundancy. Could be worthwhile to optimize during emission
674648
* though.
675649
*/
676-
caseEEOP_BOOL_AND_STEP_LAST:
650+
caseEEOP_BOOL_AND_STEP_FIRST:
677651
caseEEOP_BOOL_AND_STEP:
652+
caseEEOP_BOOL_AND_STEP_LAST:
678653
{
679654
LLVMValueRefv_boolvalue;
680655
LLVMValueRefv_boolnull;
@@ -700,6 +675,9 @@ llvm_compile_expr(ExprState *state)
700675
v_boolanynullp=l_ptr_const(op->d.boolexpr.anynull,
701676
l_ptr(TypeStorageBool));
702677

678+
if (opcode==EEOP_BOOL_AND_STEP_FIRST)
679+
LLVMBuildStore(b,l_sbool_const(0),v_boolanynullp);
680+
703681
v_boolnull=LLVMBuildLoad(b,v_resnullp,"");
704682
v_boolvalue=LLVMBuildLoad(b,v_resvaluep,"");
705683

@@ -759,23 +737,15 @@ llvm_compile_expr(ExprState *state)
759737
LLVMBuildBr(b,opblocks[opno+1]);
760738
break;
761739
}
762-
caseEEOP_BOOL_OR_STEP_FIRST:
763-
{
764-
LLVMValueRefv_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 */
771740

772741
/*
773742
* Treat them the same for now, optimizer can remove
774743
* redundancy. Could be worthwhile to optimize during emission
775744
* though.
776745
*/
777-
caseEEOP_BOOL_OR_STEP_LAST:
746+
caseEEOP_BOOL_OR_STEP_FIRST:
778747
caseEEOP_BOOL_OR_STEP:
748+
caseEEOP_BOOL_OR_STEP_LAST:
779749
{
780750
LLVMValueRefv_boolvalue;
781751
LLVMValueRefv_boolnull;
@@ -802,6 +772,8 @@ llvm_compile_expr(ExprState *state)
802772
v_boolanynullp=l_ptr_const(op->d.boolexpr.anynull,
803773
l_ptr(TypeStorageBool));
804774

775+
if (opcode==EEOP_BOOL_OR_STEP_FIRST)
776+
LLVMBuildStore(b,l_sbool_const(0),v_boolanynullp);
805777
v_boolnull=LLVMBuildLoad(b,v_resnullp,"");
806778
v_boolvalue=LLVMBuildLoad(b,v_resvaluep,"");
807779

@@ -1958,41 +1930,40 @@ llvm_compile_expr(ExprState *state)
19581930
break;
19591931

19601932
caseEEOP_AGG_STRICT_DESERIALIZE:
1961-
{
1962-
FunctionCallInfofcinfo=op->d.agg_deserialize.fcinfo_data;
1963-
LLVMValueRefv_fcinfo;
1964-
LLVMValueRefv_argnull0;
1965-
LLVMBasicBlockRefb_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-
19861933
caseEEOP_AGG_DESERIALIZE:
19871934
{
19881935
AggState*aggstate;
1989-
FunctionCallInfofcinfo;
1936+
FunctionCallInfofcinfo=op->d.agg_deserialize.fcinfo_data;
19901937

19911938
LLVMValueRefv_retval;
19921939
LLVMValueRefv_fcinfo_isnull;
19931940
LLVMValueRefv_tmpcontext;
19941941
LLVMValueRefv_oldcontext;
19951942

1943+
if (opcode==EEOP_AGG_STRICT_DESERIALIZE)
1944+
{
1945+
LLVMValueRefv_fcinfo;
1946+
LLVMValueRefv_argnull0;
1947+
LLVMBasicBlockRefb_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+
19961967
aggstate=castNode(AggState,state->parent);
19971968
fcinfo=op->d.agg_deserialize.fcinfo_data;
19981969

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp