diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-10-20 17:16:01 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-10-20 17:51:51 -0700 |
commit | 8538e2d4d47f3b235052cbaabfe1aa035ae18916 (patch) | |
tree | 111a5d2413e691c0db3ae60c2707411dfa022b79 /lib | |
parent | 40ba772c3f3fa292e5635bb62c0a68609c27fcdb (diff) | |
download | perl-8538e2d4d47f3b235052cbaabfe1aa035ae18916.tar.gz |
Rmv restrictions on op tree structure for padrange
The padrange optimisation was only happening if the op tree was laid
out in a way that would allow B::Deparse easily to restore the origi-
nal op_next pointers (via $B::overlay) for the sake of deparsing.
It turns out that B::Deparse doesn’t even use the op_next pointers
(except for deparsing ‘use’ statements, which are not affected here),
so there is no need for these restrictions.
In the case of my($a,$b)=@_, @_ was expected to be the sibling of the
preceding pushmark-cum-padrange. Removing that restriction doesn’t
allow the padrange optimisation to happen in any new cases as far as I
can tell. It just means there is less checking to do.
In the more general case of a list of lexicals with no =@_, this
allows padrange to be used for array and hash slices in conjunction
with a separate list-in-list-context optimisation, that formerly con-
flicted with padrange.
When we compile @a[$lex1,$lex2], we end up with a redundant list-in-
list-context:
7 aslice
1 pushmark
5 list
2 pushmark
3 padsv
4 padsv
6 padav (assuming the array is lexical
Pushmark pushes a mark on to the markstack, and list pops one, so
pushmark and list cancel each other out in list context.
In 5.18, when padrange was introduced, this was optimised like this:
5 aslice
1 pushmark
3 list
2 padrange
- padsv
- padsv
4 padav
Then a separate optimisation was added in 5.20 that allows a list
with a pushmark kid to turn into null ops, and this cancelled out
the padrange:
5 aslice
1 pushmark
- ex-list
- ex-pushmark
2 padsv
3 padsv
4 padav
Bunchmarks show that this is slightly faster than padrange with two
lexicals, but more lexicals would make padrange faster. This commit
brings us the goodness of both optimisations at once:
3 aslice
1 padrange
- ex-list
- ex-pushmark
- padsv
- padsv
2 padav
And it is faster than just one optimisation.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/B/Deparse.pm | 3 |
1 files changed, 0 insertions, 3 deletions
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index 3866f328b4..dd848e3043 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -358,9 +358,6 @@ sub _pessimise_walk { type => OP_PUSHMARK, name => 'pushmark', private => ($op->private & OPpLVAL_INTRO), - next => ($op->flags & OPf_SPECIAL) - ? $op->sibling->first - : $op->sibling, }; } |