diff options
author | David Mitchell <davem@iabyn.com> | 2017-07-10 15:48:02 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-07-27 11:30:22 +0100 |
commit | 748f2c65599942147442f443949449a965f6d608 (patch) | |
tree | e0ccd923e221f95c7ddb80fc5c6c4c42c85c5a8f /ext | |
parent | 4fa080dbc664ee90dd374a9a49ac0a4932421bd7 (diff) | |
download | perl-748f2c65599942147442f443949449a965f6d608.tar.gz |
optimise away OP_KEYS op in scalar/void context
In something like
if (keys %h) { ... }
the 'keys %h' is implemented as the op sequences
gv[*h] s
rv2hv lKRM/1
keys[t2] sK/1
or
padhv[%h:1,6] lRM
keys[t2] sK/1
It turns out that (%h) in scalar and void context now behaves very
similarly to (keys %h) (except that it reset the iterator), so in these
cases, convert the two ops
rv2hv/padhv, keys
into the single op
rv2hv/padhv
with a private flag indicating that the op is handling the 'keys' action
by itself.
As well as one less op to execute, this brings the boolean-context
optimisation already present in padhv/rv2sv to keys. So
if (keys %h) { ... }
is no longer slower than
if (%h) { ... }
Diffstat (limited to 'ext')
-rw-r--r-- | ext/B/t/f_map.t | 32 | ||||
-rw-r--r-- | ext/B/t/f_sort.t | 6 | ||||
-rw-r--r-- | ext/B/t/optree_samples.t | 16 |
3 files changed, 24 insertions, 30 deletions
diff --git a/ext/B/t/f_map.t b/ext/B/t/f_map.t index a1cbc38c01..96cea4a495 100644 --- a/ext/B/t/f_map.t +++ b/ext/B/t/f_map.t @@ -108,7 +108,7 @@ checkOptree(note => q{}, # goto 7 # g <0> pushmark s # h <#> gv[*hash] s -# i <1> rv2hv lKRM*/1 +# i <1> rv2hv lKRM* # j <2> aassign[t10] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -130,7 +130,7 @@ EOT_EOT # goto 7 # g <0> pushmark s # h <$> gv(*hash) s -# i <1> rv2hv lKRM*/1 +# i <1> rv2hv lKRM* # j <2> aassign[t5] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -157,7 +157,7 @@ checkOptree(note => q{}, # 4 <0> pushmark s # 5 <0> pushmark s # 6 <#> gv[*hash] s -# 7 <1> rv2hv lKRM*/1 +# 7 <1> rv2hv lKRM* # 8 <2> aassign[t3] vKS # 9 <;> nextstate(main 476 (eval 10):1) v:{ # a <0> pushmark sM @@ -171,7 +171,7 @@ checkOptree(note => q{}, # g <;> nextstate(main 475 (eval 10):1) v:{ # h <#> gvsv[*_] s # i <#> gv[*hash] s -# j <1> rv2hv sKR/1 +# j <1> rv2hv sKR # k <0> pushmark s # l <#> gvsv[*_] s # m <#> gv[*getkey] s/EARLYCV @@ -190,7 +190,7 @@ EOT_EOT # 4 <0> pushmark s # 5 <0> pushmark s # 6 <$> gv(*hash) s -# 7 <1> rv2hv lKRM*/1 +# 7 <1> rv2hv lKRM* # 8 <2> aassign[t2] vKS # 9 <;> nextstate(main 560 (eval 15):1) v:{ # a <0> pushmark sM @@ -204,7 +204,7 @@ EOT_EOT # g <;> nextstate(main 559 (eval 15):1) v:{ # h <$> gvsv(*_) s # i <$> gv(*hash) s -# j <1> rv2hv sKR/1 +# j <1> rv2hv sKR # k <0> pushmark s # l <$> gvsv(*_) s # m <$> gv(*getkey) s/EARLYCV @@ -243,7 +243,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t10] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -260,7 +260,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t6] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -289,7 +289,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t10] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -306,7 +306,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t6] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -335,7 +335,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t9] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -352,7 +352,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t5] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -381,7 +381,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t8] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -398,7 +398,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM*/1 +# d <1> rv2hv lKRM* # e <2> aassign[t5] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -426,7 +426,7 @@ checkOptree(note => q{}, # goto 7 # a <0> pushmark s # b <#> gv[*hash] s -# c <1> rv2hv lKRM*/1 +# c <1> rv2hv lKRM* # d <2> aassign[t6] KS/COM_AGG # e <#> gv[*array] s # f <1> rv2av[t8] K/1 @@ -445,7 +445,7 @@ EOT_EOT # goto 7 # a <0> pushmark s # b <$> gv(*hash) s -# c <1> rv2hv lKRM*/1 +# c <1> rv2hv lKRM* # d <2> aassign[t4] KS/COM_AGG # e <$> gv(*array) s # f <1> rv2av[t5] K/1 diff --git a/ext/B/t/f_sort.t b/ext/B/t/f_sort.t index fe0927829f..800281fa73 100644 --- a/ext/B/t/f_sort.t +++ b/ext/B/t/f_sort.t @@ -280,8 +280,7 @@ checkOptree(note => q{}, # 2 <0> pushmark s # 3 <0> pushmark s # 4 <#> gv[*age] s -# 5 <1> rv2hv[t9] lKRM/1 < 5.019006 -# 5 <1> rv2hv lKRM/1 >=5.019006 +# 5 <1> rv2hv lKRM # 6 <1> keys[t10] lK/1 < 5.019002 # 6 <1> keys[t10] lKM/1 >=5.019002 # 7 <@> sort lKS* @@ -295,8 +294,7 @@ EOT_EOT # 2 <0> pushmark s # 3 <0> pushmark s # 4 <$> gv(*age) s -# 5 <1> rv2hv[t3] lKRM/1 < 5.019006 -# 5 <1> rv2hv lKRM/1 >=5.019006 +# 5 <1> rv2hv lKRM # 6 <1> keys[t4] lK/1 < 5.019002 # 6 <1> keys[t4] lKM/1 >=5.019002 # 7 <@> sort lKS* diff --git a/ext/B/t/optree_samples.t b/ext/B/t/optree_samples.t index 1330a47302..121fd3eec9 100644 --- a/ext/B/t/optree_samples.t +++ b/ext/B/t/optree_samples.t @@ -483,8 +483,7 @@ checkOptree ( name => '%h = map { getkey($_) => $_ } @a', # goto 7 # g <0> pushmark s # h <#> gv[*h] s -# i <1> rv2hv[t2] lKRM*/1 < 5.019006 -# i <1> rv2hv lKRM*/1 >=5.019006 +# i <1> rv2hv lKRM* # j <2> aassign[t10] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -507,8 +506,7 @@ EOT_EOT # goto 7 # g <0> pushmark s # h <$> gv(*h) s -# i <1> rv2hv[t1] lKRM*/1 < 5.019006 -# i <1> rv2hv lKRM*/1 >=5.019006 +# i <1> rv2hv lKRM* # j <2> aassign[t5] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -521,8 +519,7 @@ checkOptree ( name => '%h=(); for $_(@a){$h{getkey($_)} = $_}', # 2 <0> pushmark s # 3 <0> pushmark s # 4 <#> gv[*h] s -# 5 <1> rv2hv[t2] lKRM*/1 < 5.019006 -# 5 <1> rv2hv lKRM*/1 >=5.019006 +# 5 <1> rv2hv lKRM* # 6 <2> aassign[t3] vKS # 7 <;> nextstate(main 506 (eval 24):1) v:{ # 8 <0> pushmark sM @@ -536,7 +533,7 @@ checkOptree ( name => '%h=(); for $_(@a){$h{getkey($_)} = $_}', # e <;> nextstate(main 505 (eval 24):1) v:{ # f <#> gvsv[*_] s # g <#> gv[*h] s -# h <1> rv2hv sKR/1 +# h <1> rv2hv sKR # i <0> pushmark s # j <#> gvsv[*_] s # k <#> gv[*getkey] s/EARLYCV @@ -552,8 +549,7 @@ EOT_EOT # 2 <0> pushmark s # 3 <0> pushmark s # 4 <$> gv(*h) s -# 5 <1> rv2hv[t1] lKRM*/1 < 5.019006 -# 5 <1> rv2hv lKRM*/1 >=5.019006 +# 5 <1> rv2hv lKRM* # 6 <2> aassign[t2] vKS # 7 <;> nextstate(main 506 (eval 24):1) v:{ # 8 <0> pushmark sM @@ -567,7 +563,7 @@ EOT_EOT # e <;> nextstate(main 505 (eval 24):1) v:{ # f <$> gvsv(*_) s # g <$> gv(*h) s -# h <1> rv2hv sKR/1 +# h <1> rv2hv sKR # i <0> pushmark s # j <$> gvsv(*_) s # k <$> gv(*getkey) s/EARLYCV |