From 08505635e929d3d74c63a7b0046ad0b6d2a9203d Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 13 Apr 2024 10:56:25 +0100 Subject: [PATCH] Refactor branch coverage to use counter rather than bit flags Co-authored-by: Blebowski <34539154+Blebowski@users.noreply.github.com> --- src/cov/cov-data.c | 7 +- src/cov/cov-exclude.c | 52 +++++++++++++- src/cov/cov-export.c | 3 +- src/cov/cov-report.c | 53 ++++++++++----- src/jit/jit-irgen.c | 23 +------ src/lower.c | 127 ++++++++++++++++++++++------------- src/vcode.c | 16 +---- src/vcode.h | 3 +- test/regress/gold/cover9.txt | 7 +- test/test_lower.c | 59 ++++++++++------ 10 files changed, 226 insertions(+), 124 deletions(-) diff --git a/src/cov/cov-data.c b/src/cov/cov-data.c index f1ae62b1..72f4af35 100644 --- a/src/cov/cov-data.c +++ b/src/cov/cov-data.c @@ -1,5 +1,5 @@ // -// Copyright (C) 2013-2023 Nick Gasson +// Copyright (C) 2013-2024 Nick Gasson // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,6 +32,7 @@ #include #include #include +#include //#define COVER_DEBUG_EMIT //#define COVER_DEBUG_DUMP @@ -384,10 +385,10 @@ static void cover_merge_one_item(cover_item_t *item, int32_t data) switch (item->kind) { case COV_ITEM_STMT: case COV_ITEM_FUNCTIONAL: + case COV_ITEM_BRANCH: item->data += data; break; case COV_ITEM_TOGGLE: - case COV_ITEM_BRANCH: case COV_ITEM_EXPRESSION: case COV_ITEM_STATE: item->data |= data; @@ -778,7 +779,7 @@ static void cover_merge_scope(cover_scope_t *old_s, cover_scope_t *new_s) // Compare based on hierarchical path, each // coverage item has unique hierarchical name - if (new->hier == old->hier) { + if (new->hier == old->hier && (new->flags == old->flags)) { assert(new->kind == old->kind); #ifdef COVER_DEBUG_MERGE printf("Merging coverage item: %s\n", istr(old->hier)); diff --git a/src/cov/cov-exclude.c b/src/cov/cov-exclude.c index 459e06f7..0a6e0380 100644 --- a/src/cov/cov-exclude.c +++ b/src/cov/cov-exclude.c @@ -58,8 +58,58 @@ static int cover_exclude_item(cover_exclude_ctx_t *ctx, cover_item_t *item, return 1; case COV_ITEM_BRANCH: - case COV_ITEM_TOGGLE: + { + uint32_t allowed = 0; + for (int i = 0; i < item->num; i++) + allowed |= item[i].flags; + allowed &= COVER_FLAGS_ALL_BINS; + + // If bin is not given, exclude all bins of a item + uint32_t bmask = allowed; + if (bin != NULL) + bmask = cover_bin_str_to_bmask(bin); + + if (!(bmask & allowed)) { + LOCAL_TEXT_BUF tb = tb_new(); + cover_bmask_to_bin_list(allowed, tb); + + diag_t *d = diag_new(DIAG_FATAL, &ctx->loc); + diag_printf(d, "invalid bin: $bold$'%s'$$ for %s: '%s'", bin, + kind_str, istr(item->hier)); + diag_hint(d, NULL, "valid bins are: %s", tb_get(tb)); + diag_emit(d); + + fatal_exit(1); + } + + LOCAL_TEXT_BUF tb = tb_new(); + cover_bmask_to_bin_list(bmask, tb); + note_at(&ctx->loc, "excluding %s: '%s' bins: %s", kind_str, + istr(hier), tb_get(tb)); + + uint32_t excl_cov = 0; + for (int i = 0; i < item->num; i++) { + if ((item->flags & bmask) && item[i].data > 0) + excl_cov |= (item->flags & bmask); + } + + if (excl_cov) { + tb_rewind(tb); + cover_bmask_to_bin_list(excl_cov, tb); + warn_at(&ctx->loc, "%s: '%s' bins: %s already covered!", + kind_str, istr(hier), tb_get(tb)); + } + + for (int i = 0; i < item->num; i++) { + if (item->flags & bmask) + item[i].excl_msk |= 0xFFFFFFFF; + } + + return item->num; + } + case COV_ITEM_EXPRESSION: + case COV_ITEM_TOGGLE: { uint32_t allowed = item->flags & COVER_FLAGS_ALL_BINS, bmask = allowed; diff --git a/src/cov/cov-export.c b/src/cov/cov-export.c index 01c0b915..0a66c7a3 100644 --- a/src/cov/cov-export.c +++ b/src/cov/cov-export.c @@ -126,7 +126,8 @@ static void cobertura_export_scope(cobertura_report_t *report, { cobertura_line_t *l = cobertura_get_line(class, &(t->loc)); l->branch = true; - l->bflags |= t->data; + if (t->data > 0) + l->bflags |= t->flags; } break; default: diff --git a/src/cov/cov-report.c b/src/cov/cov-report.c index 846bc6a6..4b0ac778 100644 --- a/src/cov/cov-report.c +++ b/src/cov/cov-report.c @@ -1215,23 +1215,46 @@ static void cover_report_scope(cover_report_ctx_t *ctx, break; case COV_ITEM_BRANCH: - // If/else, when else - if (item->flags & COV_FLAG_TRUE && item->flags & COV_FLAG_FALSE) { - cover_item_to_chain(ctx, item, COV_FLAG_TRUE, - &hits, &misses, &excludes); - cover_item_to_chain(ctx, item, COV_FLAG_FALSE, - &hits, &misses, &excludes); - *skipped += cover_append_to_chain(&(ctx->ch_branch), item, line, - hits, misses, excludes, limit); + if (item->flags & COV_FLAG_CHOICE) { // Case, with select + ctx->flat_stats.total_branches++; + ctx->nested_stats.total_branches++; + + if (item->data > 0) { + ctx->flat_stats.hit_branches++; + ctx->nested_stats.hit_branches++; + hits |= COV_FLAG_CHOICE; + } + else if (item->excl_msk & COV_FLAG_TRUE) { + ctx->flat_stats.hit_branches++; + ctx->nested_stats.hit_branches++; + hits |= COV_FLAG_CHOICE; + } + else + misses |= COV_FLAG_CHOICE; } - - // Case, with select - if (item->flags & COV_FLAG_CHOICE) { - cover_item_to_chain(ctx, item, COV_FLAG_CHOICE, - &hits, &misses, &excludes); - *skipped += cover_append_to_chain(&(ctx->ch_branch), item, line, - hits, misses, excludes, limit); + else if (item->num == 2) { // If/else, when else + ctx->flat_stats.total_branches += 2; + ctx->nested_stats.total_branches += 2; + + if (item[0].data > 0 || (item[0].excl_msk & COV_FLAG_TRUE)) { + ctx->flat_stats.hit_branches++; + ctx->nested_stats.hit_branches++; + hits |= COV_FLAG_TRUE; + } + else + misses |= COV_FLAG_TRUE; + + if (item[1].data > 0 || (item[1].excl_msk & COV_FLAG_FALSE)) { + ctx->flat_stats.hit_branches++; + ctx->nested_stats.hit_branches++; + hits |= COV_FLAG_FALSE; + } + else + misses |= COV_FLAG_FALSE; } + + *skipped += cover_append_to_chain(&(ctx->ch_branch), item, line, + hits, misses, excludes, limit); break; case COV_ITEM_TOGGLE: diff --git a/src/jit/jit-irgen.c b/src/jit/jit-irgen.c index 09a2303d..767c2cbf 100644 --- a/src/jit/jit-irgen.c +++ b/src/jit/jit-irgen.c @@ -3299,32 +3299,13 @@ static void irgen_op_cover_stmt(jit_irgen_t *g, int op) static void irgen_op_cover_branch(jit_irgen_t *g, int op) { - vcode_reg_t arg0 = vcode_get_arg(op, 0); - if (arg0 != g->flags) { - jit_value_t result = irgen_get_arg(g, op, 0); - j_cmp(g, JIT_CC_NE, result, jit_value_from_int64(0)); - } - uint32_t tag = vcode_get_tag(op); jit_value_t mem = jit_addr_from_cover_tag(tag); - jit_value_t tval, fval; - if (vcode_get_subkind(op) & COV_FLAG_CHOICE) { - // TODO: just make a seperate cover choice op? - tval = jit_value_from_int64(COV_FLAG_CHOICE); - fval = jit_value_from_int64(0); - } - else { - tval = jit_value_from_int64(COV_FLAG_TRUE); - fval = jit_value_from_int64(COV_FLAG_FALSE); - } - - jit_value_t mask = j_csel(g, tval, fval); - // XXX: this should be atomic jit_value_t cur = j_load(g, JIT_SZ_32, mem); - jit_value_t next = j_or(g, cur, mask); - j_store(g, JIT_SZ_32, next, mem); + jit_value_t inc = j_add(g, cur, jit_value_from_int64(1)); + j_store(g, JIT_SZ_32, inc, mem); } static void irgen_op_cover_expr(jit_irgen_t *g, int op) diff --git a/src/lower.c b/src/lower.c index f7e24435..17b83675 100644 --- a/src/lower.c +++ b/src/lower.c @@ -1484,14 +1484,44 @@ static vcode_reg_t lower_arith(tree_t fcall, subprogram_kind_t kind, } static void lower_branch_coverage(lower_unit_t *lu, tree_t b, - unsigned int flags, vcode_reg_t hit_reg) + vcode_block_t true_bb, vcode_block_t false_bb) { assert(cover_enabled(lu->cover, COVER_MASK_BRANCH)); - cover_item_t *item = cover_add_item(lu->cover, tree_to_object(b), NULL, - COV_ITEM_BRANCH, flags); - if (item != NULL) - emit_cover_branch(hit_reg, item->tag, flags); + object_t *obj = tree_to_object(b); + + cover_item_t *item_true, *item_false = NULL; + if (tree_kind(b) == T_ASSOC) { + if ((item_true = cover_add_item(lu->cover, obj, NULL, COV_ITEM_BRANCH, + COV_FLAG_CHOICE)) == NULL) + return; + + item_true->num = 1; + } + else { + if ((item_true = cover_add_item(lu->cover, obj, NULL, COV_ITEM_BRANCH, + COV_FLAG_TRUE)) == NULL) + return; + + item_true->num = 2; + item_false = cover_add_item(lu->cover, obj, NULL, COV_ITEM_BRANCH, + COV_FLAG_FALSE); + assert(item_false != NULL); + } + + assert(true_bb != VCODE_INVALID_BLOCK); + assert(item_true->num == 1 || item_true->num == 2); + + vcode_select_block(true_bb); + emit_cover_branch(item_true->tag); + + if (item_false == NULL) + return; + + assert(false_bb != VCODE_INVALID_BLOCK); + + vcode_select_block(false_bb); + emit_cover_branch(item_false->tag); } static int32_t lower_toggle_item_for(lower_unit_t *lu, type_t type, @@ -6253,6 +6283,7 @@ static void lower_sequence(lower_unit_t *lu, tree_t block, loop_stack_t *loops) static void lower_if(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) { vcode_block_t exit_bb = VCODE_INVALID_BLOCK; + const bool want_coverage = cover_enabled(lu->cover, COVER_MASK_BRANCH); const int nconds = tree_conds(stmt); for (int i = 0; i < nconds; i++) { @@ -6262,13 +6293,9 @@ static void lower_if(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) if (tree_has_value(c)) { vcode_reg_t test = lower_rvalue(lu, tree_value(c)); - - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) - lower_branch_coverage(lu, c, COV_FLAG_FALSE | COV_FLAG_TRUE, test); - vcode_block_t btrue = emit_block(); - if (i == nconds - 1) { + if (i == nconds - 1 && !want_coverage) { if (exit_bb == VCODE_INVALID_BLOCK) exit_bb = emit_block(); next_bb = exit_bb; @@ -6277,6 +6304,10 @@ static void lower_if(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) next_bb = emit_block(); emit_cond(test, btrue, next_bb); + + if (want_coverage) + lower_branch_coverage(lu, c, btrue, next_bb); + vcode_select_block(btrue); } @@ -6292,8 +6323,11 @@ static void lower_if(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) if (next_bb == VCODE_INVALID_BLOCK) break; - else - vcode_select_block(next_bb); + + vcode_select_block(next_bb); + + if (i == nconds - 1 && want_coverage) + emit_jump(exit_bb); } if (exit_bb != VCODE_INVALID_BLOCK) @@ -6614,10 +6648,10 @@ static void lower_while(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) vcode_select_block(test_bb); vcode_reg_t test = lower_rvalue(lu, tree_value(stmt)); - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) - lower_branch_coverage(lu, stmt, COV_FLAG_FALSE | COV_FLAG_TRUE, test); - emit_cond(test, body_bb, exit_bb); + + if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) + lower_branch_coverage(lu, stmt, body_bb, exit_bb); } else { test_bb = body_bb = @@ -6655,11 +6689,11 @@ static void lower_loop_control(lower_unit_t *lu, tree_t stmt, vcode_block_t true_bb = emit_block(); vcode_reg_t result = lower_rvalue(lu, tree_value(stmt)); - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) - lower_branch_coverage(lu, stmt, COV_FLAG_FALSE | COV_FLAG_TRUE, result); - emit_cond(result, true_bb, false_bb); + if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) + lower_branch_coverage(lu, stmt, true_bb, false_bb); + vcode_select_block(true_bb); } @@ -6684,6 +6718,7 @@ static void lower_case_scalar(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) { const int nstmts = tree_stmts(stmt); + const bool want_coverage = cover_enabled(lu->cover, COVER_MASK_BRANCH); vcode_block_t def_bb = VCODE_INVALID_BLOCK; vcode_block_t exit_bb = emit_block(); @@ -6716,13 +6751,14 @@ static void lower_case_scalar(lower_unit_t *lu, tree_t stmt, vcode_reg_t hcmp_reg = emit_cmp(VCODE_CMP_LEQ, value_reg, high_reg); vcode_reg_t hit_reg = emit_and(lcmp_reg, hcmp_reg); - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) - lower_branch_coverage(lu, a, COV_FLAG_CHOICE, hit_reg); - vcode_block_t skip_bb = emit_block(); - vcode_block_t hit_bb = emit_block(); + emit_cond(hit_reg, hit_bb, skip_bb); + + if (want_coverage) + lower_branch_coverage(lu, a, hit_bb, VCODE_INVALID_BLOCK); + vcode_select_block(hit_bb); lower_sequence(lu, alt, loops); @@ -6760,33 +6796,41 @@ static void lower_case_scalar(lower_unit_t *lu, tree_t stmt, if (hit_bb == VCODE_INVALID_BLOCK) hit_bb = emit_block(); + // Must track each branch cover item separately + vcode_block_t cover_bb = hit_bb; + if (want_coverage && nassocs > 1) + cover_bb = emit_block(); + if (kind == A_OTHERS) { assert(def_bb == VCODE_INVALID_BLOCK); - def_bb = hit_bb; - - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) { - vcode_select_block(hit_bb); - vcode_reg_t true_reg = emit_const(vtype_bool(), 1); - lower_branch_coverage(lu, a, COV_FLAG_CHOICE, true_reg); + if (want_coverage) { + def_bb = cover_bb; + lower_branch_coverage(lu, a, cover_bb, VCODE_INVALID_BLOCK); } + else + def_bb = hit_bb; } else { vcode_select_block(start_bb); cases[cptr] = lower_rvalue(lu, tree_name(a)); - blocks[cptr] = hit_bb; - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) { - vcode_select_block(hit_bb); + if (want_coverage) { + blocks[cptr] = cover_bb; cover_push_scope(lu->cover, a); - vcode_reg_t hit_reg = - emit_cmp(VCODE_CMP_EQ, cases[cptr], value_reg); - lower_branch_coverage(lu, a, COV_FLAG_CHOICE, hit_reg); + lower_branch_coverage(lu, a, cover_bb, VCODE_INVALID_BLOCK); cover_pop_scope(lu->cover); } + else + blocks[cptr] = hit_bb; cptr++; } + if (cover_bb != hit_bb) { + vcode_select_block(cover_bb); + emit_jump(hit_bb); + } + cover_pop_scope(lu->cover); } @@ -6967,11 +7011,8 @@ static void lower_case_array(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) assert(def_bb == VCODE_INVALID_BLOCK); def_bb = hit_bb; - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) { - vcode_select_block(hit_bb); - vcode_reg_t true_reg = emit_const(vtype_bool(), 1); - lower_branch_coverage(lu, a, COV_FLAG_CHOICE, true_reg); - } + if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) + lower_branch_coverage(lu, a, hit_bb, VCODE_INVALID_BLOCK); } else { tree_t name = tree_name(a); @@ -7013,12 +7054,8 @@ static void lower_case_array(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops) encoding[cptr] = enc; // TODO: How to handle have_dup == true ? - if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) { - vcode_select_block(hit_bb); - vcode_reg_t hit_reg = - emit_cmp(VCODE_CMP_EQ, cases[cptr], enc_reg); - lower_branch_coverage(lu, a, COV_FLAG_CHOICE, hit_reg); - } + if (cover_enabled(lu->cover, COVER_MASK_BRANCH)) + lower_branch_coverage(lu, a, hit_bb, VCODE_INVALID_BLOCK); cptr++; } diff --git a/src/vcode.c b/src/vcode.c index 5733d28c..169dfebf 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -44,8 +44,6 @@ DECLARE_AND_DEFINE_ARRAY(vcode_type); #define OP_HAS_ADDRESS(x) \ (x == VCODE_OP_LOAD || x == VCODE_OP_STORE || x == VCODE_OP_INDEX \ || x == VCODE_OP_VAR_UPREF) -#define OP_HAS_SUBKIND(x) \ - (x == VCODE_OP_COVER_BRANCH) #define OP_HAS_FUNC(x) \ (x == VCODE_OP_FCALL || x == VCODE_OP_PCALL || x == VCODE_OP_RESUME \ || x == VCODE_OP_CLOSURE || x == VCODE_OP_PROTECTED_INIT \ @@ -84,7 +82,6 @@ typedef struct { vcode_reg_array_t args; loc_t loc; vcode_type_t type; // OP_HAS_TYPE - unsigned subkind; // OP_HAS_SUBKIND union { ident_t func; // OP_HAS_FUNC ident_t ident; // OP_HAS_IDENT @@ -814,13 +811,6 @@ ident_t vcode_get_ident(int op) return o->ident; } -unsigned vcode_get_subkind(int op) -{ - op_t *o = vcode_op_data(op); - assert(OP_HAS_SUBKIND(o->kind)); - return o->subkind; -} - int64_t vcode_get_value(int op) { op_t *o = vcode_op_data(op); @@ -2125,13 +2115,13 @@ void vcode_dump_with_mark(int mark_op, vcode_dump_fn_t callback, void *arg) break; case VCODE_OP_COVER_STMT: + case VCODE_OP_COVER_BRANCH: { printf("%s %u ", vcode_op_string(op->kind), op->tag); } break; case VCODE_OP_COVER_TOGGLE: - case VCODE_OP_COVER_BRANCH: case VCODE_OP_COVER_EXPR: case VCODE_OP_COVER_STATE: { @@ -5737,12 +5727,10 @@ void emit_cover_stmt(uint32_t tag) op->tag = tag; } -void emit_cover_branch(vcode_reg_t test, uint32_t tag, uint32_t flags) +void emit_cover_branch(uint32_t tag) { op_t *op = vcode_add_op(VCODE_OP_COVER_BRANCH); - vcode_add_arg(op, test); op->tag = tag; - op->subkind = flags; } void emit_cover_toggle(vcode_reg_t signal, uint32_t tag) diff --git a/src/vcode.h b/src/vcode.h index fa35be9a..9e4f301c 100644 --- a/src/vcode.h +++ b/src/vcode.h @@ -344,7 +344,6 @@ vcode_reg_t vcode_get_result(int op); unsigned vcode_get_dim(int op); int vcode_get_hops(int op); int vcode_get_field(int op); -unsigned vcode_get_subkind(int op); uint32_t vcode_get_tag(int op); int vcode_count_vars(void); @@ -479,7 +478,7 @@ void emit_exponent_check(vcode_reg_t exp, vcode_reg_t locus); void emit_zero_check(vcode_reg_t denom, vcode_reg_t locus); void emit_debug_out(vcode_reg_t reg); void emit_cover_stmt(uint32_t tag); -void emit_cover_branch(vcode_reg_t test, uint32_t tag, uint32_t flags); +void emit_cover_branch(uint32_t tag); void emit_cover_toggle(vcode_reg_t signal, uint32_t tag); void emit_cover_state(vcode_reg_t signal, vcode_reg_t low, uint32_t tag); void emit_cover_expr(vcode_reg_t new_mask, uint32_t tag); diff --git a/test/regress/gold/cover9.txt b/test/regress/gold/cover9.txt index ee34a60e..ef9a0a63 100644 --- a/test/regress/gold/cover9.txt +++ b/test/regress/gold/cover9.txt @@ -93,7 +93,7 @@ | 5 | exclude WORK.COVER9.SUB_BLOCK_INST.* | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -** Warning: branch: 'WORK.COVER9.SUB_BLOCK_INST.AND_GATE._S0._B0' bins: BIN_FALSE already covered! +** Warning: branch: 'WORK.COVER9.SUB_BLOCK_INST.AND_GATE._S0._B0' bins: BIN_TRUE already covered! > data/cover9_ef1.txt:5 | 5 | exclude WORK.COVER9.SUB_BLOCK_INST.* @@ -148,6 +148,11 @@ | 20 | exclude WORK.COVER9.AND_GATE._S0._B0 BIN_TRUE | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +** Warning: branch: 'WORK.COVER9.AND_GATE._S0._B0' bins: BIN_TRUE already covered! + > data/cover9_ef1.txt:20 + | + 20 | exclude WORK.COVER9.AND_GATE._S0._B0 BIN_TRUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ** Note: excluding branch: 'WORK.COVER9._P1._S0._B3._B0' bins: BIN_CHOICE > data/cover9_ef1.txt:23 | diff --git a/test/test_lower.c b/test/test_lower.c index f623427e..e1aed4c2 100644 --- a/test/test_lower.c +++ b/test/test_lower.c @@ -1975,33 +1975,40 @@ START_TEST(test_cover) { VCODE_OP_SELECT }, { VCODE_OP_ADD }, { VCODE_OP_COVER_EXPR, .tag = 13 }, - { VCODE_OP_COVER_BRANCH, .tag = 14 }, { VCODE_OP_COND, .target = 2, .target_else = 3 } }; CHECK_BB(1); EXPECT_BB(2) = { - { VCODE_OP_COVER_STMT, .tag = 15 }, + { VCODE_OP_COVER_BRANCH, .tag = 14 }, + { VCODE_OP_COVER_STMT, .tag = 16 }, { VCODE_OP_CONST, .value = 2 }, { VCODE_OP_STORE, .name = "V" }, - { VCODE_OP_JUMP, .target = 3 } + { VCODE_OP_JUMP, .target = 4 } }; CHECK_BB(2); EXPECT_BB(3) = { + { VCODE_OP_COVER_BRANCH, .tag = 15 }, + { VCODE_OP_JUMP, .target = 4 } + }; + + CHECK_BB(3); + + EXPECT_BB(4) = { { VCODE_OP_VAR_UPREF, .name = "S", .hops = 1 }, { VCODE_OP_LOAD_INDIRECT }, { VCODE_OP_CONST, .value = 1 }, { VCODE_OP_CONST, .value = 0 }, { VCODE_OP_CONST, .value = 1 }, { VCODE_OP_SCHED_WAVEFORM }, - { VCODE_OP_COVER_STMT, .tag = 16 }, - { VCODE_OP_WAIT, .target = 4 } + { VCODE_OP_COVER_STMT, .tag = 17 }, + { VCODE_OP_WAIT, .target = 5 } }; - CHECK_BB(3); + CHECK_BB(4); jit_free(jit); @@ -2442,7 +2449,6 @@ START_TEST(test_choice1) { VCODE_OP_CMP, .cmp = VCODE_CMP_GEQ }, { VCODE_OP_CMP, .cmp = VCODE_CMP_LEQ }, { VCODE_OP_AND }, - { VCODE_OP_COVER_BRANCH, .tag = 0 }, { VCODE_OP_COND, .target = 4, .target_else = 3 }, }; @@ -2460,6 +2466,7 @@ START_TEST(test_choice1) CHECK_BB(3); EXPECT_BB(4) = { + { VCODE_OP_COVER_BRANCH, .tag = 0 }, { VCODE_OP_CONST, .value = -1 }, { VCODE_OP_STORE, .name = "X" }, { VCODE_OP_JUMP, .target = 2 } @@ -2468,10 +2475,6 @@ START_TEST(test_choice1) CHECK_BB(4); EXPECT_BB(5) = { - { VCODE_OP_CMP }, - { VCODE_OP_COVER_BRANCH, .tag = 1 }, - { VCODE_OP_CMP }, - { VCODE_OP_COVER_BRANCH, .tag = 2 }, { VCODE_OP_CONST, .value = 3 }, { VCODE_OP_STORE, .name = "X" }, { VCODE_OP_JUMP, .target = 2 } @@ -2480,28 +2483,42 @@ START_TEST(test_choice1) CHECK_BB(5); EXPECT_BB(6) = { - { VCODE_OP_CMP }, - { VCODE_OP_COVER_BRANCH, .tag = 3 }, - { VCODE_OP_CMP }, - { VCODE_OP_COVER_BRANCH, .tag = 4 }, - { VCODE_OP_CMP }, - { VCODE_OP_COVER_BRANCH, .tag = 5 }, + { VCODE_OP_COVER_BRANCH, .tag = 1 }, + { VCODE_OP_JUMP, .target = 5 } + }; + + CHECK_BB(6); + + EXPECT_BB(7) = { + { VCODE_OP_COVER_BRANCH, .tag = 2 }, + { VCODE_OP_JUMP, .target = 5 } + }; + + CHECK_BB(7); + + EXPECT_BB(8) = { { VCODE_OP_CONST, .value = 4 }, { VCODE_OP_STORE, .name = "X" }, { VCODE_OP_JUMP, .target = 2 } }; - CHECK_BB(6); + CHECK_BB(8); - EXPECT_BB(7) = { - { VCODE_OP_CONST, .value = 1 }, + EXPECT_BB(9) = { + { VCODE_OP_COVER_BRANCH, .tag = 3 }, + { VCODE_OP_JUMP, .target = 8 } + }; + + CHECK_BB(9); + + EXPECT_BB(12) = { { VCODE_OP_COVER_BRANCH, .tag = 6 }, { VCODE_OP_CONST, .value = 5 }, { VCODE_OP_STORE, .name = "X" }, { VCODE_OP_JUMP, .target = 2 } }; - CHECK_BB(7); + CHECK_BB(12); jit_free(jit); } -- 2.39.2