Skip to content

Commit abd3ade

Browse files
committed
OP_EMPTYAVHV - optimized empty ANONLIST/ANONHASH
This commit introduces a new OP to replace cases of OP_ANONLIST and OP_ANONHASH where there are zero elements, which is very common in Perl code. As an example, `my $x = {}` is currently implemented like this: ... 6 <2> sassign vKS/2 ->7 4 <@> anonhash sK* ->5 3 <0> pushmark s ->4 5 <0> padsv[$x:1,2] sRM*/LVINTRO ->6 The pushmark serves no meaningful purpose when there are zero elements and the anonhash, besides undoing the pushmark, performs work that is unnecessary for this special case. The peephole optimizer, which also checks for applicability of a related TARGMY optimization, transforms this example into: ... - <1> ex-sassign vKS/2 ->4 3 <@> emptyavhv[$x:1,2] vK*/LVINTRO,ANONHASH,TARGMY ->4 - <0> ex-pushmark s ->3 - <0> ex-padsv sRM*/LVINTRO ->-
1 parent e63223c commit abd3ade

File tree

12 files changed

+663
-402
lines changed

12 files changed

+663
-402
lines changed

ext/Opcode/Opcode.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ invert_opset function.
336336
warn die lineseq nextstate scope enter leave
337337
338338
rv2cv anoncode prototype coreargs avhvswitch anonconst
339+
emptyavhv
339340
340341
entersub leavesub leavesublv return method method_named
341342
method_super method_redir method_redir_super

lib/B/Deparse.pm

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
1414
OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
1515
OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL OPf_MOD OPf_PARENS
1616
OPpLVAL_INTRO OPpOUR_INTRO OPpENTERSUB_AMPER OPpSLICE OPpKVSLICE
17-
OPpCONST_BARE
17+
OPpCONST_BARE OPpEMPTYAVHV_IS_HV
1818
OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY
1919
OPpEXISTS_SUB OPpSORT_NUMERIC OPpSORT_INTEGER OPpREPEAT_DOLIST
2020
OPpSORT_REVERSE OPpMULTIDEREF_EXISTS OPpMULTIDEREF_DELETE
@@ -2785,6 +2785,21 @@ sub pp_anonlist {
27852785

27862786
*pp_anonhash = \&pp_anonlist;
27872787

2788+
sub pp_emptyavhv {
2789+
my $self = shift;
2790+
my ($op, $cx, $forbid_parens) = @_;
2791+
my $val = ($op->private & OPpEMPTYAVHV_IS_HV) ? '{}' : '[]';
2792+
if ($op->private & OPpTARGET_MY) {
2793+
my $targ = $op->targ;
2794+
my $var = $self->maybe_my($op, $cx, $self->padname($targ),
2795+
$self->padname_sv($targ),
2796+
$forbid_parens);
2797+
return $self->maybe_parens("$var = $val", $cx, 7);
2798+
} else {
2799+
return $val;
2800+
}
2801+
}
2802+
27882803
sub pp_refgen {
27892804
my $self = shift;
27902805
my($op, $cx) = @_;

lib/B/Op_private.pm

Lines changed: 10 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)