summaryrefslogtreecommitdiff
path: root/op.h
diff options
context:
space:
mode:
authorMatthew Horsfall <WolfSage@gmail.com>2013-12-11 18:28:21 -0500
committerSteffen Mueller <smueller@cpan.org>2013-12-13 18:15:30 +0100
commit437e3a7dac994ebace1195549170c81f474d9c20 (patch)
tree86a8fd6b0a36e0fb66683a245cfdb1d9deb43b78 /op.h
parent4b76cb9db827e0f9f047de33ae98ca8b86be8260 (diff)
downloadperl-437e3a7dac994ebace1195549170c81f474d9c20.tar.gz
Optimise out PUSHMARK/RETURN if return is the last statement in a sub.
This makes: sub baz { return $cat; } Behave like: sub baz { $cat; } Which is notably faster. Unpatched: ./perl -Ilib/ ~/stuff/bench.pl Benchmark: timing 40000000 iterations of normal, ret... normal: 3 wallclock secs ( 1.60 usr + 0.01 sys = 1.61 CPU) @ 24844720.50/s (n=40000000) ret: 3 wallclock secs ( 2.08 usr + 0.00 sys = 2.08 CPU) @ 19230769.23/s (n=40000000) Patched: ./perl -Ilib ~/stuff/bench.pl Benchmark: timing 40000000 iterations of aret, normal... normal: 2 wallclock secs ( 1.72 usr + 0.00 sys = 1.72 CPU) @ 23255813.95/s (n=40000000) ret: 2 wallclock secs ( 1.72 usr + 0.00 sys = 1.72 CPU) @ 23255813.95/s (n=40000000) The difference in OP trees can be seen here: Unpatched: $ perl -MO=Concise,baz -e 'sub baz { return $cat }' main::baz: 5 <1> leavesub[1 ref] K/REFC,1 ->(end) - <@> lineseq KP ->5 1 <;> nextstate(main 1 -e:1) v ->2 4 <@> return K ->5 2 <0> pushmark s ->3 - <1> ex-rv2sv sK/1 ->4 3 <#> gvsv[*cat] s ->4 -e syntax OK Patched: $ ./perl -Ilib -MO=Concise,baz -e 'sub baz { return $cat }' main::baz: 3 <1> leavesub[1 ref] K/REFC,1 ->(end) - <@> lineseq KP ->3 1 <;> nextstate(main 1 -e:1) v ->2 - <@> return K ->- - <0> pushmark s ->2 - <1> ex-rv2sv sK/1 ->- 2 <$> gvsv(*cat) s ->3 -e syntax OK (Includes some modifications from Steffen)
Diffstat (limited to 'op.h')
-rw-r--r--op.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/op.h b/op.h
index 8b8e3d2a56..0b84594824 100644
--- a/op.h
+++ b/op.h
@@ -1003,6 +1003,9 @@ For custom ops the type is returned from the registration, and it is up
to the registree to ensure it is accurate. The value returned will be
one of the OA_* constants from op.h.
+=for apidoc Am|bool|OP_TYPE_IS|OP *o, Optype type
+Returns true if the given OP is not NULL and if it is of the given
+type.
=cut
*/
@@ -1016,6 +1019,9 @@ one of the OA_* constants from op.h.
? XopENTRYCUSTOM(o, xop_class) \
: (PL_opargs[(o)->op_type] & OA_CLASS_MASK))
+#define OP_TYPE_IS(o, type) ((o) && (o)->op_type == (type))
+
+
#define newSUB(f, o, p, b) Perl_newATTRSUB(aTHX_ (f), (o), (p), NULL, (b))
#ifdef PERL_MAD