In perl.git, the branch smueller/fewer_listops4 has been created <http://perl5.git.perl.org/perl.git/commitdiff/9b0393d15f1224e3544907d41c25cfcf4b7b0636?hp=0000000000000000000000000000000000000000>
at 9b0393d15f1224e3544907d41c25cfcf4b7b0636 (commit) - Log ----------------------------------------------------------------- commit 9b0393d15f1224e3544907d41c25cfcf4b7b0636 Author: Steffen Mueller <smuel...@cpan.org> Date: Sat Feb 22 10:08:25 2014 +0100 WIP: Optimization: Remove needless list/pushmark pairs from the OP execution This is an optimization for OP trees that involve list OPs in list context. In list context, the list OP's first child, a pushmark, will do what its name claims and push a mark. Then the list's other children will do their stack pushing. Finally, the list OP will be executed and do nothing but undo what the pushmark has done. This is because the main effect of the list OP only really kicks in if it's not in array context (actually, it should probably only kick in if it's in scalar context, but I don't know of any valid examples of list OPs in void contexts). This optimization is quite a measurable speed-up for array or hash slicing and some other situations. Another (contrived) example is that (1,2,(3,4)) now actually is the same, performance-wise as (1,2,3,4), albeit that's rarely relevant. The price to pay for this is a slightly convoluted (by standards other than the perl core) bit of optimization logic that has to do single-OP look-ahead on any OP in the peephole optimizer. WIP! Right now, some tests still fail, but on quick inspection, those are exclusively OP-tree inspecting tests. Citation required. This raises an interesting point: This is a relatively significant change to the structure of some OP trees, particularly when dumped with the -exec option of B::Concise. The OP tree checking tests have a Perl-version-dependent-test feature, but that seems inadequate to encompass changes this significant to the test output. What to do? The change includes modifying B::Deparse to handle the new cases. M embed.fnc M embed.h M lib/B/Deparse.pm M op.c M proto.h commit f0eaab20696ac3da76e8af751544dfafc8d313f7 Author: Steffen Mueller <smuel...@cpan.org> Date: Fri Feb 21 18:58:04 2014 +0100 Macro for common OP checks: "is this X or was it before NULLing?" For example, if (OP_TYPE_IS_OR_WAS(o, OP_LIST)) ... is now available instead of either of the following: if ( o && ( o->op_type == OP_LIST || (o->op_type == OP_NULL && o->op_targ == OP_LIST) ) ) ... if ( o && (o->op_type == OP_NULL ? o->op_targ ? o->op_type) == OP_LIST ) ... In case the above logic is a bit unclear: It checks whether that OP is an OP_LIST or used to be one before being NULLed using op_null. (FTR, the resulting OP_NULLs have their op_targ set to the old OP type). This sort of check (and it's reverse "isn't and didn't use to be") are a relatively common pattern in the part of op.c that tries to intuit structures from optimization-mangled OP trees. Hopefully, using these macros will make some code a fair amount clearer. M op.c M op.h ----------------------------------------------------------------------- -- Perl5 Master Repository