X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firverify.c;h=78c6ca117fb1b61a1e0b14b202be2b5c68b79da9;hb=f8526c841999667a93e57d08cbaa66c01f2cb5b6;hp=4868f07483a15eea4658d0dd4c84ba4293d60192;hpb=94d8ca165f5304ba0c78a7bb5ce524693b58ec2e;p=libfirm diff --git a/ir/ir/irverify.c b/ir/ir/irverify.c index 4868f0748..78c6ca117 100644 --- a/ir/ir/irverify.c +++ b/ir/ir/irverify.c @@ -348,20 +348,29 @@ static int verify_node_Proj_Start(const ir_node *p) static int verify_node_Proj_Cond(const ir_node *p) { ir_mode *mode = get_irn_mode(p); - ir_node *pred = get_Proj_pred(p); - long proj = get_Proj_proj(p); + long proj = get_Proj_proj(p); ASSERT_AND_RET_DBG( - ( - (proj >= 0 && mode == mode_X && get_irn_mode(get_Cond_selector(pred)) == mode_b) || /* compare */ - (mode == mode_X && mode_is_int(get_irn_mode(get_Cond_selector(pred)))) /* switch */ - ), + mode == mode_X && (proj == pn_Cond_false || proj == pn_Cond_true), "wrong Proj from Cond", 0, show_proj_failure(p); ); return 1; } +static int verify_node_Proj_Switch(const ir_node *p) +{ + ir_mode *mode = get_irn_mode(p); + long pn = get_Proj_proj(p); + ir_node *pred = get_Proj_pred(p); + ASSERT_AND_RET_DBG( + mode == mode_X && (pn >= 0 && pn < (long)get_Switch_n_outs(pred)), + "wrong Proj from Switch", 0, + show_proj_failure(p); + ); + return 1; +} + /** * verify a Proj(Raise) node */ @@ -863,14 +872,47 @@ static int verify_node_Cond(const ir_node *n) ir_mode *mymode = get_irn_mode(n); ir_mode *op1mode = get_irn_mode(get_Cond_selector(n)); - ASSERT_AND_RET( - /* Cond: BB x b --> X x X */ - (op1mode == mode_b || - /* Cond: BB x int --> X^n */ - mode_is_int(op1mode) ), "Cond node", 0 - ); + ASSERT_AND_RET(op1mode == mode_b, "Cond operand not mode_b", 0); ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0); + return 1; +} + +static int verify_switch_table(const ir_node *n) +{ + const ir_switch_table *table = get_Switch_table(n); + size_t n_entries = ir_switch_table_get_n_entries(table); + unsigned n_outs = get_Switch_n_outs(n); + ir_node *selector = get_Switch_selector(n); + ir_mode *mode = get_irn_mode(selector); + size_t e; + + for (e = 0; e < n_entries; ++e) { + const ir_switch_table_entry *entry + = ir_switch_table_get_entry_const(table, e); + if (entry->pn == 0) + continue; + ASSERT_AND_RET(entry->min != NULL && entry->max != NULL, + "switch table entry without min+max value", 0); + ASSERT_AND_RET(get_tarval_mode(entry->min) == mode && + get_tarval_mode(entry->max) == mode, + "switch table entry with wrong modes", 0); + ASSERT_AND_RET(tarval_cmp(entry->min, entry->max) != ir_relation_greater, + "switch table entry without min+max value", 0); + ASSERT_AND_RET(entry->pn >= 0 && entry->pn < (long)n_outs, + "switch table entry with invalid proj number", 0); + } + return 1; +} +static int verify_node_Switch(const ir_node *n) +{ + ir_mode *mymode = get_irn_mode(n); + ir_mode *op1mode = get_irn_mode(get_Switch_selector(n)); + if (!verify_switch_table(n)) + return 0; + + ASSERT_AND_RET(mode_is_int(op1mode), "Switch operand not integer", 0); + ASSERT_AND_RET(mymode == mode_T, "Switch mode is not a tuple", 0); return 1; } @@ -988,14 +1030,14 @@ static int verify_node_Sel(const ir_node *n) ASSERT_AND_RET_DBG( /* Sel: BB x M x ref x int^n --> ref */ (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)), - "Sel node", 0, show_node_failure(n) + "Sel node", 0, show_node_failure(n); ); for (i = get_Sel_n_indexs(n) - 1; i >= 0; --i) { - ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(get_Sel_index(n, i))), "Sel node", 0, show_node_failure(n)); + ASSERT_AND_RET_DBG(mode_is_int(get_irn_mode(get_Sel_index(n, i))), "Sel node", 0, show_node_failure(n);); } ent = get_Sel_entity(n); - ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n)); + ASSERT_AND_RET_DBG(ent, "Sel node with empty entity", 0, show_node_failure(n);); return 1; } @@ -1392,13 +1434,10 @@ static int verify_node_Rotl(const ir_node *n) */ static int verify_node_Conv(const ir_node *n) { - ir_graph *irg = get_irn_irg(n); - ir_mode *mymode = get_irn_mode(n); - ir_mode *op1mode = get_irn_mode(get_Conv_op(n)); + ir_mode *mymode = get_irn_mode(n); + ir_mode *op1mode = get_irn_mode(get_Conv_op(n)); - ASSERT_AND_RET_DBG( - is_irg_state(irg, IR_GRAPH_STATE_BCONV_ALLOWED) || - (mode_is_datab(op1mode) && mode_is_data(mymode)), + ASSERT_AND_RET_DBG(mode_is_data(op1mode) && mode_is_data(mymode), "Conv node", 0, show_unop_failure(n, "/* Conv: BB x datab --> data */"); ); @@ -1550,7 +1589,7 @@ static int verify_node_Free(const ir_node *n) ir_mode *mymode = get_irn_mode(n); ir_mode *op1mode = get_irn_mode(get_Free_mem(n)); ir_mode *op2mode = get_irn_mode(get_Free_ptr(n)); - ir_mode *op3mode = get_irn_mode(get_Free_size(n)); + ir_mode *op3mode = get_irn_mode(get_Free_count(n)); ASSERT_AND_RET_DBG( /* Free: BB x M x ref x int_u --> M */ @@ -1575,7 +1614,7 @@ static int verify_node_Sync(const ir_node *n) /* Sync: BB x M^n --> M */ for (i = get_Sync_n_preds(n) - 1; i >= 0; --i) { ASSERT_AND_RET( get_irn_mode(get_Sync_pred(n, i)) == mode_M, "Sync node", 0 ); - }; + } ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 ); return 1; } @@ -1748,23 +1787,26 @@ int irn_verify_irg(const ir_node *n, ir_graph *irg) unsigned idx = get_irn_idx(n); ir_node *node_from_map = get_idx_irn(irg, idx); ASSERT_AND_RET_DBG(node_from_map == n, "Node index and index map entry differ", 0, - ir_printf("node %+F node in map %+F(%p)\n", n, node_from_map, node_from_map)); + ir_printf("node %+F node in map %+F(%p)\n", n, node_from_map, node_from_map); + ); } op = get_irn_op(n); - if (_get_op_pinned(op) >= op_pin_state_exc_pinned) { + if (get_op_pinned(op) >= op_pin_state_exc_pinned) { op_pin_state state = get_irn_pinned(n); ASSERT_AND_RET_DBG( state == op_pin_state_floats || state == op_pin_state_pinned, "invalid pin state", 0, - ir_printf("node %+F", n)); + ir_printf("node %+F", n); + ); } else if (!is_Block(n) && is_irn_pinned_in_irg(n) - && !is_irg_state(irg, IR_GRAPH_STATE_BAD_BLOCK)) { + && is_irg_state(irg, IR_GRAPH_STATE_NO_BADS)) { ASSERT_AND_RET_DBG(is_Block(get_nodes_block(n)) || is_Anchor(n), "block input is not a block", 0, - ir_printf("node %+F", n)); + ir_printf("node %+F", n); + ); } if (op->ops.verify_node) @@ -1832,7 +1874,8 @@ static int check_block_cfg(const ir_node *block, check_cfg_env_t *env) ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->reachable_blocks, block), "Block is not reachable by blockwalker (endless loop with no kept block?)", 0, - ir_printf("block %+F\n", block)); + ir_printf("block %+F\n", block); + ); n_cfgpreds = get_Block_n_cfgpreds(block); branch_nodes = env->branch_nodes; @@ -1850,7 +1893,8 @@ static int check_block_cfg(const ir_node *block, check_cfg_env_t *env) former_dest = pmap_get(branch_nodes, branch); ASSERT_AND_RET_DBG(former_dest==NULL || is_unknown_jump(skip_Proj(branch)), "Multiple users on mode_X node", 0, - ir_printf("node %+F\n", branch)); + ir_printf("node %+F\n", branch); + ); pmap_insert(branch_nodes, branch, (void*)block); /* check that there's only 1 branching instruction in each block */ @@ -1864,21 +1908,20 @@ static int check_block_cfg(const ir_node *block, check_cfg_env_t *env) ASSERT_AND_RET_DBG(former_branch == NULL || former_branch == branch, "Multiple branching nodes in a block", 0, ir_printf("nodes %+F,%+F in block %+F\n", - branch, former_branch, branch_block)); + branch, former_branch, branch_block); + ); pmap_insert(branch_nodes, branch_block, branch); if (is_Cond(branch)) { long pn = get_Proj_proj(branch_proj); - if (get_irn_mode(get_Cond_selector(branch)) == mode_b) { - if (pn == pn_Cond_true) - ir_nodeset_insert(&env->true_projs, branch); - if (pn == pn_Cond_false) - ir_nodeset_insert(&env->false_projs, branch); - } else { - long default_pn = get_Cond_default_proj(branch); - if (pn == default_pn) - ir_nodeset_insert(&env->true_projs, branch); - } + if (pn == pn_Cond_true) + ir_nodeset_insert(&env->true_projs, branch); + if (pn == pn_Cond_false) + ir_nodeset_insert(&env->false_projs, branch); + } else if (is_Switch(branch)) { + long pn = get_Proj_proj(branch_proj); + if (pn == pn_Switch_default) + ir_nodeset_insert(&env->true_projs, branch); } } @@ -1900,24 +1943,30 @@ static int verify_block_branch(const ir_node *block, check_cfg_env_t *env) || ir_nodeset_contains(&env->kept_nodes, block) || block == get_irg_end_block(get_irn_irg(block)), "block contains no cfop", 0, - ir_printf("block %+F\n", block)); + ir_printf("block %+F\n", block); + ); return 1; } static int verify_cond_projs(const ir_node *cond, check_cfg_env_t *env) { - if (get_irn_mode(get_Cond_selector(cond)) == mode_b) { - ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, cond), - "Cond node lacks true proj", 0, - ir_printf("Cond %+F\n", cond)); - ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->false_projs, cond), - "Cond node lacks false proj", 0, - ir_printf("Cond %+F\n", cond)); - } else { - ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, cond), - "Cond node lacks default Proj", 0, - ir_printf("Cond %+F\n", cond)); - } + ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, cond), + "Cond node lacks true proj", 0, + ir_printf("Cond %+F\n", cond); + ); + ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->false_projs, cond), + "Cond node lacks false proj", 0, + ir_printf("Cond %+F\n", cond); + ); + return 1; +} + +static int verify_switch_projs(const ir_node *sw, check_cfg_env_t *env) +{ + ASSERT_AND_RET_DBG(ir_nodeset_contains(&env->true_projs, sw), + "Switch node lacks default Proj", 0, + ir_printf("Switch %+F\n", sw); + ); return 1; } @@ -1928,6 +1977,8 @@ static void assert_branch(ir_node *node, void *data) env->res &= verify_block_branch(node, env); } else if (is_Cond(node)) { env->res &= verify_cond_projs(node, env); + } else if (is_Switch(node)) { + env->res &= verify_switch_projs(node, env); } } @@ -2000,7 +2051,7 @@ int irg_verify(ir_graph *irg, unsigned flags) irg_walk_anchors( irg, - pinned && get_irg_dom_state(irg) == dom_consistent + pinned && is_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE) ? verify_wrap_ssa : verify_wrap, NULL, &res @@ -2065,7 +2116,7 @@ int irn_verify_irg_dump(const ir_node *n, ir_graph *irg, firm_verify_failure_msg = NULL; do_node_verification(FIRM_VERIFICATION_ERROR_ONLY); res = irn_verify_irg(n, irg); - if (res && get_irg_dom_state(irg) == dom_consistent && + if (res && is_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE) && get_irg_pinned(irg) == op_pin_state_pinned) res = check_dominance_for_node(n); do_node_verification(old); @@ -2203,49 +2254,50 @@ void firm_set_default_verifier(unsigned code, ir_op_ops *ops) break switch (code) { - CASE(Proj); + CASE(Add); + CASE(Alloc); + CASE(And); CASE(Block); - CASE(Start); - CASE(Jmp); - CASE(IJmp); + CASE(Bound); + CASE(Call); + CASE(Cast); + CASE(Cmp); CASE(Cond); - CASE(Return); - CASE(Raise); + CASE(Confirm); CASE(Const); - CASE(SymConst); - CASE(Sel); + CASE(Conv); + CASE(CopyB); + CASE(Div); + CASE(Eor); + CASE(Free); + CASE(IJmp); CASE(InstOf); - CASE(Call); - CASE(Add); - CASE(Sub); + CASE(Jmp); + CASE(Load); CASE(Minus); + CASE(Mod); CASE(Mul); CASE(Mulh); - CASE(Div); - CASE(Mod); - CASE(And); - CASE(Or); - CASE(Eor); + CASE(Mux); CASE(Not); - CASE(Cmp); + CASE(Or); + CASE(Phi); + CASE(Proj); + CASE(Raise); + CASE(Return); + CASE(Rotl); + CASE(Sel); CASE(Shl); CASE(Shr); CASE(Shrs); - CASE(Rotl); - CASE(Conv); - CASE(Cast); - CASE(Phi); - CASE(Load); + CASE(Start); CASE(Store); - CASE(Alloc); - CASE(Free); + CASE(Sub); + CASE(Switch); + CASE(SymConst); CASE(Sync); - CASE(Confirm); - CASE(Mux); - CASE(CopyB); - CASE(Bound); default: - /* leave NULL */; + break; } #undef CASE @@ -2255,22 +2307,23 @@ void firm_set_default_verifier(unsigned code, ir_op_ops *ops) break switch (code) { - CASE(Start); - CASE(Cond); - CASE(Raise); - CASE(InstOf); + CASE(Alloc); + CASE(Bound); CASE(Call); + CASE(Cond); + CASE(CopyB); CASE(Div); - CASE(Mod); + CASE(InstOf); CASE(Load); - CASE(Store); - CASE(Alloc); + CASE(Mod); CASE(Proj); + CASE(Raise); + CASE(Start); + CASE(Store); + CASE(Switch); CASE(Tuple); - CASE(CopyB); - CASE(Bound); default: - /* leave NULL */; + break; } #undef CASE }