X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeverify.c;h=ab1e9390d12bc568f7f17abdb5e8549a77e76f6f;hb=d300330b1e6df8c8914b8fb70cf38ee1c8ca2634;hp=bc281ae84fce1273f3a0dba891f8b0668594d173;hpb=55437d814f031e648187e51ba6e952907f9a480c;p=libfirm diff --git a/ir/be/beverify.c b/ir/be/beverify.c index bc281ae84..ab1e9390d 100644 --- a/ir/be/beverify.c +++ b/ir/be/beverify.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -62,11 +62,12 @@ typedef struct be_verify_register_pressure_env_t_ { /** * Print all nodes of a pset into a file. */ -static void print_living_values(FILE *F, pset *live_nodes) { +static void print_living_values(FILE *F, const ir_nodeset_t *live_nodes) { + ir_nodeset_iterator_t iter; ir_node *node; ir_fprintf(F, "\t"); - foreach_pset(live_nodes, node) { + foreach_ir_nodeset(live_nodes, node, iter) { ir_fprintf(F, "%+F ", node); } ir_fprintf(F, "\n"); @@ -77,18 +78,22 @@ static void print_living_values(FILE *F, pset *live_nodes) { */ static void verify_liveness_walker(ir_node *block, void *data) { be_verify_register_pressure_env_t *env = (be_verify_register_pressure_env_t *)data; - pset *live_nodes = pset_new_ptr_default(); + ir_nodeset_t live_nodes; ir_node *irn; int pressure; /* collect register pressure info, start with end of a block */ - be_liveness_end_of_block(env->lv, env->arch_env, env->cls, block, live_nodes); + // ir_fprintf(stderr, "liveness check %+F\n", block); + ir_nodeset_init(&live_nodes); + be_liveness_end_of_block(env->lv, env->arch_env, env->cls, block, + &live_nodes); - pressure = pset_count(live_nodes); + // print_living_values(stderr, &live_nodes); + pressure = ir_nodeset_size(&live_nodes); if(pressure > env->registers_available) { ir_fprintf(stderr, "Verify Warning: Register pressure too high at end of block %+F(%s) (%d/%d):\n", block, get_irg_dump_name(env->irg), pressure, env->registers_available); - print_living_values(stderr, live_nodes); + print_living_values(stderr, &live_nodes); env->problem_found = 1; } @@ -96,18 +101,20 @@ static void verify_liveness_walker(ir_node *block, void *data) { if (is_Phi(irn)) break; - be_liveness_transfer(env->arch_env, env->cls, irn, live_nodes); + // print_living_values(stderr, &live_nodes); + be_liveness_transfer(env->arch_env, env->cls, irn, &live_nodes); - pressure = pset_count(live_nodes); + pressure = ir_nodeset_size(&live_nodes); if(pressure > env->registers_available) { ir_fprintf(stderr, "Verify Warning: Register pressure too high before node %+F in %+F(%s) (%d/%d):\n", irn, block, get_irg_dump_name(env->irg), pressure, env->registers_available); - print_living_values(stderr, live_nodes); + print_living_values(stderr, &live_nodes); env->problem_found = 1; + assert(0); } } - del_pset(live_nodes); + ir_nodeset_destroy(&live_nodes); } /** @@ -118,7 +125,7 @@ int be_verify_register_pressure(const be_irg_t *birg, ir_graph *irg) { be_verify_register_pressure_env_t env; - env.lv = be_liveness(irg); + env.lv = be_liveness(birg); env.irg = irg; env.arch_env = birg->main_env->arch_env; env.cls = cls; @@ -249,48 +256,17 @@ static void verify_schedule_walker(ir_node *block, void *data) { env->problem_found = 1; } -#ifdef SCHEDULE_PROJS - /* check that all projs/keeps are behind their nodes */ - if(is_Proj(node)) { - ir_node *prev = sched_prev(node); - while(is_Proj(prev)) - prev = sched_prev(prev); - if(get_Proj_pred(node) != prev) { - ir_fprintf(stderr, "%+F not scheduled after its pred node in block %+F (%s)\n", - node, block, get_irg_dump_name(env->irg)); - env->problem_found = 1; - } - } -#endif if(be_is_Keep(node)) { - int arity = get_irn_arity(node); - int problem = 0; + /* at least 1 of the keep arguments has to be it schedule + * predecessor */ + int arity = get_irn_arity(node); + int problem = 1; + ir_node *prev = sched_prev(node); for(i = 0; i < arity; ++i) { ir_node *in = get_irn_n(node, i); - ir_node *succ = sched_next(in); - while(succ != node && !sched_is_end(succ)) { - /* the node in between has to be another input of the - * keep or a Proj */ - int i2; - int found = 0; - - if(is_Proj(succ)) { - succ = sched_next(succ); - continue; - } - - for(i2 = 0; i2 < arity; ++i2) { - ir_node *in2 = get_irn_n(node, i2); - if(in2 == succ) { - found = 1; - break; - } - } - if(!found) - problem = 1; - - succ = sched_next(succ); - } + in = skip_Proj(in); + if(in == prev) + problem = 0; } if(problem) { ir_fprintf(stderr, "%+F not scheduled after its pred node in block %+F (%s)\n", @@ -731,7 +707,9 @@ typedef struct _be_verify_register_allocation_env_t { int problem_found; } be_verify_register_allocation_env_t; -static void check_register_constraints(ir_node *node, be_verify_register_allocation_env_t *env) { +static void check_register_constraints(ir_node *node, + be_verify_register_allocation_env_t *env) +{ const arch_env_t *arch_env = env->arch_env; const arch_register_t *reg; int i, arity; @@ -771,8 +749,8 @@ static void check_register_constraints(ir_node *node, be_verify_register_allocat reg = arch_get_irn_register(arch_env, pred); if (reg == NULL) { - ir_fprintf(stderr, "Verify warning: Node %+F in block %+F(%s) should have a register assigned\n", - pred, get_nodes_block(pred), get_irg_dump_name(env->irg)); + ir_fprintf(stderr, "Verify warning: Node %+F in block %+F(%s) should have a register assigned (%+F input constraint)\n", + pred, get_nodes_block(pred), get_irg_dump_name(env->irg), node); env->problem_found = 1; continue; } @@ -785,14 +763,17 @@ static void check_register_constraints(ir_node *node, be_verify_register_allocat } static void check_register_allocation(be_verify_register_allocation_env_t *env, - const arch_register_class_t *regclass, pset *nodes) { + const arch_register_class_t *regclass, + ir_nodeset_t *nodes) +{ const arch_env_t *arch_env = env->arch_env; const arch_register_t *reg = NULL; int fail = 0; bitset_t *registers = bitset_alloca(arch_register_class_n_regs(regclass)); ir_node *node; + ir_nodeset_iterator_t iter; - foreach_pset(nodes, node) { + foreach_ir_nodeset(nodes, node, iter) { if (arch_get_irn_reg_class(arch_env, node, -1) != regclass) continue; @@ -803,7 +784,6 @@ static void check_register_allocation(be_verify_register_allocation_env_t *env, continue; if (bitset_is_set(registers, reg->index)) { - pset_break(nodes); fail = 1; break; } @@ -815,7 +795,7 @@ static void check_register_allocation(be_verify_register_allocation_env_t *env, reg->name, get_nodes_block(node), get_irg_dump_name(env->irg)); env->problem_found = 1; - foreach_pset(nodes, node) { + foreach_ir_nodeset(nodes, node, iter) { if (arch_get_irn_register(arch_env, node) == reg) { ir_fprintf(stderr, " at node %+F\n", node); } @@ -833,34 +813,37 @@ static void verify_block_register_allocation(ir_node *block, void *data) { for (i = 0; i < nregclasses; ++i) { const arch_register_class_t *regclass = arch_isa_get_reg_class(isa, i); ir_node *node; - pset *live_nodes = pset_new_ptr_default(); + ir_nodeset_t live_nodes; - be_liveness_end_of_block(env->lv, env->arch_env, regclass, block, live_nodes); - check_register_allocation(env, regclass, live_nodes); + ir_nodeset_init(&live_nodes); + + be_liveness_end_of_block(env->lv, env->arch_env, regclass, block, + &live_nodes); + check_register_allocation(env, regclass, &live_nodes); sched_foreach_reverse(block, node) { if (is_Phi(node)) break; - be_liveness_transfer(env->arch_env, regclass, node, live_nodes); - check_register_allocation(env, regclass, live_nodes); + be_liveness_transfer(env->arch_env, regclass, node, &live_nodes); + check_register_allocation(env, regclass, &live_nodes); check_register_constraints(node, env); } - del_pset(live_nodes); + ir_nodeset_destroy(&live_nodes); } } -int be_verify_register_allocation(const arch_env_t *arch_env, ir_graph *irg) { +int be_verify_register_allocation(const be_irg_t *birg) { be_verify_register_allocation_env_t env; - env.arch_env = arch_env; - env.irg = irg; - env.lv = be_liveness(irg); + env.arch_env = be_get_birg_arch_env(birg); + env.irg = be_get_birg_irg(birg); + env.lv = be_liveness(birg); env.problem_found = 0; be_liveness_assure_sets(env.lv); - irg_block_walk_graph(irg, verify_block_register_allocation, NULL, &env); + irg_block_walk_graph(env.irg, verify_block_register_allocation, NULL, &env); be_liveness_free(env.lv); @@ -887,10 +870,14 @@ static void check_out_edges(ir_node *node, verify_out_dead_nodes_env *env) { return; mark_irn_visited(node); + /* we find too many (uncritical) dead nodes in block out edges */ + if(is_Block(node)) + return; + foreach_out_edge(node, edge) { ir_node* src = get_edge_src_irn(edge); - if(!bitset_is_set(env->reachable, get_irn_idx(src)) && !is_Block(node)) { + if(!bitset_is_set(env->reachable, get_irn_idx(src)) && !is_Block(src)) { ir_fprintf(stderr, "Verify warning: Node %+F in block %+F(%s) only reachable through out edges from %+F\n", src, get_nodes_block(src), get_irg_dump_name(irg), node); env->problem_found = 1;