Re: 'if not / unless' optimization change makes my pow test go POW!
Vincent Pit [Mon, 8 Sep 2008 22:10:34 +0000 (00:10 +0200)]
Message-ID: <48C586BA.4050603@profvince.com>
Date: Mon, 08 Sep 2008 22:10:34 +0200

p4raw-id: //depot/perl@34322

ext/B/t/deparse.t
op.c
t/op/lop.t

index f28c688..42d50ba 100644 (file)
@@ -434,6 +434,7 @@ use constant H => { "#" => 1 }; H->{"#"}
 foreach my $i (@_) { 0 }
 ####
 # 58 tests with not, not optimized
+my $c;
 x() unless $a;
 x() if not $a and $b;
 x() if $a and not $b;
@@ -443,18 +444,46 @@ x() if not $a or $b;
 x() if $a or not $b;
 x() unless not $a or $b;
 x() unless $a or not $b;
+x() if $a and not $b and $c;
+x() if not $a and $b and not $c;
+x() unless $a and not $b and $c;
+x() unless not $a and $b and not $c;
+x() if $a or not $b or $c;
+x() if not $a or $b or not $c;
+x() unless $a or not $b or $c;
+x() unless not $a or $b or not $c;
 ####
 # 59 tests with not, optimized
+my $c;
 x() if not $a;
 x() unless not $a;
 x() if not $a and not $b;
 x() unless not $a and not $b;
 x() if not $a or not $b;
 x() unless not $a or not $b;
+x() if not $a and not $b and $c;
+x() unless not $a and not $b and $c;
+x() if not $a or not $b or $c;
+x() unless not $a or not $b or $c;
+x() if not $a and not $b and not $c;
+x() unless not $a and not $b and not $c;
+x() if not $a or not $b or not $c;
+x() unless not $a or not $b or not $c;
+x() unless not $a or not $b or not $c;
 >>>>
+my $c;
 x() unless $a;
 x() if $a;
 x() unless $a or $b;
 x() if $a or $b;
 x() unless $a and $b;
-x() unless not $a && $b;
+x() if $a and $b;
+x() if not $a || $b and $c;
+x() unless not $a || $b and $c;
+x() if not $a && $b or $c;
+x() unless not $a && $b or $c;
+x() unless $a or $b or $c;
+x() if $a or $b or $c;
+x() unless $a and $b and $c;
+x() if $a and $b and $c;
+x() unless not $a && $b && $c;
diff --git a/op.c b/op.c
index ef8fc1a..d50660d 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4476,19 +4476,9 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
                type = OP_OR;
            else
                type = OP_AND;
-           o = first;
-           first = *firstp = cUNOPo->op_first;
-           if (o->op_next)
-               first->op_next = o->op_next;
-           cUNOPo->op_first = NULL;
-           op_free(o);
+           op_null(first);
            if (other->op_type == OP_NOT) { /* !a AND|OR !b => !(a OR|AND b) */
-               o = other;
-               other = *otherp = cUNOPo->op_first;
-               if (o->op_next)
-                   other->op_next = o->op_next;
-               cUNOPo->op_first = NULL;
-               op_free(o);
+               op_null(other);
                prepend_not = 1; /* prepend a NOT op later */
            }
        }
index a78ac72..2c2d2a6 100755 (executable)
@@ -9,7 +9,7 @@ BEGIN {
     @INC = '../lib';
 }
 
-print "1..9\n";
+print "1..11\n";
 
 my $test = 0;
 for my $i (undef, 0 .. 2, "", "0 but true") {
@@ -48,7 +48,18 @@ $i = !$x || $y;
 print "not " unless $i == 8;
 print "ok ", ++$test, "\n";
 
-($x, $y) = (0, 9);
-$i = !$x && $y;
+++$y;
+$i = !$x || !$x || !$x || $y;
 print "not " unless $i == 9;
 print "ok ", ++$test, "\n";
+
+$x = 0;
+++$y;
+$i = !$x && $y;
+print "not " unless $i == 10;
+print "ok ", ++$test, "\n";
+
+++$y;
+$i = !$x && !$x && !$x && $y;
+print "not " unless $i == 11;
+print "ok ", ++$test, "\n";