This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
op.c: Two more boolean %hash optimisations
authorFather Chrysostomos <sprout@cpan.org>
Tue, 28 Aug 2012 08:22:13 +0000 (01:22 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 28 Aug 2012 08:23:06 +0000 (01:23 -0700)
In commit c8fe3bdf72 I used the wrong flag for ?:, causing it to slow
down unless the ?: was in void context.

OP_NOT has been sensitive to void context all along, which was never
necessary.

These two should be just as fast.  The second should not be slower:

!%hash;
!!%hash;

op.c

diff --git a/op.c b/op.c
index f807d33..14ca6fc 100644 (file)
--- a/op.c
+++ b/op.c
@@ -10496,10 +10496,18 @@ Perl_rpeep(pTHX_ register OP *o)
             OP *fop;
             OP *sop;
             
             OP *fop;
             OP *sop;
             
+#define HV_OR_SCALARHV(op)                                   \
+    (  (op)->op_type == OP_PADHV || (op)->op_type == OP_RV2HV \
+       ? (op)                                                  \
+       : (op)->op_type == OP_SCALAR && (op)->op_flags & OPf_KIDS \
+       && (  cUNOPx(op)->op_first->op_type == OP_PADHV          \
+          || cUNOPx(op)->op_first->op_type == OP_RV2HV)          \
+         ? cUNOPx(op)->op_first                                   \
+         : NULL)
+
         case OP_NOT:
         case OP_NOT:
-            fop = cUNOP->op_first;
-            sop = NULL;
-            goto stitch_keys;
+            if ((fop = HV_OR_SCALARHV(cUNOP->op_first)))
+                fop->op_private |= OPpTRUEBOOL;
             break;
 
         case OP_AND:
             break;
 
         case OP_AND:
@@ -10514,17 +10522,7 @@ Perl_rpeep(pTHX_ register OP *o)
                o->op_next = o->op_next->op_next;
            DEFER(cLOGOP->op_other);
           
                o->op_next = o->op_next->op_next;
            DEFER(cLOGOP->op_other);
           
-          stitch_keys:     
            o->op_opt = 1;
            o->op_opt = 1;
-#define HV_OR_SCALARHV(op)                                   \
-    (  (op)->op_type == OP_PADHV || (op)->op_type == OP_RV2HV \
-       ? (op)                                                  \
-       : (op)->op_type == OP_SCALAR && (op)->op_flags & OPf_KIDS \
-       && (  cUNOPx(op)->op_first->op_type == OP_PADHV          \
-          || cUNOPx(op)->op_first->op_type == OP_RV2HV)          \
-         ? cUNOPx(op)->op_first                                   \
-         : NULL)
-
             fop = HV_OR_SCALARHV(fop);
             if (sop) sop = HV_OR_SCALARHV(sop);
             if (fop || sop
             fop = HV_OR_SCALARHV(fop);
             if (sop) sop = HV_OR_SCALARHV(sop);
             if (fop || sop
@@ -10566,7 +10564,7 @@ Perl_rpeep(pTHX_ register OP *o)
        
        case OP_COND_EXPR:
            if ((fop = HV_OR_SCALARHV(cLOGOP->op_first)))
        
        case OP_COND_EXPR:
            if ((fop = HV_OR_SCALARHV(cLOGOP->op_first)))
-               fop->op_private |= OPpMAYBE_TRUEBOOL;
+               fop->op_private |= OPpTRUEBOOL;
 #undef HV_OR_SCALARHV
            /* GERONIMO! */
        }    
 #undef HV_OR_SCALARHV
            /* GERONIMO! */
        }