From: Mathieu Desnoyers Date: Tue, 17 Jul 2012 19:07:43 +0000 (-0400) Subject: Filter: specialize double-s64 binary comparators X-Git-Tag: v2.1.0-rc1~20 X-Git-Url: https://git.lttng.org/?a=commitdiff_plain;h=dbea82ec5429aa713b029dfdfaf2fcff5287321d;p=lttng-ust.git Filter: specialize double-s64 binary comparators Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust/filter-bytecode.h b/liblttng-ust/filter-bytecode.h index 50a60c69..3358a2fd 100644 --- a/liblttng-ust/filter-bytecode.h +++ b/liblttng-ust/filter-bytecode.h @@ -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, diff --git a/liblttng-ust/lttng-filter-interpreter.c b/liblttng-ust/lttng-filter-interpreter.c index dbc3cfea..3ce00bba 100644 --- a/liblttng-ust/lttng-filter-interpreter.c +++ b/liblttng-ust/lttng-filter-interpreter.c @@ -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; diff --git a/liblttng-ust/lttng-filter-specialize.c b/liblttng-ust/lttng-filter-specialize.c index ef0d811b..b422f508 100644 --- a/liblttng-ust/lttng-filter-specialize.c +++ b/liblttng-ust/lttng-filter-specialize.c @@ -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)) { diff --git a/liblttng-ust/lttng-filter-validator.c b/liblttng-ust/lttng-filter-validator.c index a41deb5e..4e257f5d 100644 --- a/liblttng-ust/lttng-filter-validator.c +++ b/liblttng-ust/lttng-filter-validator.c @@ -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)) {