Filter: specialize double-s64 binary comparators
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 Jul 2012 19:07:43 +0000 (15:07 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 Jul 2012 19:07:43 +0000 (15:07 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
liblttng-ust/filter-bytecode.h
liblttng-ust/lttng-filter-interpreter.c
liblttng-ust/lttng-filter-specialize.c
liblttng-ust/lttng-filter-validator.c

index 50a60c69da46923706149152eff512b71666546e..3358a2fd6c90c733cc43ee49b65d2d4c1e0b1310 100644 (file)
@@ -94,6 +94,21 @@ enum filter_op {
        FILTER_OP_GE_DOUBLE,
        FILTER_OP_LE_DOUBLE,
 
+       /* Mixed S64-double binary comparators */
+       FILTER_OP_EQ_DOUBLE_S64,
+       FILTER_OP_NE_DOUBLE_S64,
+       FILTER_OP_GT_DOUBLE_S64,
+       FILTER_OP_LT_DOUBLE_S64,
+       FILTER_OP_GE_DOUBLE_S64,
+       FILTER_OP_LE_DOUBLE_S64,
+
+       FILTER_OP_EQ_S64_DOUBLE,
+       FILTER_OP_NE_S64_DOUBLE,
+       FILTER_OP_GT_S64_DOUBLE,
+       FILTER_OP_LT_S64_DOUBLE,
+       FILTER_OP_GE_S64_DOUBLE,
+       FILTER_OP_LE_S64_DOUBLE,
+
        /* unary */
        FILTER_OP_UNARY_PLUS,
        FILTER_OP_UNARY_MINUS,
index dbc3cfeafb5cdaac719a2c1ec38dad933b674d6e..3ce00bbafc1d3941270ebf7134055a3a0551d2e1 100644 (file)
@@ -216,6 +216,21 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                [ FILTER_OP_GE_DOUBLE ] = &&LABEL_FILTER_OP_GE_DOUBLE,
                [ FILTER_OP_LE_DOUBLE ] = &&LABEL_FILTER_OP_LE_DOUBLE,
 
+               /* Mixed S64-double binary comparators */
+               [ FILTER_OP_EQ_DOUBLE_S64 ] = &&LABEL_FILTER_OP_EQ_DOUBLE_S64,
+               [ FILTER_OP_NE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_NE_DOUBLE_S64,
+               [ FILTER_OP_GT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GT_DOUBLE_S64,
+               [ FILTER_OP_LT_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LT_DOUBLE_S64,
+               [ FILTER_OP_GE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_GE_DOUBLE_S64,
+               [ FILTER_OP_LE_DOUBLE_S64 ] = &&LABEL_FILTER_OP_LE_DOUBLE_S64,
+
+               [ FILTER_OP_EQ_S64_DOUBLE ] = &&LABEL_FILTER_OP_EQ_S64_DOUBLE,
+               [ FILTER_OP_NE_S64_DOUBLE ] = &&LABEL_FILTER_OP_NE_S64_DOUBLE,
+               [ FILTER_OP_GT_S64_DOUBLE ] = &&LABEL_FILTER_OP_GT_S64_DOUBLE,
+               [ FILTER_OP_LT_S64_DOUBLE ] = &&LABEL_FILTER_OP_LT_S64_DOUBLE,
+               [ FILTER_OP_GE_S64_DOUBLE ] = &&LABEL_FILTER_OP_GE_S64_DOUBLE,
+               [ FILTER_OP_LE_S64_DOUBLE ] = &&LABEL_FILTER_OP_LE_S64_DOUBLE,
+
                /* unary */
                [ FILTER_OP_UNARY_PLUS ] = &&LABEL_FILTER_OP_UNARY_PLUS,
                [ FILTER_OP_UNARY_MINUS ] = &&LABEL_FILTER_OP_UNARY_MINUS,
@@ -433,11 +448,7 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int res;
 
-                       if (unlikely(estack_ax(stack)->type == REG_S64))
-                               estack_ax(stack)->u.d = (double) estack_ax(stack)->u.v;
-                       else if (unlikely(estack_bx(stack)->type == REG_S64))
-                               estack_bx(stack)->u.d = (double) estack_bx(stack)->u.v;
-                       res = (estack_bx(stack)->u.v == estack_ax(stack)->u.v);
+                       res = (estack_bx(stack)->u.d == estack_ax(stack)->u.d);
                        estack_pop(stack);
                        estack_ax(stack)->u.v = res;
                        estack_ax(stack)->type = REG_S64;
@@ -448,11 +459,7 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int res;
 
-                       if (unlikely(estack_ax(stack)->type == REG_S64))
-                               estack_ax(stack)->u.d = (double) estack_ax(stack)->u.v;
-                       else if (unlikely(estack_bx(stack)->type == REG_S64))
-                               estack_bx(stack)->u.d = (double) estack_bx(stack)->u.v;
-                       res = (estack_bx(stack)->u.v != estack_ax(stack)->u.v);
+                       res = (estack_bx(stack)->u.d != estack_ax(stack)->u.d);
                        estack_pop(stack);
                        estack_ax(stack)->u.v = res;
                        estack_ax(stack)->type = REG_S64;
@@ -463,11 +470,7 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int res;
 
-                       if (unlikely(estack_ax(stack)->type == REG_S64))
-                               estack_ax(stack)->u.d = (double) estack_ax(stack)->u.v;
-                       else if (unlikely(estack_bx(stack)->type == REG_S64))
-                               estack_bx(stack)->u.d = (double) estack_bx(stack)->u.v;
-                       res = (estack_bx(stack)->u.v > estack_ax(stack)->u.v);
+                       res = (estack_bx(stack)->u.d > estack_ax(stack)->u.d);
                        estack_pop(stack);
                        estack_ax(stack)->u.v = res;
                        estack_ax(stack)->type = REG_S64;
@@ -478,11 +481,7 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int res;
 
-                       if (unlikely(estack_ax(stack)->type == REG_S64))
-                               estack_ax(stack)->u.d = (double) estack_ax(stack)->u.v;
-                       else if (unlikely(estack_bx(stack)->type == REG_S64))
-                               estack_bx(stack)->u.d = (double) estack_bx(stack)->u.v;
-                       res = (estack_bx(stack)->u.v < estack_ax(stack)->u.v);
+                       res = (estack_bx(stack)->u.d < estack_ax(stack)->u.d);
                        estack_pop(stack);
                        estack_ax(stack)->u.v = res;
                        estack_ax(stack)->type = REG_S64;
@@ -493,11 +492,7 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int res;
 
-                       if (unlikely(estack_ax(stack)->type == REG_S64))
-                               estack_ax(stack)->u.d = (double) estack_ax(stack)->u.v;
-                       else if (unlikely(estack_bx(stack)->type == REG_S64))
-                               estack_bx(stack)->u.d = (double) estack_bx(stack)->u.v;
-                       res = (estack_bx(stack)->u.v >= estack_ax(stack)->u.v);
+                       res = (estack_bx(stack)->u.d >= estack_ax(stack)->u.d);
                        estack_pop(stack);
                        estack_ax(stack)->u.v = res;
                        estack_ax(stack)->type = REG_S64;
@@ -508,11 +503,142 @@ int lttng_filter_interpret_bytecode(void *filter_data,
                {
                        int res;
 
-                       if (unlikely(estack_ax(stack)->type == REG_S64))
-                               estack_ax(stack)->u.d = (double) estack_ax(stack)->u.v;
-                       else if (unlikely(estack_bx(stack)->type == REG_S64))
-                               estack_bx(stack)->u.d = (double) estack_bx(stack)->u.v;
-                       res = (estack_bx(stack)->u.v <= estack_ax(stack)->u.v);
+                       res = (estack_bx(stack)->u.d <= estack_ax(stack)->u.d);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+
+               /* Mixed S64-double binary comparators */
+               OP(FILTER_OP_EQ_DOUBLE_S64):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.d == estack_ax(stack)->u.v);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_NE_DOUBLE_S64):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.d != estack_ax(stack)->u.v);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_GT_DOUBLE_S64):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.d > estack_ax(stack)->u.v);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_LT_DOUBLE_S64):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.d < estack_ax(stack)->u.v);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_GE_DOUBLE_S64):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.d >= estack_ax(stack)->u.v);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_LE_DOUBLE_S64):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.d <= estack_ax(stack)->u.v);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+
+               OP(FILTER_OP_EQ_S64_DOUBLE):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.v == estack_ax(stack)->u.d);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_NE_S64_DOUBLE):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.v != estack_ax(stack)->u.d);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_GT_S64_DOUBLE):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.v > estack_ax(stack)->u.d);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_LT_S64_DOUBLE):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.v < estack_ax(stack)->u.d);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_GE_S64_DOUBLE):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.v >= estack_ax(stack)->u.d);
+                       estack_pop(stack);
+                       estack_ax(stack)->u.v = res;
+                       estack_ax(stack)->type = REG_S64;
+                       next_pc += sizeof(struct binary_op);
+                       PO;
+               }
+               OP(FILTER_OP_LE_S64_DOUBLE):
+               {
+                       int res;
+
+                       res = (estack_bx(stack)->u.v <= estack_ax(stack)->u.d);
                        estack_pop(stack);
                        estack_ax(stack)->u.v = res;
                        estack_ax(stack)->type = REG_S64;
index ef0d811bf5c342418a146ed52799694047857183..b422f50863a5f4608405c5c41ca5ed32faf1f61f 100644 (file)
@@ -79,10 +79,13 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                                if (vstack_bx(stack)->type == REG_S64)
                                        insn->op = FILTER_OP_EQ_S64;
                                else
-                                       insn->op = FILTER_OP_EQ_DOUBLE;
+                                       insn->op = FILTER_OP_EQ_DOUBLE_S64;
                                break;
                        case REG_DOUBLE:
-                               insn->op = FILTER_OP_EQ_DOUBLE;
+                               if (vstack_bx(stack)->type == REG_S64)
+                                       insn->op = FILTER_OP_EQ_S64_DOUBLE;
+                               else
+                                       insn->op = FILTER_OP_EQ_DOUBLE;
                                break;
                        }
                        /* Pop 2, push 1 */
@@ -112,10 +115,13 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                                if (vstack_bx(stack)->type == REG_S64)
                                        insn->op = FILTER_OP_NE_S64;
                                else
-                                       insn->op = FILTER_OP_NE_DOUBLE;
+                                       insn->op = FILTER_OP_NE_DOUBLE_S64;
                                break;
                        case REG_DOUBLE:
-                               insn->op = FILTER_OP_NE_DOUBLE;
+                               if (vstack_bx(stack)->type == REG_S64)
+                                       insn->op = FILTER_OP_NE_S64_DOUBLE;
+                               else
+                                       insn->op = FILTER_OP_NE_DOUBLE;
                                break;
                        }
                        /* Pop 2, push 1 */
@@ -145,10 +151,13 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                                if (vstack_bx(stack)->type == REG_S64)
                                        insn->op = FILTER_OP_GT_S64;
                                else
-                                       insn->op = FILTER_OP_GT_DOUBLE;
+                                       insn->op = FILTER_OP_GT_DOUBLE_S64;
                                break;
                        case REG_DOUBLE:
-                               insn->op = FILTER_OP_GT_DOUBLE;
+                               if (vstack_bx(stack)->type == REG_S64)
+                                       insn->op = FILTER_OP_GT_S64_DOUBLE;
+                               else
+                                       insn->op = FILTER_OP_GT_DOUBLE;
                                break;
                        }
                        /* Pop 2, push 1 */
@@ -178,10 +187,13 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                                if (vstack_bx(stack)->type == REG_S64)
                                        insn->op = FILTER_OP_LT_S64;
                                else
-                                       insn->op = FILTER_OP_LT_DOUBLE;
+                                       insn->op = FILTER_OP_LT_DOUBLE_S64;
                                break;
                        case REG_DOUBLE:
-                               insn->op = FILTER_OP_LT_DOUBLE;
+                               if (vstack_bx(stack)->type == REG_S64)
+                                       insn->op = FILTER_OP_LT_S64_DOUBLE;
+                               else
+                                       insn->op = FILTER_OP_LT_DOUBLE;
                                break;
                        }
                        /* Pop 2, push 1 */
@@ -211,10 +223,13 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                                if (vstack_bx(stack)->type == REG_S64)
                                        insn->op = FILTER_OP_GE_S64;
                                else
-                                       insn->op = FILTER_OP_GE_DOUBLE;
+                                       insn->op = FILTER_OP_GE_DOUBLE_S64;
                                break;
                        case REG_DOUBLE:
-                               insn->op = FILTER_OP_GE_DOUBLE;
+                               if (vstack_bx(stack)->type == REG_S64)
+                                       insn->op = FILTER_OP_GE_S64_DOUBLE;
+                               else
+                                       insn->op = FILTER_OP_GE_DOUBLE;
                                break;
                        }
                        /* Pop 2, push 1 */
@@ -243,10 +258,13 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                                if (vstack_bx(stack)->type == REG_S64)
                                        insn->op = FILTER_OP_LE_S64;
                                else
-                                       insn->op = FILTER_OP_LE_DOUBLE;
+                                       insn->op = FILTER_OP_LE_DOUBLE_S64;
                                break;
                        case REG_DOUBLE:
-                               insn->op = FILTER_OP_LE_DOUBLE;
+                               if (vstack_bx(stack)->type == REG_S64)
+                                       insn->op = FILTER_OP_LE_S64_DOUBLE;
+                               else
+                                       insn->op = FILTER_OP_LE_DOUBLE;
                                break;
                        }
                        vstack_ax(stack)->type = REG_S64;
@@ -272,6 +290,18 @@ int lttng_filter_specialize_bytecode(struct bytecode_runtime *bytecode)
                case FILTER_OP_LT_DOUBLE:
                case FILTER_OP_GE_DOUBLE:
                case FILTER_OP_LE_DOUBLE:
+               case FILTER_OP_EQ_DOUBLE_S64:
+               case FILTER_OP_NE_DOUBLE_S64:
+               case FILTER_OP_GT_DOUBLE_S64:
+               case FILTER_OP_LT_DOUBLE_S64:
+               case FILTER_OP_GE_DOUBLE_S64:
+               case FILTER_OP_LE_DOUBLE_S64:
+               case FILTER_OP_EQ_S64_DOUBLE:
+               case FILTER_OP_NE_S64_DOUBLE:
+               case FILTER_OP_GT_S64_DOUBLE:
+               case FILTER_OP_LT_S64_DOUBLE:
+               case FILTER_OP_GE_S64_DOUBLE:
+               case FILTER_OP_LE_S64_DOUBLE:
                {
                        /* Pop 2, push 1 */
                        if (vstack_pop(stack)) {
index a41deb5e7ac54bdd1df2b8a842f368d3a556fd76..4e257f5d9b969558f29e15dfcd34d3ea0e33dd85 100644 (file)
@@ -237,6 +237,18 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
        case FILTER_OP_LT_DOUBLE:
        case FILTER_OP_GE_DOUBLE:
        case FILTER_OP_LE_DOUBLE:
+       case FILTER_OP_EQ_DOUBLE_S64:
+       case FILTER_OP_NE_DOUBLE_S64:
+       case FILTER_OP_GT_DOUBLE_S64:
+       case FILTER_OP_LT_DOUBLE_S64:
+       case FILTER_OP_GE_DOUBLE_S64:
+       case FILTER_OP_LE_DOUBLE_S64:
+       case FILTER_OP_EQ_S64_DOUBLE:
+       case FILTER_OP_NE_S64_DOUBLE:
+       case FILTER_OP_GT_S64_DOUBLE:
+       case FILTER_OP_LT_S64_DOUBLE:
+       case FILTER_OP_GE_S64_DOUBLE:
+       case FILTER_OP_LE_S64_DOUBLE:
        {
                if (unlikely(pc + sizeof(struct binary_op)
                                > start_pc + bytecode->len)) {
@@ -508,14 +520,48 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if ((vstack_ax(stack)->type != REG_DOUBLE && vstack_ax(stack)->type != REG_S64)
-                               || (vstack_bx(stack)-> type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64)) {
-                       ERR("Unexpected register type for double comparator\n");
+               if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_DOUBLE) {
+                       ERR("Double operator should have two double registers\n");
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_DOUBLE) {
-                       ERR("Double operator should have at least one double register\n");
+               break;
+       }
+
+       case FILTER_OP_EQ_DOUBLE_S64:
+       case FILTER_OP_NE_DOUBLE_S64:
+       case FILTER_OP_GT_DOUBLE_S64:
+       case FILTER_OP_LT_DOUBLE_S64:
+       case FILTER_OP_GE_DOUBLE_S64:
+       case FILTER_OP_LE_DOUBLE_S64:
+       {
+               if (!vstack_ax(stack) || !vstack_bx(stack)) {
+                       ERR("Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               if (vstack_ax(stack)->type != REG_S64 && vstack_bx(stack)->type != REG_DOUBLE) {
+                       ERR("Double-S64 operator has unexpected register types\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               break;
+       }
+
+       case FILTER_OP_EQ_S64_DOUBLE:
+       case FILTER_OP_NE_S64_DOUBLE:
+       case FILTER_OP_GT_S64_DOUBLE:
+       case FILTER_OP_LT_S64_DOUBLE:
+       case FILTER_OP_GE_S64_DOUBLE:
+       case FILTER_OP_LE_S64_DOUBLE:
+       {
+               if (!vstack_ax(stack) || !vstack_bx(stack)) {
+                       ERR("Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64) {
+                       ERR("S64-Double operator has unexpected register types\n");
                        ret = -EINVAL;
                        goto end;
                }
@@ -834,6 +880,18 @@ int exec_insn(struct bytecode_runtime *bytecode,
        case FILTER_OP_LT_DOUBLE:
        case FILTER_OP_GE_DOUBLE:
        case FILTER_OP_LE_DOUBLE:
+       case FILTER_OP_EQ_DOUBLE_S64:
+       case FILTER_OP_NE_DOUBLE_S64:
+       case FILTER_OP_GT_DOUBLE_S64:
+       case FILTER_OP_LT_DOUBLE_S64:
+       case FILTER_OP_GE_DOUBLE_S64:
+       case FILTER_OP_LE_DOUBLE_S64:
+       case FILTER_OP_EQ_S64_DOUBLE:
+       case FILTER_OP_NE_S64_DOUBLE:
+       case FILTER_OP_GT_S64_DOUBLE:
+       case FILTER_OP_LT_S64_DOUBLE:
+       case FILTER_OP_GE_S64_DOUBLE:
+       case FILTER_OP_LE_S64_DOUBLE:
        {
                /* Pop 2, push 1 */
                if (vstack_pop(stack)) {
This page took 0.032851 seconds and 4 git commands to generate.