summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-10 15:48:02 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-27 11:30:22 +0100
commit748f2c65599942147442f443949449a965f6d608 (patch)
treee0ccd923e221f95c7ddb80fc5c6c4c42c85c5a8f /ext
parent4fa080dbc664ee90dd374a9a49ac0a4932421bd7 (diff)
downloadperl-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.t32
-rw-r--r--ext/B/t/f_sort.t6
-rw-r--r--ext/B/t/optree_samples.t16
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