merge Perl_ck_cmp() and Perl_ck_eq()
authorDavid Mitchell <davem@iabyn.com>
Fri, 4 Aug 2017 15:40:15 +0000 (16:40 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 4 Aug 2017 15:45:02 +0000 (16:45 +0100)
I added ck_eq() recently; it's used for the EQ and NE ops, while ck_cmp()
is used for LT, GT, LE, GE.

This commit eliminates the ck_eq() function and makes ck_cmp() handle
EQ/NE too.

This will will make it easier to extend the index() == -1 optimisation
to handle index() >= 0 etc too.

At the moment there should be no functional differences.

embed.h
op.c
opcode.h
proto.h
regen/opcodes

diff --git a/embed.h b/embed.h
index a41020d..cbef9aa 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define ck_delete(a)           Perl_ck_delete(aTHX_ a)
 #define ck_each(a)             Perl_ck_each(aTHX_ a)
 #define ck_eof(a)              Perl_ck_eof(aTHX_ a)
-#define ck_eq(a)               Perl_ck_eq(aTHX_ a)
 #define ck_eval(a)             Perl_ck_eval(aTHX_ a)
 #define ck_exec(a)             Perl_ck_exec(aTHX_ a)
 #define ck_exists(a)           Perl_ck_exists(aTHX_ a)
diff --git a/op.c b/op.c
index a72dd13..9e05afa 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9681,11 +9681,23 @@ is_dollar_bracket(pTHX_ const OP * const o)
        && strEQ(GvNAME(cGVOPx_gv(kid)), "[");
 }
 
+/* for lt, gt, le, ge, eq, ne and their i_ variants */
+
 OP *
 Perl_ck_cmp(pTHX_ OP *o)
 {
+    bool is_eq;
+    OP *indexop, *constop, *start;
+    SV *sv;
+
     PERL_ARGS_ASSERT_CK_CMP;
-    if (ckWARN(WARN_SYNTAX)) {
+
+    is_eq = (   o->op_type == OP_EQ
+             || o->op_type == OP_NE
+             || o->op_type == OP_I_EQ
+             || o->op_type == OP_I_NE);
+
+    if (!is_eq && ckWARN(WARN_SYNTAX)) {
        const OP *kid = cUNOPo->op_first;
        if (kid &&
             (
@@ -9700,9 +9712,49 @@ Perl_ck_cmp(pTHX_ OP *o)
            Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                        "$[ used in %s (did you mean $] ?)", OP_DESC(o));
     }
-    return o;
+    if (!is_eq)
+        return o;
+
+    /* convert (index(...) == -1) and variations into
+     *   (r)index/BOOL(,NEG)
+     */
+
+    indexop = cUNOPo->op_first;
+    constop = OpSIBLING(indexop);
+    start = NULL;
+    if (indexop->op_type == OP_CONST) {
+        constop = indexop;
+        indexop = OpSIBLING(constop);
+        start = constop;
+    }
+
+    if (indexop->op_type != OP_INDEX && indexop->op_type != OP_RINDEX)
+        return o;
+
+    if (constop->op_type != OP_CONST)
+        return o;
+
+    sv = cSVOPx_sv(constop);
+    if (!(sv && SvIOK_notUV(sv) && SvIVX(sv) == -1))
+        return o;
+
+    /* ($lex = index(....)) == -1 */
+    if (indexop->op_private & OPpTARGET_MY)
+        return o;
+
+    indexop->op_flags &= ~OPf_PARENS;
+    indexop->op_flags |= (o->op_flags & OPf_PARENS);
+    indexop->op_private |= OPpTRUEBOOL;
+    if (o->op_type == OP_EQ || o->op_type == OP_I_EQ)
+        indexop->op_private |= OPpINDEX_BOOLNEG;
+    /* cut out the index op and free the eq,const ops */
+    (void)op_sibling_splice(o, start, 1, NULL);
+    op_free(o);
+
+    return indexop;
 }
 
+
 OP *
 Perl_ck_concat(pTHX_ OP *o)
 {
@@ -9816,55 +9868,6 @@ Perl_ck_eof(pTHX_ OP *o)
 }
 
 
-/* for OP_EQ, OP_NE, OP_I_EQ, OP_I_NE */
-
-OP *
-Perl_ck_eq(pTHX_ OP *o)
-{
-    OP *indexop, *constop, *start;
-    SV *sv;
-    PERL_ARGS_ASSERT_CK_EQ;
-
-    /* convert (index(...) == -1) and variations into
-     *   (r)index/BOOL(,NEG)
-     */
-
-    indexop = cUNOPo->op_first;
-    constop = OpSIBLING(indexop);
-    start = NULL;
-    if (indexop->op_type == OP_CONST) {
-        constop = indexop;
-        indexop = OpSIBLING(constop);
-        start = constop;
-    }
-
-    if (indexop->op_type != OP_INDEX && indexop->op_type != OP_RINDEX)
-        return o;
-
-    if (constop->op_type != OP_CONST)
-        return o;
-
-    sv = cSVOPx_sv(constop);
-    if (!(sv && SvIOK_notUV(sv) && SvIVX(sv) == -1))
-        return o;
-
-    /* ($lex = index(....)) == -1 */
-    if (indexop->op_private & OPpTARGET_MY)
-        return o;
-
-    indexop->op_flags &= ~OPf_PARENS;
-    indexop->op_flags |= (o->op_flags & OPf_PARENS);
-    indexop->op_private |= OPpTRUEBOOL;
-    if (o->op_type == OP_EQ || o->op_type == OP_I_EQ)
-        indexop->op_private |= OPpINDEX_BOOLNEG;
-    /* cut out the index op and free the eq,const ops */
-    (void)op_sibling_splice(o, start, 1, NULL);
-    op_free(o);
-
-    return indexop;
-}
-
-
 OP *
 Perl_ck_eval(pTHX_ OP *o)
 {
index 23595c1..bd8de36 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -1460,10 +1460,10 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
        Perl_ck_cmp,            /* i_le */
        Perl_ck_cmp,            /* ge */
        Perl_ck_cmp,            /* i_ge */
-       Perl_ck_eq,             /* eq */
-       Perl_ck_eq,             /* i_eq */
-       Perl_ck_eq,             /* ne */
-       Perl_ck_eq,             /* i_ne */
+       Perl_ck_cmp,            /* eq */
+       Perl_ck_cmp,            /* i_eq */
+       Perl_ck_cmp,            /* ne */
+       Perl_ck_cmp,            /* i_ne */
        Perl_ck_null,           /* ncmp */
        Perl_ck_null,           /* i_ncmp */
        Perl_ck_null,           /* slt */
diff --git a/proto.h b/proto.h
index efbc52b..e667d4f 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -363,11 +363,6 @@ PERL_CALLCONV OP * Perl_ck_eof(pTHX_ OP *o)
 #define PERL_ARGS_ASSERT_CK_EOF        \
        assert(o)
 
-PERL_CALLCONV OP *     Perl_ck_eq(pTHX_ OP *o)
-                       __attribute__warn_unused_result__;
-#define PERL_ARGS_ASSERT_CK_EQ \
-       assert(o)
-
 PERL_CALLCONV OP *     Perl_ck_eval(pTHX_ OP *o)
                        __attribute__warn_unused_result__;
 #define PERL_ARGS_ASSERT_CK_EVAL       \
index 137a44f..096c6fe 100644 (file)
@@ -144,10 +144,10 @@ le                numeric le (<=)         ck_cmp          Iifs2   S S<
 i_le           integer le (<=)         ck_cmp          ifs2    S S<
 ge             numeric ge (>=)         ck_cmp          Iifs2   S S<
 i_ge           integer ge (>=)         ck_cmp          ifs2    S S<
-eq             numeric eq (==)         ck_eq           Iifs2   S S<
-i_eq           integer eq (==)         ck_eq           ifs2    S S<
-ne             numeric ne (!=)         ck_eq           Iifs2   S S<
-i_ne           integer ne (!=)         ck_eq           ifs2    S S<
+eq             numeric eq (==)         ck_cmp          Iifs2   S S<
+i_eq           integer eq (==)         ck_cmp          ifs2    S S<
+ne             numeric ne (!=)         ck_cmp          Iifs2   S S<
+i_ne           integer ne (!=)         ck_cmp          ifs2    S S<
 ncmp           numeric comparison (<=>)        ck_null         Iifst2  S S<
 i_ncmp         integer comparison (<=>)        ck_null         ifst2   S S<