This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Optimise 'if ($a || $b)' and 'unless ($a && $b)' early exit
authorMatthew Horsfall (alh) <wolfsage@gmail.com>
Tue, 8 Oct 2013 16:56:08 +0000 (12:56 -0400)
committerTony Cook <tony@develop-help.com>
Tue, 19 Nov 2013 04:35:32 +0000 (15:35 +1100)
commite45d8982aeb58420180a04c6079471d707058965
treeaabdb7bb894da028248ce14d1828af50c4720f69
parentd320cf40013cb3d9e9458bacdc38048ffba35a6c
Optimise 'if ($a || $b)' and 'unless ($a && $b)' early exit

An OP_AND/OP_OR in void context provides a short circuit
through ->op_other that can be used if AND/OR ops contained
within it jump out early. Use that short circuit.

Previously:

  $ ./perl -Ilib -MO=Concise -e 'if ($aa || $bb) {}'
  8  <@> leave[1 ref] vKP/REFC ->(end)
  1     <0> enter ->2
  2     <;> nextstate(main 3 -e:1) v:{ ->3
  -     <1> null vK/1 ->8
  6        <|> and(other->7) vK/1 ->8
  -           <1> null sK/1 ->6
  4              <|> or(other->5) sK/1 ->6              <-- Not optimised
  -                 <1> ex-rv2sv sK/1 ->4
  3                    <$> gvsv(*aa) s ->4
  -                 <1> ex-rv2sv sK/1 ->-
  5                    <$> gvsv(*bb) s ->6
  -           <@> scope vK ->-
  7              <0> stub v ->8

Now:

  $ ./perl -Ilib -MO=Concise -e 'if ($aa || $bb) {}'
  8  <@> leave[1 ref] vKP/REFC ->(end)
  1     <0> enter ->2
  2     <;> nextstate(main 3 -e:1) v:{ ->3
  -     <1> null vK/1 ->8
  6        <|> and(other->7) vK/1 ->8
  -           <1> null sK/1 ->6
  4              <|> or(other->5) sK/1 ->7               <-- Short circuited
  -                 <1> ex-rv2sv sK/1 ->4
  3                    <$> gvsv(*aa) s ->4
  -                 <1> ex-rv2sv sK/1 ->-
  5                    <$> gvsv(*bb) s ->6
  -           <@> scope vK ->-
  7              <0> stub v ->8
op.c
t/op/dor.t
t/op/or.t