Skip to content

Commit f5932f8

Browse files
committed
perf/opcount.t: ensure imported builtins are optimized
When I saw (in #23429) that use builtin qw(indexed); sub { for my ($x, $y) (indexed) {} } crashes, but sub { for my ($x, $y) (builtin::indexed) {} } works fine, I realized that optrees for calls to lexically imported subs look different from calls to package subs. This commit make sure both call variants are optimized to direct ops.
1 parent 48ccf3e commit f5932f8

File tree

1 file changed

+124
-5
lines changed

1 file changed

+124
-5
lines changed

t/perf/opcount.t

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,21 @@ test_opcount(0, "multiconcat: local assign",
698698

699699
# builtin:: function calls should be replaced with efficient op implementations
700700
no warnings 'experimental::builtin';
701+
use builtin qw(
702+
blessed
703+
ceil
704+
false
705+
floor
706+
indexed
707+
is_bool
708+
is_tainted
709+
is_weak
710+
refaddr
711+
reftype
712+
true
713+
unweaken
714+
weaken
715+
);
701716

702717
test_opcount(0, "builtin::true/false are replaced with constants",
703718
sub { my $x = builtin::true(); my $y = builtin::false() },
@@ -706,6 +721,13 @@ test_opcount(0, "builtin::true/false are replaced with constants",
706721
const => 2,
707722
});
708723

724+
test_opcount(0, "imported true/false are replaced with constants",
725+
sub { my $x = true(); my $y = false() },
726+
{
727+
entersub => 0,
728+
const => 2,
729+
});
730+
709731
test_opcount(0, "builtin::is_bool is replaced with direct opcode",
710732
sub { my $x; my $y; $y = builtin::is_bool($x); 1; },
711733
{
@@ -715,6 +737,15 @@ test_opcount(0, "builtin::is_bool is replaced with direct opcode",
715737
padsv_store => 1,
716738
});
717739

740+
test_opcount(0, "imported is_bool is replaced with direct opcode",
741+
sub { my $x; my $y; $y = is_bool($x); 1; },
742+
{
743+
entersub => 0,
744+
is_bool => 1,
745+
padsv => 3,
746+
padsv_store => 1,
747+
});
748+
718749
test_opcount(0, "builtin::is_bool gets constant-folded",
719750
sub { builtin::is_bool(123); },
720751
{
@@ -723,48 +754,98 @@ test_opcount(0, "builtin::is_bool gets constant-folded",
723754
const => 1,
724755
});
725756

757+
test_opcount(0, "imported is_bool gets constant-folded",
758+
sub { is_bool(123); },
759+
{
760+
entersub => 0,
761+
is_bool => 0,
762+
const => 1,
763+
});
764+
726765
test_opcount(0, "builtin::weaken is replaced with direct opcode",
727766
sub { my $x = []; builtin::weaken($x); },
728767
{
729768
entersub => 0,
730769
weaken => 1,
731770
});
732771

772+
test_opcount(0, "imported weaken is replaced with direct opcode",
773+
sub { my $x = []; weaken($x); },
774+
{
775+
entersub => 0,
776+
weaken => 1,
777+
});
778+
733779
test_opcount(0, "builtin::unweaken is replaced with direct opcode",
734780
sub { my $x = []; builtin::unweaken($x); },
735781
{
736782
entersub => 0,
737783
unweaken => 1,
738784
});
739785

786+
test_opcount(0, "imported unweaken is replaced with direct opcode",
787+
sub { my $x = []; unweaken($x); },
788+
{
789+
entersub => 0,
790+
unweaken => 1,
791+
});
792+
740793
test_opcount(0, "builtin::is_weak is replaced with direct opcode",
741794
sub { builtin::is_weak([]); },
742795
{
743796
entersub => 0,
744797
is_weak => 1,
745798
});
746799

800+
test_opcount(0, "imported is_weak is replaced with direct opcode",
801+
sub { is_weak([]); },
802+
{
803+
entersub => 0,
804+
is_weak => 1,
805+
});
806+
747807
test_opcount(0, "builtin::blessed is replaced with direct opcode",
748808
sub { builtin::blessed([]); },
749809
{
750810
entersub => 0,
751811
blessed => 1,
752812
});
753813

814+
test_opcount(0, "imported blessed is replaced with direct opcode",
815+
sub { blessed([]); },
816+
{
817+
entersub => 0,
818+
blessed => 1,
819+
});
820+
754821
test_opcount(0, "builtin::refaddr is replaced with direct opcode",
755822
sub { builtin::refaddr([]); },
756823
{
757824
entersub => 0,
758825
refaddr => 1,
759826
});
760827

828+
test_opcount(0, "imported refaddr is replaced with direct opcode",
829+
sub { refaddr([]); },
830+
{
831+
entersub => 0,
832+
refaddr => 1,
833+
});
834+
761835
test_opcount(0, "builtin::reftype is replaced with direct opcode",
762836
sub { builtin::reftype([]); },
763837
{
764838
entersub => 0,
765839
reftype => 1,
766840
});
767841

842+
test_opcount(0, "imported reftype is replaced with direct opcode",
843+
sub { reftype([]); },
844+
{
845+
entersub => 0,
846+
reftype => 1,
847+
});
848+
768849
my $one_point_five = 1.5; # Prevent const-folding.
769850
test_opcount(0, "builtin::ceil is replaced with direct opcode",
770851
sub { builtin::ceil($one_point_five); },
@@ -773,20 +854,41 @@ test_opcount(0, "builtin::ceil is replaced with direct opcode",
773854
ceil => 1,
774855
});
775856

857+
test_opcount(0, "imported ceil is replaced with direct opcode",
858+
sub { ceil($one_point_five); },
859+
{
860+
entersub => 0,
861+
ceil => 1,
862+
});
863+
776864
test_opcount(0, "builtin::floor is replaced with direct opcode",
777865
sub { builtin::floor($one_point_five); },
778866
{
779867
entersub => 0,
780868
floor => 1,
781869
});
782870

871+
test_opcount(0, "imported floor is replaced with direct opcode",
872+
sub { floor($one_point_five); },
873+
{
874+
entersub => 0,
875+
floor => 1,
876+
});
877+
783878
test_opcount(0, "builtin::is_tainted is replaced with direct opcode",
784879
sub { builtin::is_tainted($0); },
785880
{
786881
entersub => 0,
787882
is_tainted => 1,
788883
});
789884

885+
test_opcount(0, "imported is_tainted is replaced with direct opcode",
886+
sub { is_tainted($0); },
887+
{
888+
entersub => 0,
889+
is_tainted => 1,
890+
});
891+
790892
# void sassign + padsv combinations are replaced by padsv_store
791893
test_opcount(0, "sassign + padsv replaced by padsv_store",
792894
sub { my $y; my $z = $y = 3; 1; },
@@ -1014,18 +1116,35 @@ test_opcount(0, "Empty anonhash ref and direct lexical assignment",
10141116
test_opcount(0, "foreach 2 lexicals on builtin::indexed ARRAY",
10151117
sub { my @input = (); foreach my ($i, $x) (builtin::indexed @input) { } },
10161118
{
1017-
entersub => 0, # no call to builtin::indexed
1119+
entersub => 0, # no call to builtin::indexed
10181120
enteriter => 1,
1019-
iter => 1,
1020-
padav => 2,
1121+
iter => 1,
1122+
padav => 2,
1123+
});
1124+
1125+
test_opcount(0, "foreach 2 lexicals on imported indexed ARRAY",
1126+
sub { my @input = (); foreach my ($i, $x) (indexed @input) { } },
1127+
{
1128+
entersub => 0, # no call to builtin::indexed
1129+
enteriter => 1,
1130+
iter => 1,
1131+
padav => 2,
10211132
});
10221133

10231134
test_opcount(0, "foreach 2 lexicals on builtin::indexed LIST",
10241135
sub { foreach my ($i, $x) (builtin::indexed qw( x y z )) { } },
10251136
{
1026-
entersub => 0, # no call to builtin::indexed
1137+
entersub => 0, # no call to builtin::indexed
1138+
enteriter => 1,
1139+
iter => 1,
1140+
});
1141+
1142+
test_opcount(0, "foreach 2 lexicals on imported indexed LIST",
1143+
sub { foreach my ($i, $x) (indexed qw( x y z )) { } },
1144+
{
1145+
entersub => 0, # no call to builtin::indexed
10271146
enteriter => 1,
1028-
iter => 1,
1147+
iter => 1,
10291148
});
10301149

10311150
# substr with const zero offset and "" replacements

0 commit comments

Comments
 (0)