This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_leavesub(): call FREETMPS and optimise
[perl5.git] / t / perf / benchmarks
CommitLineData
24fb648d
DM
1#!perl
2
9e7973fa 3# This file specifies an array-of-hashes that define snippets of code that
24fb648d
DM
4# can be run by various measurement and profiling tools.
5#
6# The basic idea is that any time you add an optimisation that is intended
7# to make a particular construct faster, then you should add that construct
8# to this file.
9#
10# Under the normal test suite, the test file benchmarks.t does a basic
11# compile and run of each of these snippets; not to test performance,
12# but just to ensure that the code doesn't have errors.
13#
14# Over time, it is intended that various measurement and profiling tools
15# will be written that can run selected (or all) snippets in various
16# environments. These will not be run as part of a normal test suite run.
17#
9e7973fa
DM
18# It is intended that the tests in this file will be lightweight; e.g.
19# a hash access, an empty function call, or a single regex match etc.
20#
24fb648d
DM
21# This file is designed to be read in by 'do' (and in such a way that
22# multiple versions of this file from different releases can be read in
23# by a single process).
24#
9e7973fa
DM
25# The top-level array has name/hash pairs (we use an array rather than a
26# hash so that duplicate keys can be spotted) Each name is a token that
27# describes a particular test. Code will be compiled in the package named
28# after the token, so it should match /^(\w|::)+$/a. It is intended that
29# this can be used on the command line of tools to select particular
30# tests.
31# In addition, the package names are arranged into an informal hierarchy
32# whose top members are (this is subject to change):
33#
34# call:: subroutine and method handling
35# expr:: expressions: e.g. $x=1, $foo{bar}[0]
36# loop:: structural code like for, while(), etc
37# regex:: regular expressions
38# string:: string handling
24fb648d 39#
9e7973fa
DM
40#
41# Each hash has three fields:
24fb648d
DM
42#
43# desc is a description of the test
44# setup is a string containing setup code
45# code is a string containing the code to run in a loop
46#
47# So typically a benchmark tool might do something like
48#
49# eval "package $token; $setup; for (1..1000000) { $code }"
9e7973fa
DM
50#
51# Currently the only tool that uses this file is Porting/bench.pl;
52# try C<perl Porting/bench.pl --help> for more info
24fb648d
DM
53
54
9e7973fa 55[
e800e134
DM
56 'call::sub::empty' => {
57 desc => 'function call with no args or body',
58 setup => 'sub f { }',
59 code => 'f()',
60 },
f7a874b8
DM
61 'call::sub::amp_empty' => {
62 desc => '&foo function call with no args or body',
63 setup => 'sub f { }; @_ = ();',
64 code => '&f',
65 },
e800e134 66 'call::sub::args3' => {
9e7973fa 67 desc => 'function call with 3 local lexical vars',
e800e134
DM
68 setup => 'sub f { my ($a, $b, $c) = @_; 1 }',
69 code => 'f(1,2,3)',
70 },
f7a874b8
DM
71 'call::sub::args2_ret1' => {
72 desc => 'function call with 2 local lex vars and 1 return value',
73 setup => 'my $x; sub f { my ($a, $b) = @_; $a+$b }',
74 code => '$x = f(1,2)',
75 },
76 'call::sub::args2_ret1temp' => {
77 desc => 'function call with 2 local lex vars and 1 return TEMP value',
78 setup => 'my $x; sub f { my ($a, $b) = @_; \$a }',
79 code => '$x = f(1,2)',
80 },
e800e134
DM
81 'call::sub::args3_ret3' => {
82 desc => 'function call with 3 local lex vars and 3 return values',
83 setup => 'my @a; sub f { my ($a, $b, $c) = @_; $a+$b, $c, 1 }',
84 code => '@a = f(1,2,3)',
85 },
f7a874b8
DM
86 'call::sub::args3_ret3str' => {
87 desc => 'function call with 3 local lex vars and 3 string return values',
88 setup => 'my @a; sub f { my ($a, $b, $c) = @_; my @s = ("aa","bb","cc"); @s }',
89 code => '@a = f(1,2,3)',
90 },
91 'call::sub::args3_ret3temp' => {
92 desc => 'function call with 3 local lex vars and 3 TEMP return values',
93 setup => 'my @a; sub f { my ($a, $b, $c) = @_; 1..3 }',
94 code => '@a = f(1,2,3)',
95 },
96 'call::sub::recursive' => {
97 desc => 'basic recursive function call',
98 setup => 'my $x; sub f { my ($i) = @_; $i > 0 ? $i + f($i-1) : 0 }',
99 code => '$x = f(1)',
100 },
e800e134
DM
101
102 'call::goto::empty' => {
103 desc => 'goto &funtion with no args or body',
104 setup => 'sub f { goto &g } sub g {}',
105 code => 'f()',
106 },
107 'call::goto::args3' => {
108 desc => 'goto &funtion with 3 local lexical vars',
109 setup => 'sub f { goto &g } sub g { my ($a, $b, $c) = @_ }',
9e7973fa
DM
110 code => 'f(1,2,3)',
111 },
112
fedf30e1
DM
113
114 'expr::array::lex_1const_0' => {
115 desc => 'lexical $array[0]',
116 setup => 'my @a = (1)',
117 code => '$a[0]',
118 },
119 'expr::array::lex_1const_m1' => {
120 desc => 'lexical $array[-1]',
121 setup => 'my @a = (1)',
122 code => '$a[-1]',
123 },
124 'expr::array::lex_2const' => {
125 desc => 'lexical $array[const][const]',
126 setup => 'my @a = ([1,2])',
127 code => '$a[0][1]',
128 },
129 'expr::array::lex_2var' => {
130 desc => 'lexical $array[$i1][$i2]',
131 setup => 'my ($i1,$i2) = (0,1); my @a = ([1,2])',
132 code => '$a[$i1][$i2]',
133 },
134 'expr::array::ref_lex_2var' => {
135 desc => 'lexical $arrayref->[$i1][$i2]',
136 setup => 'my ($i1,$i2) = (0,1); my $r = [[1,2]]',
137 code => '$r->[$i1][$i2]',
138 },
139 'expr::array::ref_lex_3const' => {
140 desc => 'lexical $arrayref->[const][const][const]',
141 setup => 'my $r = [[[1,2]]]',
142 code => '$r->[0][0][0]',
143 },
144 'expr::array::ref_expr_lex_3const' => {
145 desc => '(lexical expr)->[const][const][const]',
146 setup => 'my $r = [[[1,2]]]',
92792a1c 147 code => '($r||0)->[0][0][0]',
fedf30e1
DM
148 },
149
150
151 'expr::array::pkg_1const_0' => {
152 desc => 'package $array[0]',
92792a1c 153 setup => '@a = (1)',
fedf30e1
DM
154 code => '$a[0]',
155 },
156 'expr::array::pkg_1const_m1' => {
157 desc => 'package $array[-1]',
92792a1c 158 setup => '@a = (1)',
fedf30e1
DM
159 code => '$a[-1]',
160 },
161 'expr::array::pkg_2const' => {
162 desc => 'package $array[const][const]',
92792a1c 163 setup => '@a = ([1,2])',
fedf30e1
DM
164 code => '$a[0][1]',
165 },
166 'expr::array::pkg_2var' => {
167 desc => 'package $array[$i1][$i2]',
92792a1c 168 setup => '($i1,$i2) = (0,1); @a = ([1,2])',
fedf30e1
DM
169 code => '$a[$i1][$i2]',
170 },
171 'expr::array::ref_pkg_2var' => {
172 desc => 'package $arrayref->[$i1][$i2]',
92792a1c 173 setup => '($i1,$i2) = (0,1); $r = [[1,2]]',
fedf30e1
DM
174 code => '$r->[$i1][$i2]',
175 },
176 'expr::array::ref_pkg_3const' => {
177 desc => 'package $arrayref->[const][const][const]',
92792a1c 178 setup => '$r = [[[1,2]]]',
fedf30e1
DM
179 code => '$r->[0][0][0]',
180 },
181 'expr::array::ref_expr_pkg_3const' => {
182 desc => '(package expr)->[const][const][const]',
92792a1c
DM
183 setup => '$r = [[[1,2]]]',
184 code => '($r||0)->[0][0][0]',
fedf30e1
DM
185 },
186
187
188 'expr::arrayhash::lex_3var' => {
189 desc => 'lexical $h{$k1}[$i]{$k2}',
190 setup => 'my ($i, $k1, $k2) = (0,"foo","bar");'
191 . 'my %h = (foo => [ { bar => 1 } ])',
192 code => '$h{$k1}[$i]{$k2}',
193 },
194 'expr::arrayhash::pkg_3var' => {
195 desc => 'package $h{$k1}[$i]{$k2}',
92792a1c
DM
196 setup => '($i, $k1, $k2) = (0,"foo","bar");'
197 . '%h = (foo => [ { bar => 1 } ])',
fedf30e1
DM
198 code => '$h{$k1}[$i]{$k2}',
199 },
200
201
478d54a9 202 'expr::assign::scalar_lex_int' => {
9e7973fa
DM
203 desc => 'lexical $x = 1',
204 setup => 'my $x',
205 code => '$x = 1',
206 },
478d54a9
DM
207 'expr::assign::scalar_lex_str' => {
208 desc => 'lexical $x = "abc"',
209 setup => 'my $x',
210 code => '$x = "abc"',
211 },
212 'expr::assign::scalar_lex_strint' => {
213 desc => 'lexical $x = 1 where $x was previously a string',
214 setup => 'my $x = "abc"',
215 code => '$x = 1',
216 },
217 'expr::assign::scalar_lex_intstr' => {
218 desc => 'lexical $x = "abc" where $x was previously an int',
219 setup => 'my $x = 1;',
220 code => '$x = "abc"',
221 },
9e7973fa
DM
222 'expr::assign::2list_lex' => {
223 desc => 'lexical ($x, $y) = (1, 2)',
224 setup => 'my ($x, $y)',
225 code => '($x, $y) = (1, 2)',
24fb648d 226 },
15c41403 227
fedf30e1
DM
228
229 'expr::hash::lex_1const' => {
230 desc => 'lexical $hash{const}',
231 setup => 'my %h = ("foo" => 1)',
232 code => '$h{foo}',
233 },
234 'expr::hash::lex_2const' => {
235 desc => 'lexical $hash{const}{const}',
236 setup => 'my %h = (foo => { bar => 1 })',
237 code => '$h{foo}{bar}',
238 },
239 'expr::hash::lex_2var' => {
240 desc => 'lexical $hash{$k1}{$k2}',
241 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 })',
242 code => '$h{$k1}{$k2}',
243 },
244 'expr::hash::ref_lex_2var' => {
245 desc => 'lexical $hashref->{$k1}{$k2}',
246 setup => 'my ($k1,$k2) = qw(foo bar); my $r = {$k1 => { $k2 => 1 }}',
247 code => '$r->{$k1}{$k2}',
248 },
249 'expr::hash::ref_lex_3const' => {
250 desc => 'lexical $hashref->{const}{const}{const}',
251 setup => 'my $r = {foo => { bar => { baz => 1 }}}',
252 code => '$r->{foo}{bar}{baz}',
253 },
254 'expr::hash::ref_expr_lex_3const' => {
255 desc => '(lexical expr)->{const}{const}{const}',
256 setup => 'my $r = {foo => { bar => { baz => 1 }}}',
92792a1c 257 code => '($r||0)->{foo}{bar}{baz}',
fedf30e1
DM
258 },
259
260
261 'expr::hash::pkg_1const' => {
262 desc => 'package $hash{const}',
92792a1c 263 setup => '%h = ("foo" => 1)',
fedf30e1
DM
264 code => '$h{foo}',
265 },
266 'expr::hash::pkg_2const' => {
267 desc => 'package $hash{const}{const}',
92792a1c 268 setup => '%h = (foo => { bar => 1 })',
fedf30e1
DM
269 code => '$h{foo}{bar}',
270 },
271 'expr::hash::pkg_2var' => {
272 desc => 'package $hash{$k1}{$k2}',
92792a1c 273 setup => '($k1,$k2) = qw(foo bar); %h = ($k1 => { $k2 => 1 })',
fedf30e1
DM
274 code => '$h{$k1}{$k2}',
275 },
276 'expr::hash::ref_pkg_2var' => {
277 desc => 'package $hashref->{$k1}{$k2}',
92792a1c 278 setup => '($k1,$k2) = qw(foo bar); $r = {$k1 => { $k2 => 1 }}',
fedf30e1
DM
279 code => '$r->{$k1}{$k2}',
280 },
281 'expr::hash::ref_pkg_3const' => {
282 desc => 'package $hashref->{const}{const}{const}',
92792a1c 283 setup => '$r = {foo => { bar => { baz => 1 }}}',
fedf30e1
DM
284 code => '$r->{foo}{bar}{baz}',
285 },
286 'expr::hash::ref_expr_pkg_3const' => {
287 desc => '(package expr)->{const}{const}{const}',
92792a1c
DM
288 setup => '$r = {foo => { bar => { baz => 1 }}}',
289 code => '($r||0)->{foo}{bar}{baz}',
fedf30e1
DM
290 },
291
292
293 'expr::hash::exists_lex_2var' => {
294 desc => 'lexical exists $hash{$k1}{$k2}',
295 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
296 code => 'exists $h{$k1}{$k2}',
297 },
298 'expr::hash::delete_lex_2var' => {
299 desc => 'lexical delete $hash{$k1}{$k2}',
300 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
301 code => 'delete $h{$k1}{$k2}',
302 },
303
304
147f21b5
DM
305 # using a const string as second arg to index triggers using FBM.
306 # the FBM matcher special-cases 1,2-byte strings.
307 #
308 'expr::index::short_const1' => {
309 desc => 'index of a short string against a 1 char const substr',
310 setup => 'my $x = "aaaab"',
311 code => 'index $x, "b"',
312 },
313 'expr::index::long_const1' => {
314 desc => 'index of a long string against a 1 char const substr',
315 setup => 'my $x = "a" x 1000 . "b"',
316 code => 'index $x, "b"',
317 },
318 'expr::index::short_const2aabc_bc' => {
319 desc => 'index of a short string against a 2 char const substr',
320 setup => 'my $x = "aaaabc"',
321 code => 'index $x, "bc"',
322 },
323 'expr::index::long_const2aabc_bc' => {
324 desc => 'index of a long string against a 2 char const substr',
325 setup => 'my $x = "a" x 1000 . "bc"',
326 code => 'index $x, "bc"',
327 },
328 'expr::index::long_const2aa_ab' => {
329 desc => 'index of a long string aaa.. against const substr "ab"',
330 setup => 'my $x = "a" x 1000',
331 code => 'index $x, "ab"',
332 },
333 'expr::index::long_const2bb_ab' => {
334 desc => 'index of a long string bbb.. against const substr "ab"',
335 setup => 'my $x = "b" x 1000',
336 code => 'index $x, "ab"',
337 },
338 'expr::index::long_const2aa_bb' => {
339 desc => 'index of a long string aaa.. against const substr "bb"',
340 setup => 'my $x = "a" x 1000',
341 code => 'index $x, "bb"',
342 },
343 # this one is designed to be pathological
344 'expr::index::long_const2ab_aa' => {
345 desc => 'index of a long string abab.. against const substr "aa"',
346 setup => 'my $x = "ab" x 500',
347 code => 'index $x, "aa"',
348 },
349 # near misses with gaps, 1st letter
350 'expr::index::long_const2aaxx_xy' => {
351 desc => 'index of a long string with "xx"s against const substr "xy"',
352 setup => 'my $x = "aaaaaaaaxx" x 100',
353 code => 'index $x, "xy"',
354 },
355 # near misses with gaps, 2nd letter
356 'expr::index::long_const2aayy_xy' => {
357 desc => 'index of a long string with "yy"s against const substr "xy"',
358 setup => 'my $x = "aaaaaaaayy" x 100',
359 code => 'index $x, "xy"',
360 },
361 # near misses with gaps, duplicate letter
362 'expr::index::long_const2aaxy_xx' => {
363 desc => 'index of a long string with "xy"s against const substr "xx"',
364 setup => 'my $x = "aaaaaaaaxy" x 100',
365 code => 'index $x, "xx"',
366 },
367 # alternating near misses with gaps
368 'expr::index::long_const2aaxxaayy_xy' => {
369 desc => 'index of a long string with "xx/yy"s against const substr "xy"',
370 setup => 'my $x = "aaaaaaaaxxbbbbbbbbyy" x 50',
371 code => 'index $x, "xy"',
372 },
373 'expr::index::short_const3aabcd_bcd' => {
374 desc => 'index of a short string against a 3 char const substr',
375 setup => 'my $x = "aaaabcd"',
376 code => 'index $x, "bcd"',
377 },
378 'expr::index::long_const3aabcd_bcd' => {
379 desc => 'index of a long string against a 3 char const substr',
380 setup => 'my $x = "a" x 1000 . "bcd"',
381 code => 'index $x, "bcd"',
382 },
383 'expr::index::long_const3ab_abc' => {
384 desc => 'index of a long string of "ab"s against a 3 char const substr "abc"',
385 setup => 'my $x = "ab" x 500',
386 code => 'index $x, "abc"',
387 },
388 'expr::index::long_const3bc_abc' => {
389 desc => 'index of a long string of "bc"s against a 3 char const substr "abc"',
390 setup => 'my $x = "bc" x 500',
391 code => 'index $x, "abc"',
392 },
41f678d9 393 'expr::index::utf8_position_1' => {
15c41403 394 desc => 'index of a utf8 string, matching at position 1',
92792a1c 395 setup => 'my $x = "abc". chr(0x100); chop $x',
15c41403
JR
396 code => 'index $x, "b"',
397 },
24fb648d 398
a5f48505
DM
399
400 # list assign, OP_AASSIGN
401
402
403 # (....) = ()
404
405 'expr::aassign::ma_empty' => {
406 desc => 'my array assigned empty',
407 setup => '',
408 code => 'my @a = ()',
409 },
410 'expr::aassign::lax_empty' => {
411 desc => 'non-empty lexical array assigned empty',
412 setup => 'my @a = 1..3;',
413 code => '@a = ()',
414 },
415 'expr::aassign::llax_empty' => {
416 desc => 'non-empty lexical var and array assigned empty',
417 setup => 'my ($x, @a) = 1..4;',
418 code => '($x, @a) = ()',
419 },
420 'expr::aassign::3m_empty' => {
421 desc => 'three my vars assigned empty',
422 setup => '',
423 code => 'my ($x,$y,$z) = ()',
424 },
425 'expr::aassign::3l_empty' => {
426 desc => 'three lexical vars assigned empty',
427 setup => 'my ($x,$y,$z)',
428 code => '($x,$y,$z) = ()',
429 },
430 'expr::aassign::pa_empty' => {
431 desc => 'package array assigned empty',
432 setup => '',
433 code => '@a = ()',
434 },
435 'expr::aassign::pax_empty' => {
436 desc => 'non-empty package array assigned empty',
437 setup => '@a = (1,2,3)',
438 code => '@a = ()',
439 },
440 'expr::aassign::3p_empty' => {
441 desc => 'three package vars assigned empty',
442 setup => '($x,$y,$z) = 1..3;',
443 code => '($x,$y,$z) = ()',
444 },
445
446 # (....) = (1,2,3)
447
448 'expr::aassign::ma_3c' => {
449 desc => 'my array assigned 3 consts',
450 setup => '',
451 code => 'my @a = (1,2,3)',
452 },
453 'expr::aassign::lax_3c' => {
454 desc => 'non-empty lexical array assigned 3 consts',
455 setup => 'my @a = 1..3;',
456 code => '@a = (1,2,3)',
457 },
458 'expr::aassign::llax_3c' => {
459 desc => 'non-empty lexical var and array assigned 3 consts',
460 setup => 'my ($x, @a) = 1..4;',
461 code => '($x, @a) = (1,2,3)',
462 },
463 'expr::aassign::3m_3c' => {
464 desc => 'three my vars assigned 3 consts',
465 setup => '',
466 code => 'my ($x,$y,$z) = (1,2,3)',
467 },
468 'expr::aassign::3l_3c' => {
469 desc => 'three lexical vars assigned 3 consts',
470 setup => 'my ($x,$y,$z)',
471 code => '($x,$y,$z) = (1,2,3)',
472 },
473 'expr::aassign::pa_3c' => {
474 desc => 'package array assigned 3 consts',
475 setup => '',
476 code => '@a = (1,2,3)',
477 },
478 'expr::aassign::pax_3c' => {
479 desc => 'non-empty package array assigned 3 consts',
480 setup => '@a = (1,2,3)',
481 code => '@a = (1,2,3)',
482 },
483 'expr::aassign::3p_3c' => {
484 desc => 'three package vars assigned 3 consts',
485 setup => '($x,$y,$z) = 1..3;',
486 code => '($x,$y,$z) = (1,2,3)',
487 },
488
489 # (....) = @lexical
490
491 'expr::aassign::ma_la' => {
492 desc => 'my array assigned lexical array',
493 setup => 'my @init = 1..3;',
494 code => 'my @a = @init',
495 },
496 'expr::aassign::lax_la' => {
497 desc => 'non-empty lexical array assigned lexical array',
498 setup => 'my @init = 1..3; my @a = 1..3;',
499 code => '@a = @init',
500 },
501 'expr::aassign::llax_la' => {
502 desc => 'non-empty lexical var and array assigned lexical array',
503 setup => 'my @init = 1..3; my ($x, @a) = 1..4;',
504 code => '($x, @a) = @init',
505 },
506 'expr::aassign::3m_la' => {
507 desc => 'three my vars assigned lexical array',
508 setup => 'my @init = 1..3;',
509 code => 'my ($x,$y,$z) = @init',
510 },
511 'expr::aassign::3l_la' => {
512 desc => 'three lexical vars assigned lexical array',
513 setup => 'my @init = 1..3; my ($x,$y,$z)',
514 code => '($x,$y,$z) = @init',
515 },
516 'expr::aassign::pa_la' => {
517 desc => 'package array assigned lexical array',
518 setup => 'my @init = 1..3;',
519 code => '@a = @init',
520 },
521 'expr::aassign::pax_la' => {
522 desc => 'non-empty package array assigned lexical array',
523 setup => 'my @init = 1..3; @a = @init',
524 code => '@a = @init',
525 },
526 'expr::aassign::3p_la' => {
527 desc => 'three package vars assigned lexical array',
528 setup => 'my @init = 1..3; ($x,$y,$z) = 1..3;',
529 code => '($x,$y,$z) = @init',
530 },
531
532 # (....) = @package
533
534 'expr::aassign::ma_pa' => {
535 desc => 'my array assigned package array',
536 setup => '@init = 1..3;',
537 code => 'my @a = @init',
538 },
539 'expr::aassign::lax_pa' => {
540 desc => 'non-empty lexical array assigned package array',
541 setup => '@init = 1..3; my @a = 1..3;',
542 code => '@a = @init',
543 },
544 'expr::aassign::llax_pa' => {
545 desc => 'non-empty lexical var and array assigned package array',
546 setup => '@init = 1..3; my ($x, @a) = 1..4;',
547 code => '($x, @a) = @init',
548 },
549 'expr::aassign::3m_pa' => {
550 desc => 'three my vars assigned package array',
551 setup => '@init = 1..3;',
552 code => 'my ($x,$y,$z) = @init',
553 },
554 'expr::aassign::3l_pa' => {
555 desc => 'three lexical vars assigned package array',
556 setup => '@init = 1..3; my ($x,$y,$z)',
557 code => '($x,$y,$z) = @init',
558 },
559 'expr::aassign::pa_pa' => {
560 desc => 'package array assigned package array',
561 setup => '@init = 1..3;',
562 code => '@a = @init',
563 },
564 'expr::aassign::pax_pa' => {
565 desc => 'non-empty package array assigned package array',
566 setup => '@init = 1..3; @a = @init',
567 code => '@a = @init',
568 },
569 'expr::aassign::3p_pa' => {
570 desc => 'three package vars assigned package array',
571 setup => '@init = 1..3; ($x,$y,$z) = 1..3;',
572 code => '($x,$y,$z) = @init',
573 },
574
575 # (....) = @_;
576
577 'expr::aassign::ma_defary' => {
578 desc => 'my array assigned @_',
579 setup => '@_ = 1..3;',
580 code => 'my @a = @_',
581 },
582 'expr::aassign::lax_defary' => {
583 desc => 'non-empty lexical array assigned @_',
584 setup => '@_ = 1..3; my @a = 1..3;',
585 code => '@a = @_',
586 },
587 'expr::aassign::llax_defary' => {
588 desc => 'non-empty lexical var and array assigned @_',
589 setup => '@_ = 1..3; my ($x, @a) = 1..4;',
590 code => '($x, @a) = @_',
591 },
592 'expr::aassign::3m_defary' => {
593 desc => 'three my vars assigned @_',
594 setup => '@_ = 1..3;',
595 code => 'my ($x,$y,$z) = @_',
596 },
597 'expr::aassign::3l_defary' => {
598 desc => 'three lexical vars assigned @_',
599 setup => '@_ = 1..3; my ($x,$y,$z)',
600 code => '($x,$y,$z) = @_',
601 },
602 'expr::aassign::pa_defary' => {
603 desc => 'package array assigned @_',
604 setup => '@_ = 1..3;',
605 code => '@a = @_',
606 },
607 'expr::aassign::pax_defary' => {
608 desc => 'non-empty package array assigned @_',
609 setup => '@_ = 1..3; @a = @_',
610 code => '@a = @_',
611 },
612 'expr::aassign::3p_defary' => {
613 desc => 'three package vars assigned @_',
614 setup => '@_ = 1..3; ($x,$y,$z) = 1..3;',
615 code => '($x,$y,$z) = @_',
616 },
617
618
619 # (....) = ($lex1,$lex2,$lex3);
620
621 'expr::aassign::ma_3l' => {
622 desc => 'my array assigned lexicals',
623 setup => 'my ($v1,$v2,$v3) = 1..3;',
624 code => 'my @a = ($v1,$v2,$v3)',
625 },
626 'expr::aassign::lax_3l' => {
627 desc => 'non-empty lexical array assigned lexicals',
628 setup => 'my ($v1,$v2,$v3) = 1..3; my @a = 1..3;',
629 code => '@a = ($v1,$v2,$v3)',
630 },
631 'expr::aassign::llax_3l' => {
632 desc => 'non-empty lexical var and array assigned lexicals',
633 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;',
634 code => '($x, @a) = ($v1,$v2,$v3)',
635 },
636 'expr::aassign::3m_3l' => {
637 desc => 'three my vars assigned lexicals',
638 setup => 'my ($v1,$v2,$v3) = 1..3;',
639 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)',
640 },
641 'expr::aassign::3l_3l' => {
642 desc => 'three lexical vars assigned lexicals',
643 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x,$y,$z)',
644 code => '($x,$y,$z) = ($v1,$v2,$v3)',
645 },
646 'expr::aassign::pa_3l' => {
647 desc => 'package array assigned lexicals',
648 setup => 'my ($v1,$v2,$v3) = 1..3;',
649 code => '@a = ($v1,$v2,$v3)',
650 },
651 'expr::aassign::pax_3l' => {
652 desc => 'non-empty package array assigned lexicals',
653 setup => 'my ($v1,$v2,$v3) = 1..3; @a = @_',
654 code => '@a = ($v1,$v2,$v3)',
655 },
656 'expr::aassign::3p_3l' => {
657 desc => 'three package vars assigned lexicals',
658 setup => 'my ($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;',
659 code => '($x,$y,$z) = ($v1,$v2,$v3)',
660 },
661
662
663 # (....) = ($pkg1,$pkg2,$pkg3);
664
665 'expr::aassign::ma_3p' => {
666 desc => 'my array assigned 3 package vars',
667 setup => '($v1,$v2,$v3) = 1..3;',
668 code => 'my @a = ($v1,$v2,$v3)',
669 },
670 'expr::aassign::lax_3p' => {
671 desc => 'non-empty lexical array assigned 3 package vars',
672 setup => '($v1,$v2,$v3) = 1..3; my @a = 1..3;',
673 code => '@a = ($v1,$v2,$v3)',
674 },
675 'expr::aassign::llax_3p' => {
676 desc => 'non-empty lexical var and array assigned 3 package vars',
677 setup => '($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;',
678 code => '($x, @a) = ($v1,$v2,$v3)',
679 },
680 'expr::aassign::3m_3p' => {
681 desc => 'three my vars assigned 3 package vars',
682 setup => '($v1,$v2,$v3) = 1..3;',
683 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)',
684 },
685 'expr::aassign::3l_3p' => {
686 desc => 'three lexical vars assigned 3 package vars',
687 setup => '($v1,$v2,$v3) = 1..3; my ($x,$y,$z)',
688 code => '($x,$y,$z) = ($v1,$v2,$v3)',
689 },
690 'expr::aassign::pa_3p' => {
691 desc => 'package array assigned 3 package vars',
692 setup => '($v1,$v2,$v3) = 1..3;',
693 code => '@a = ($v1,$v2,$v3)',
694 },
695 'expr::aassign::pax_3p' => {
696 desc => 'non-empty package array assigned 3 package vars',
697 setup => '($v1,$v2,$v3) = 1..3; @a = @_',
698 code => '@a = ($v1,$v2,$v3)',
699 },
700 'expr::aassign::3p_3p' => {
701 desc => 'three package vars assigned 3 package vars',
702 setup => '($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;',
703 code => '($x,$y,$z) = ($v1,$v2,$v3)',
704 },
705
706
707 # (....) = (1,2,$shared);
708
709 'expr::aassign::llax_2c1s' => {
710 desc => 'non-empty lexical var and array assigned 2 consts and 1 shared var',
711 setup => 'my ($x, @a) = 1..4;',
712 code => '($x, @a) = (1,2,$x)',
713 },
714 'expr::aassign::3l_2c1s' => {
715 desc => 'three lexical vars assigned 2 consts and 1 shared var',
716 setup => 'my ($x,$y,$z) = 1..3;',
717 code => '($x,$y,$z) = (1,2,$x)',
718 },
719 'expr::aassign::3p_2c1s' => {
720 desc => 'three package vars assigned 2 consts and 1 shared var',
721 setup => '($x,$y,$z) = 1..3;',
722 code => '($x,$y,$z) = (1,2,$x)',
723 },
724
725
726 # ($a,$b) = ($b,$a);
727
728 'expr::aassign::2l_swap' => {
729 desc => 'swap two lexical vars',
730 setup => 'my ($a,$b) = (1,2)',
731 code => '($a,$b) = ($b,$a)',
732 },
733 'expr::aassign::2p_swap' => {
734 desc => 'swap two package vars',
735 setup => '($a,$b) = (1,2)',
736 code => '($a,$b) = ($b,$a)',
737 },
738 'expr::aassign::2laelem_swap' => {
739 desc => 'swap two lexical vars',
740 setup => 'my @a = (1,2)',
741 code => '($a[0],$a[1]) = ($a[1],$a[0])',
742 },
743
744 # misc list assign
745
746 'expr::aassign::5l_4l1s' => {
747 desc => 'long list of lexical vars, 1 shared',
748 setup => 'my ($a,$b,$c,$d,$e) = 1..5',
749 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)',
750 },
751
752 'expr::aassign::5p_4p1s' => {
753 desc => 'long list of package vars, 1 shared',
754 setup => '($a,$b,$c,$d,$e) = 1..5',
755 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)',
756 },
757 'expr::aassign::5l_defary' => {
758 desc => 'long list of lexical vars to assign @_ to',
759 setup => '@_ = 1..5',
760 code => 'my ($a,$b,$c,$d,$e) = @_',
761 },
762 'expr::aassign::5l1la_defary' => {
763 desc => 'long list of lexical vars plus long slurp to assign @_ to',
764 setup => '@_ = 1..20',
765 code => 'my ($a,$b,$c,$d,$e,@rest) = @_',
766 },
808ce557
DM
767 'expr::aassign::1l_2l' => {
768 desc => 'single lexical LHS',
769 setup => 'my $x = 1;',
770 code => '(undef,$x) = ($x,$x)',
771 },
772 'expr::aassign::2l_1l' => {
773 desc => 'single lexical RHS',
774 setup => 'my $x = 1;',
9ae0115f
DM
775 code => '($x,$x) = ($x)',
776 },
777 'expr::aassign::2l_1ul' => {
778 desc => 'undef and single lexical RHS',
779 setup => 'my $x = 1;',
808ce557
DM
780 code => '($x,$x) = (undef, $x)',
781 },
a5f48505
DM
782
783
230ee21f
DM
784 'expr::arith::add_lex_ii' => {
785 desc => 'add two integers and assign to a lexical var',
786 setup => 'my ($x,$y,$z) = 1..3;',
787 code => '$z = $x + $y',
788 },
789 'expr::arith::add_pkg_ii' => {
790 desc => 'add two integers and assign to a package var',
791 setup => 'my ($x,$y) = 1..2; $z = 3;',
792 code => '$z = $x + $y',
793 },
794 'expr::arith::add_lex_nn' => {
795 desc => 'add two NVs and assign to a lexical var',
796 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);',
797 code => '$z = $x + $y',
798 },
799 'expr::arith::add_pkg_nn' => {
800 desc => 'add two NVs and assign to a package var',
801 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);',
802 code => '$z = $x + $y',
803 },
804 'expr::arith::add_lex_ni' => {
805 desc => 'add an int and an NV and assign to a lexical var',
806 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);',
807 code => '$z = $x + $y',
808 },
809 'expr::arith::add_pkg_ni' => {
810 desc => 'add an int and an NV and assign to a package var',
811 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);',
812 code => '$z = $x + $y',
813 },
814
815 'expr::arith::sub_lex_ii' => {
816 desc => 'subtract two integers and assign to a lexical var',
817 setup => 'my ($x,$y,$z) = 1..3;',
818 code => '$z = $x - $y',
819 },
820 'expr::arith::sub_pkg_ii' => {
821 desc => 'subtract two integers and assign to a package var',
822 setup => 'my ($x,$y) = 1..2; $z = 3;',
823 code => '$z = $x - $y',
824 },
825 'expr::arith::sub_lex_nn' => {
826 desc => 'subtract two NVs and assign to a lexical var',
827 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);',
828 code => '$z = $x - $y',
829 },
830 'expr::arith::sub_pkg_nn' => {
831 desc => 'subtract two NVs and assign to a package var',
832 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);',
833 code => '$z = $x - $y',
834 },
835 'expr::arith::sub_lex_ni' => {
836 desc => 'subtract an int and an NV and assign to a lexical var',
837 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);',
838 code => '$z = $x - $y',
839 },
840 'expr::arith::sub_pkg_ni' => {
841 desc => 'subtract an int and an NV and assign to a package var',
842 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);',
843 code => '$z = $x - $y',
844 },
845
846 'expr::arith::mult_lex_ii' => {
847 desc => 'multiply two integers and assign to a lexical var',
848 setup => 'my ($x,$y,$z) = 1..3;',
849 code => '$z = $x * $y',
850 },
851 'expr::arith::mult_pkg_ii' => {
852 desc => 'multiply two integers and assign to a package var',
853 setup => 'my ($x,$y) = 1..2; $z = 3;',
854 code => '$z = $x * $y',
855 },
856 'expr::arith::mult_lex_nn' => {
857 desc => 'multiply two NVs and assign to a lexical var',
858 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);',
859 code => '$z = $x * $y',
860 },
861 'expr::arith::mult_pkg_nn' => {
862 desc => 'multiply two NVs and assign to a package var',
863 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);',
864 code => '$z = $x * $y',
865 },
866 'expr::arith::mult_lex_ni' => {
867 desc => 'multiply an int and an NV and assign to a lexical var',
868 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);',
869 code => '$z = $x * $y',
870 },
871 'expr::arith::mult_pkg_ni' => {
872 desc => 'multiply an int and an NV and assign to a package var',
873 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);',
874 code => '$z = $x * $y',
875 },
876
4c2c3128
DM
877 'expr::arith::preinc' => {
878 desc => '++$x',
879 setup => 'my $x = 1;',
880 code => '++$x',
881 },
882 'expr::arith::predec' => {
883 desc => '--$x',
884 setup => 'my $x = 1;',
885 code => '--$x',
886 },
887 'expr::arith::postinc' => {
888 desc => '$x++',
889 setup => 'my $x = 1; my $y',
890 code => '$y = $x++', # scalar context so not optimised to ++$x
891 },
892 'expr::arith::postdec' => {
893 desc => '$x--',
894 setup => 'my $x = 1; my $y',
895 code => '$y = $x--', # scalar context so not optimised to --$x
b52de964
DM
896 },
897
aedeb7c2
DM
898 'loop::block' => {
899 desc => 'empty basic loop',
900 setup => ';',
901 code => '{1;}',
902 },
903
904 'loop::do' => {
905 desc => 'basic do block',
906 setup => 'my $x; my $y = 2;',
907 code => '$x = do {1; $y}', # the ';' stops the do being optimised
908 },
909
910 'loop::for::my_range1' => {
911 desc => 'empty for loop with my var and 1 integer range',
912 setup => '',
913 code => 'for my $x (1..1) {}',
914 },
915 'loop::for::lex_range1' => {
916 desc => 'empty for loop with lexical var and 1 integer range',
917 setup => 'my $x;',
918 code => 'for $x (1..1) {}',
919 },
920 'loop::for::pkg_range1' => {
921 desc => 'empty for loop with package var and 1 integer range',
922 setup => '$x = 1;',
923 code => 'for $x (1..1) {}',
924 },
925 'loop::for::defsv_range1' => {
926 desc => 'empty for loop with $_ and integer 1 range',
927 setup => ';',
928 code => 'for (1..1) {}',
929 },
930 'loop::for::my_range4' => {
931 desc => 'empty for loop with my var and 4 integer range',
932 setup => '',
933 code => 'for my $x (1..4) {}',
934 },
935 'loop::for::lex_range4' => {
936 desc => 'empty for loop with lexical var and 4 integer range',
937 setup => 'my $x;',
938 code => 'for $x (1..4) {}',
939 },
940 'loop::for::pkg_range4' => {
941 desc => 'empty for loop with package var and 4 integer range',
942 setup => '$x = 1;',
943 code => 'for $x (1..4) {}',
944 },
945 'loop::for::defsv_range4' => {
946 desc => 'empty for loop with $_ and integer 4 range',
947 setup => ';',
948 code => 'for (1..4) {}',
949 },
4c2c3128 950
aedeb7c2
DM
951 'loop::for::my_list1' => {
952 desc => 'empty for loop with my var and 1 integer list',
b52de964 953 setup => '',
aedeb7c2
DM
954 code => 'for my $x (1) {}',
955 },
956 'loop::for::lex_list1' => {
957 desc => 'empty for loop with lexical var and 1 integer list',
958 setup => 'my $x;',
959 code => 'for $x (1) {}',
960 },
961 'loop::for::pkg_list1' => {
962 desc => 'empty for loop with package var and 1 integer list',
963 setup => '$x = 1;',
964 code => 'for $x (1) {}',
965 },
966 'loop::for::defsv_list1' => {
967 desc => 'empty for loop with $_ and integer 1 list',
968 setup => ';',
969 code => 'for (1) {}',
970 },
971 'loop::for::my_list4' => {
972 desc => 'empty for loop with my var and 4 integer list',
973 setup => '',
974 code => 'for my $x (1,2,3,4) {}',
975 },
976 'loop::for::lex_list4' => {
977 desc => 'empty for loop with lexical var and 4 integer list',
978 setup => 'my $x;',
979 code => 'for $x (1,2,3,4) {}',
980 },
981 'loop::for::pkg_list4' => {
982 desc => 'empty for loop with package var and 4 integer list',
983 setup => '$x = 1;',
984 code => 'for $x (1,2,3,4) {}',
985 },
986 'loop::for::defsv_list4' => {
987 desc => 'empty for loop with $_ and integer 4 list',
988 setup => '',
989 code => 'for (1,2,3,4) {}',
990 },
991
0724084c
DM
992 'loop::for::my_array1' => {
993 desc => 'empty for loop with my var and 1 integer array',
994 setup => 'my @a = (1);',
995 code => 'for my $x (@a) {}',
996 },
997 'loop::for::lex_array1' => {
998 desc => 'empty for loop with lexical var and 1 integer array',
999 setup => 'my $x; my @a = (1);',
1000 code => 'for $x (@a) {}',
1001 },
1002 'loop::for::pkg_array1' => {
1003 desc => 'empty for loop with package var and 1 integer array',
1004 setup => '$x = 1; my @a = (1);',
1005 code => 'for $x (@a) {}',
1006 },
1007 'loop::for::defsv_array1' => {
1008 desc => 'empty for loop with $_ and integer 1 array',
1009 setup => 'my @a = (@a);',
1010 code => 'for (1) {}',
1011 },
1012 'loop::for::my_array4' => {
1013 desc => 'empty for loop with my var and 4 integer array',
1014 setup => 'my @a = (1..4);',
1015 code => 'for my $x (@a) {}',
1016 },
1017 'loop::for::lex_array4' => {
1018 desc => 'empty for loop with lexical var and 4 integer array',
1019 setup => 'my $x; my @a = (1..4);',
1020 code => 'for $x (@a) {}',
1021 },
1022 'loop::for::pkg_array4' => {
1023 desc => 'empty for loop with package var and 4 integer array',
1024 setup => '$x = 1; my @a = (1..4);',
1025 code => 'for $x (@a) {}',
1026 },
1027 'loop::for::defsv_array4' => {
1028 desc => 'empty for loop with $_ and integer 4 array',
1029 setup => 'my @a = (1..4);',
1030 code => 'for (@a) {}',
1031 },
1032
aedeb7c2
DM
1033 'loop::while::i1' => {
1034 desc => 'empty while loop 1 iteration',
1035 setup => 'my $i = 0;',
1036 code => 'while (++$i % 2) {}',
1037 },
1038 'loop::while::i4' => {
1039 desc => 'empty while loop 4 iterations',
1040 setup => 'my $i = 0;',
1041 code => 'while (++$i % 4) {}',
4c2c3128
DM
1042 },
1043
fedf30e1 1044];