In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/5afbd73327c66567d331236ae7c1ad047efd945a?hp=6dace35894a5f483df6175d4ae815d2139ce317c>
- Log ----------------------------------------------------------------- commit 5afbd73327c66567d331236ae7c1ad047efd945a Author: Father Chrysostomos <[email protected]> Date: Wed Oct 15 12:58:18 2014 -0700 Elide our($foo) from execution order in void cx our($foo) in void context has a compile-time affect but no run-item effect, except to execute ops needlessly. There is no need to execute those ops. We can simply remove them from the execution order. âour($foo,$fit,$far);â still leaves a list and a pushmark, which I plan to eliminate in the next commit. âour $foo; our $bar; our $baz;â has no run-time cost now, because, once the variables are eliminated, the nextstate ops in betwen them, now adjacent, are also eliminated by another optimisation. ----------------------------------------------------------------------- Summary of changes: ext/B/t/optree_concise.t | 30 ++++++++++++------------------ ext/B/t/optree_misc.t | 44 ++++++++++++++++++++++---------------------- ext/B/t/optree_varinit.t | 12 ++++++------ lib/B/Deparse.pm | 4 ++-- op.c | 25 +++++++++++++++++++++++-- 5 files changed, 65 insertions(+), 50 deletions(-) diff --git a/ext/B/t/optree_concise.t b/ext/B/t/optree_concise.t index f9a2729..12781ac 100644 --- a/ext/B/t/optree_concise.t +++ b/ext/B/t/optree_concise.t @@ -291,26 +291,20 @@ checkOptree strip_open_hints => 1, expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); # 1 <0> enter -# 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ -# 3 <#> gv[*a] s -# 4 <1> rv2av[t3] vK/OURINTR,1 -# 5 <;> nextstate(main 2 -e:1) v:>,<,%,{ -# 6 <0> pushmark s -# 7 <#> gv[*a] s -# 8 <1> rv2av[t5] lK/1 -# 9 <@> sort vK -# a <@> leave[1 ref] vKP/REFC +# 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ +# 3 <0> pushmark s +# 4 <#> gv[*a] s +# 5 <1> rv2av[t5] lK/1 +# 6 <@> sort vK +# 7 <@> leave[1 ref] vKP/REFC EOT_EOT # 1 <0> enter -# 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ -# 3 <$> gv(*a) s -# 4 <1> rv2av[t2] vK/OURINTR,1 -# 5 <;> nextstate(main 2 -e:1) v:>,<,%,{ -# 6 <0> pushmark s -# 7 <$> gv(*a) s -# 8 <1> rv2av[t3] lK/1 -# 9 <@> sort vK -# a <@> leave[1 ref] vKP/REFC +# 2 <;> nextstate(main 2 -e:1) v:>,<,%,{ +# 3 <0> pushmark s +# 4 <$> gv(*a) s +# 5 <1> rv2av[t3] lK/1 +# 6 <@> sort vK +# 7 <@> leave[1 ref] vKP/REFC EONT_EONT diff --git a/ext/B/t/optree_misc.t b/ext/B/t/optree_misc.t index f327bfc..3133ea0 100644 --- a/ext/B/t/optree_misc.t +++ b/ext/B/t/optree_misc.t @@ -27,38 +27,38 @@ checkOptree ( name => 'OP_AELEMFAST opclass', code => sub { my @x; our @y; $x[127] + $y[-128]}, strip_open_hints => 1, expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); -# a <1> leavesub[1 ref] K/REFC,1 ->(end) -# - <@> lineseq KP ->a +# 7 <1> leavesub[1 ref] K/REFC,1 ->(end) +# - <@> lineseq KP ->7 # 1 <;> nextstate(main 634 optree_misc.t:25) v:>,<,% ->2 # 2 <0> padav[@x:634,636] vM/LVINTRO ->3 -# 3 <;> nextstate(main 635 optree_misc.t:25) v:>,<,% ->4 -# 5 <1> rv2av[t4] vK/OURINTR,1 ->6 -# 4 <#> gv[*y] s ->5 -# 6 <;> nextstate(main 636 optree_misc.t:25) v:>,<,%,{ ->7 -# 9 <2> add[t6] sK/2 ->a -# - <1> ex-aelem sK/2 ->8 -# 7 <0> aelemfast_lex[@x:634,636] sR/127 ->8 +# - <0> ex-nextstate v ->3 +# - <1> rv2av[t4] vK/OURINTR,1 ->3 +# - <#> gv[*y] s ->- +# 3 <;> nextstate(main 636 optree_misc.t:25) v:>,<,%,{ ->4 +# 6 <2> add[t6] sK/2 ->7 +# - <1> ex-aelem sK/2 ->5 +# 4 <0> aelemfast_lex[@x:634,636] sR/127 ->5 # - <0> ex-const s ->- -# - <1> ex-aelem sK/2 ->9 +# - <1> ex-aelem sK/2 ->6 # - <1> ex-rv2av sKR/1 ->- -# 8 <#> aelemfast[*y] s/128 ->9 +# 5 <#> aelemfast[*y] s/128 ->6 # - <0> ex-const s/FOLD ->- EOT_EOT -# a <1> leavesub[1 ref] K/REFC,1 ->(end) -# - <@> lineseq KP ->a +# 7 <1> leavesub[1 ref] K/REFC,1 ->(end) +# - <@> lineseq KP ->7 # 1 <;> nextstate(main 634 optree_misc.t:27) v:>,<,% ->2 # 2 <0> padav[@x:634,636] vM/LVINTRO ->3 -# 3 <;> nextstate(main 635 optree_misc.t:27) v:>,<,% ->4 -# 5 <1> rv2av[t3] vK/OURINTR,1 ->6 -# 4 <$> gv(*y) s ->5 -# 6 <;> nextstate(main 636 optree_misc.t:27) v:>,<,%,{ ->7 -# 9 <2> add[t4] sK/2 ->a -# - <1> ex-aelem sK/2 ->8 -# 7 <0> aelemfast_lex[@x:634,636] sR/127 ->8 +# - <0> ex-nextstate v ->3 +# - <1> rv2av[t3] vK/OURINTR,1 ->3 +# - <$> gv(*y) s ->- +# 3 <;> nextstate(main 636 optree_misc.t:27) v:>,<,%,{ ->4 +# 6 <2> add[t4] sK/2 ->7 +# - <1> ex-aelem sK/2 ->5 +# 4 <0> aelemfast_lex[@x:634,636] sR/127 ->5 # - <0> ex-const s ->- -# - <1> ex-aelem sK/2 ->9 +# - <1> ex-aelem sK/2 ->6 # - <1> ex-rv2av sKR/1 ->- -# 8 <$> aelemfast(*y) s/128 ->9 +# 5 <$> aelemfast(*y) s/128 ->6 # - <0> ex-const s/FOLD ->- EONT_EONT diff --git a/ext/B/t/optree_varinit.t b/ext/B/t/optree_varinit.t index ca2b59b..676d517 100644 --- a/ext/B/t/optree_varinit.t +++ b/ext/B/t/optree_varinit.t @@ -95,17 +95,17 @@ checkOptree ( name => 'our $a', bcopts => '-basic', strip_open_hints => 1, expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); -4 <@> leave[1 ref] vKP/REFC ->(end) +3 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3 -- <1> ex-rv2sv vK/17 ->4 -3 <#> gvsv[*a] s/OURINTR ->4 +- <1> rv2sv vK/OURINTR,1 ->3 +- <#> gv[*a] s ->- EOT_EOT -# 4 <@> leave[1 ref] vKP/REFC ->(end) +# 3 <@> leave[1 ref] vKP/REFC ->(end) # 1 <0> enter ->2 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3 -# - <1> ex-rv2sv vK/17 ->4 -# 3 <$> gvsv(*a) s/OURINTR ->4 +# - <1> rv2sv vK/OURINTR,1 ->3 +# - <$> gv(*a) s ->- EONT_EONT checkOptree ( name => 'local $c', diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index f821c8f..ddf2952 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -1203,10 +1203,10 @@ sub maybe_parens_func { sub find_our_type { my ($self, $name) = @_; $self->populate_curcvlex() if !defined $self->{'curcvlex'}; - my $seq = $self->{'curcop'}->cop_seq; + my $seq = $self->{'curcop'} ? $self->{'curcop'}->cop_seq : 0; for my $a (@{$self->{'curcvlex'}{"o$name"}}) { my ($st, undef, $padname) = @$a; - if ($st == $seq && $padname->FLAGS & SVpad_TYPED) { + if ($st >= $seq && $padname->FLAGS & SVpad_TYPED) { return $padname->SvSTASH->NAME; } } diff --git a/op.c b/op.c index 2217307..cfb57e4 100644 --- a/op.c +++ b/op.c @@ -12211,10 +12211,31 @@ Perl_rpeep(pTHX_ OP *o) else o->op_type = OP_AELEMFAST_LEX; } - break; + if (o->op_type != OP_GV) + break; } - if (o->op_next->op_type == OP_RV2SV) { + /* Remove $foo from the op_next chain in void context. */ + if (oldop + && ( o->op_next->op_type == OP_RV2SV + || o->op_next->op_type == OP_RV2AV + || o->op_next->op_type == OP_RV2HV ) + && (o->op_next->op_flags & OPf_WANT) == OPf_WANT_VOID + && !(o->op_next->op_private & OPpLVAL_INTRO)) + { + oldop->op_next = o->op_next->op_next; + /* Reprocess the previous op if it is a nextstate, to + allow double-nextstate optimisation. */ + if (oldop->op_type == OP_NEXTSTATE && oldoldop + && oldoldop->op_next == oldop) { + oldop->op_opt = 0; + o = oldop = oldoldop; + oldoldop = NULL; + continue; + } + o = oldop; + } + else if (o->op_next->op_type == OP_RV2SV) { if (!(o->op_next->op_private & OPpDEREF)) { op_null(o->op_next); o->op_private |= o->op_next->op_private & (OPpLVAL_INTRO -- Perl5 Master Repository
