In perl.git, the branch smoke-me/davem/pushre has been created

<http://perl5.git.perl.org/perl.git/commitdiff/96daa60182cbc16b20f54959b023447a280782ee?hp=0000000000000000000000000000000000000000>

        at  96daa60182cbc16b20f54959b023447a280782ee (commit)

- Log -----------------------------------------------------------------
commit 96daa60182cbc16b20f54959b023447a280782ee
Author: David Mitchell <[email protected]>
Date:   Mon Sep 19 16:42:45 2016 +0100

    Concise.pm: extract padname code and fixup split
    
    The code that prints '$i:1,2'' in something like 'padsv[$i:1,2]':
    extract it out into a separate function, then use it with  split
    to display the array name rather than just a target number in:
    
        $ perl -MO=Concise -e'my @a = split()'
        ...
        split(/" "/ => @a:1,2)[t2] vK/LVINTRO,RTIME,ASSIGN,LEX,IMPLIM ->6

M       ext/B/B/Concise.pm

commit 3fa2e287a2233b0e3114a4f85ce4e2935fe07468
Author: David Mitchell <[email protected]>
Date:   Mon Sep 19 15:39:34 2016 +0100

    fix common assign issue on @a = (split(), 1)
    
    RT #127999 Slowdown in split + list assign
    
    The compile-time common-value detection mechanism for OP_ASSIGN
    was getting OP_SPLIT wrong.
    
    It was assuming that OP_SPLIT was always dangerous. In fact,
    OP_SPLIT is usually completely safe, not passing though any of its
    arguments, except where the assign in (@a = split()) has been optimised
    away and the array attached directly to the OP_SPLIT op, or the ops that
    produce the array have been appended as an extra child of the OP_SPLIT op
    (OPf_STACKED).

M       op.c
M       t/perf/benchmarks
M       t/perf/optree.t

commit 4dd47e36995451d7a5400a12f244c5ce5ab8b678
Author: David Mitchell <[email protected]>
Date:   Mon Sep 19 12:35:13 2016 +0100

    Better optimise my/local @a = split()
    
    There are currently two optimisations for when the results of a split
    are assigned to an array.
    
    For the first,
    
        @array = split(...);
    
    the aassign and padav/rv2av are optimised away, and pp_split() directly
    assigns to the array attached to the split op (via op_pmtargetoff or
    op_pmtargetgv).
    
    For the second,
    
        my @array    = split(...);
        local @array = split(...);
        @{$expr}     = split(...);
    
    The aassign is optimised away, but the padav/rv2av is kept as an additional
    arg to split. pp_split itself then uses the first arg popped off the stack
    as the array (This was introduced by FC with v5.21.4-409-gef7999f).
    
    This commit moves these two:
    
        my @array    = split(...);
        local @array = split(...);
    
    from the second case to the first case, by simply setting OPpLVAL_INTRO
    on the OP_SPLIT, and making pp_split() do SAVECLEARSV() or save_ary()
    as appropriate.
    
    This makes my @a = split(...) a few percent faster.

M       ext/B/B/Concise.pm
M       lib/B/Deparse.pm
M       lib/B/Op_private.pm
M       op.c
M       opcode.h
M       pp.c
M       regen/op_private
M       t/op/split.t
M       t/perf/benchmarks
M       t/perf/opcount.t

commit 4562efc3f24e7e4dc4ad4dabbc7cf1c33e8671d8
Author: David Mitchell <[email protected]>
Date:   Sun Sep 18 16:13:41 2016 +0100

    re-indent block in Perl_newASSIGNOP
    
    Whitepace-only change.
    
    This is a followup to the previous commit, which simplified that code
    somewhat.

M       op.c

commit e505c6fa5fa71fde220a84dd42edbcb3b3c82566
Author: David Mitchell <[email protected]>
Date:   Thu Sep 15 10:59:37 2016 +0100

    make OP_SPLIT a PMOP, and eliminate OP_PUSHRE
    
    Most ops that execute a regex, such as match and subst, are of type PMOP.
    A PMOP allows the actual regex to be attached directly to that op, due
    to its extra fields.
    
    OP_SPLIT is different; it is just a plain LISTOP, but it always has an
    OP_PUSHRE as its first child, which *is* a PMOP and which has the regex
    attached.
    
    At runtime, pp_pushre()'s only job is to push itself (i.e. the current
    PL_op) onto the stack. Later pp_split() pops this to get access to the
    regex it wants to execute.
    
    This is a bit unpleasant, because we're pushing an OP* onto the stack,
    which is supposed to be an array of SV*'s. As a bit of a hack, on
    DEBUGGING builds we push a PVLV with the PL_op address embedded instead,
    but this still isn't very satisfactory.
    
    Now that regexes are first-class SVs, we could push a REGEXP onto the
    stack rather than PL_op. However, there is an optimisation of @array =
    split which eliminates the assign and embeds the array's GV/padix directly
    in the PUSHRE op. So split still needs access to that op. But the pushre
    op will always be splitop->op_first anyway, so one possibility is to just
    skip executing the pushre altogether, and make pp_split just directly
    access op_first instead to get the regex and @array info.
    
    But if we're doing that, then why not just go the full hog and make
    OP_SPLIT into a PMOP, and eliminate the OP_PUSHRE op entirely: with the
    data that was spread across the two ops now combined into just the one
    split op.
    
    That is exactly what this commit does.
    
    For a simple compile-time pattern like  split(/foo/, $s, 1), the optree
    looks like:
    
        before:
            <@> split[t2] lK
               </> pushre(/"foo"/) s/RTIME
               <0> padsv[$s:1,2] s
               <$> const(IV 1) s
    
        after:
            </> split(/"foo"/)[t2] lK/RTIME
               <0> padsv[$s:1,2] s
               <$> const[IV 1] s
    
    while for a run-time expression like split(/$pat/, $s, 1),
    
        before:
            <@> split[t3] lK
               </> pushre() sK/RTIME
                  <|> regcomp(other->8) sK
                     <0> padsv[$pat:2,3] s
               <0> padsv[$s:1,3] s
               <$> const(IV 1)s
    
        after:
            </> split()[t3] lK/RTIME
               <|> regcomp(other->8) sK
                  <0> padsv[$pat:2,3] s
               <0> padsv[$s:1,3] s
               <$> const[IV 1] s
    
    This makes the code faster and simpler.
    
    At the same time, two new private flags have been added for OP_SPLIT -
    OPpSPLIT_ASSIGN and OPpSPLIT_LEX - which make it explicit that the
    assign op has been optimised away, and if so, whether the array is
    lexical.
    
    Also, deparsing of split has been improved, to the extent that
    
        perl TEST -deparse op/split.t
    
    now passes.
    
    Also, a couple of panic messages in pp_split() have been replaced with
    asserts().

M       Porting/deparse-skips.txt
M       cpan/B-Debug/t/debug.t
M       dist/Safe/t/safeops.t
M       dump.c
M       embed.fnc
M       ext/B/B.pm
M       ext/B/B.xs
M       ext/B/B/Concise.pm
M       ext/B/t/b.t
M       ext/B/t/optree_concise.t
M       ext/B/t/walkoptree.t
M       ext/Opcode/Opcode.pm
M       lib/B/Deparse.pm
M       lib/B/Deparse.t
M       lib/B/Op_private.pm
M       op.c
M       op.h
M       opcode.h
M       opnames.h
M       pod/perldiag.pod
M       pp.c
M       pp_ctl.c
M       pp_hot.c
M       pp_proto.h
M       proto.h
M       regen/op_private
M       regen/opcodes
M       regexp.h
M       t/op/split.t
M       t/perf/benchmarks
-----------------------------------------------------------------------

--
Perl5 Master Repository

Reply via email to