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

Reply via email to