X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbelower.c;h=0ff5504eb4ba5349f9ea058f910aa785396ec14b;hb=b9d45e08e23bcf058fa8f2d9e18dd78e8cccd044;hp=cb1dcb5e6324a12da91910085ae363e83f12245b;hpb=ce96c087e689e244abcb48e7e823929a90d771ba;p=libfirm diff --git a/ir/be/belower.c b/ir/be/belower.c index cb1dcb5e6..0ff5504eb 100644 --- a/ir/be/belower.c +++ b/ir/be/belower.c @@ -23,6 +23,7 @@ #include "bechordal_t.h" #include "besched_t.h" #include "bestat.h" +#include "benodesets.h" #include "irgmod.h" #include "iredges_t.h" @@ -36,13 +37,12 @@ #endif #undef is_Perm -#define is_Perm(arch_env, irn) (arch_irn_classify(arch_env, irn) == arch_irn_class_perm) +#define is_Perm(arch_env, irn) (arch_irn_class_is(arch_env, irn, perm)) /* associates op with it's copy and CopyKeep */ typedef struct { ir_node *op; /* an irn which must be different */ pset *copies; /* all non-spillable copies of this irn */ - pset *copy_keeps; /* the CopyKeep's of this irn */ } op_copy_assoc_t; /* environment for constraints */ @@ -270,8 +270,9 @@ static void lower_perm_node(ir_node *irn, void *walk_env) { const arch_register_class_t *reg_class; const arch_env_t *arch_env; lower_env_t *env = walk_env; - int real_size = 0; - int n, i, pn, do_copy, j, n_ops; + int real_size = 0; + int keep_perm = 0; + int n, i, pn, do_copy, j, n_ops; reg_pair_t *pairs; const ir_edge_t *edge; perm_cycle_t *cycle; @@ -337,6 +338,7 @@ static void lower_perm_node(ir_node *irn, void *walk_env) { /* reroute the edges from the proj to the argument */ edges_reroute(pairs[i].out_node, pairs[i].in_node, env->chord_env->irg); + set_irn_n(pairs[i].out_node, 0, new_Bad()); pairs[i].checked = 1; } @@ -366,11 +368,14 @@ static void lower_perm_node(ir_node *irn, void *walk_env) { } DB((mod, LEVEL_1, "\n")); - /* We don't need to do anything if we have a Perm with two + /* + We don't need to do anything if we have a Perm with two elements which represents a cycle, because those nodes - already represent exchange nodes */ + already represent exchange nodes + */ if (n == 2 && cycle->type == PERM_CYCLE) { free(cycle); + keep_perm = 1; continue; } @@ -494,10 +499,14 @@ static void lower_perm_node(ir_node *irn, void *walk_env) { free(cycle); } - - /* remove the perm from schedule */ - sched_remove(irn); + if (! keep_perm) { + int arity = get_irn_arity(irn); + for(i = 0; i < arity; ++i) { + set_irn_n(irn, i, new_Bad()); + } + sched_remove(irn); + } } @@ -519,20 +528,6 @@ static ir_node *belower_skip_proj(ir_node *irn) { return irn; } -static void fix_in(ir_node *irn, ir_node *old, ir_node *nw) { - int i, n; - - irn = belower_skip_proj(irn); - n = get_irn_arity(irn); - - for (i = 0; i < n; i++) { - if (get_irn_n(irn, i) == old) { - set_irn_n(irn, i, nw); - break; - } - } -} - static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, constraint_env_t *env) { be_irg_t *birg = env->birg; pset *op_set = env->op_set; @@ -580,14 +575,12 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, /* insert the other different and it's copies into the set */ key.op = other_different; key.copies = NULL; - key.copy_keeps = NULL; - entry = pset_find(op_set, &key, HASH_PTR(other_different)); + entry = pset_find(op_set, &key, nodeset_hash(other_different)); if (! entry) { - entry = obstack_alloc(&env->obst, sizeof(*entry)); - entry->copies = pset_new_ptr_default(); - entry->copy_keeps = pset_new_ptr_default(); - entry->op = other_different; + entry = obstack_alloc(&env->obst, sizeof(*entry)); + entry->copies = pset_new_ptr_default(); + entry->op = other_different; } /* insert copy */ @@ -595,9 +588,9 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, /* insert keep in case of CopyKeep */ if (be_is_CopyKeep(keep)) - pset_insert_ptr(entry->copy_keeps, keep); + pset_insert_ptr(entry->copies, keep); - pset_insert(op_set, entry, HASH_PTR(other_different)); + pset_insert(op_set, entry, nodeset_hash(other_different)); DBG((mod, LEVEL_1, "created %+F for %+F to assure should_be_different\n", keep, irn)); } @@ -671,9 +664,7 @@ void assure_constraints(be_irg_t *birg) { int n; ir_node *cp; - n = pset_count(entry->copies); - n += pset_count(entry->copy_keeps); - + n = pset_count(entry->copies); nodes = alloca((n + 1) * sizeof(nodes[0])); /* put the node in an array */ @@ -687,38 +678,31 @@ void assure_constraints(be_irg_t *birg) { DB((mod, LEVEL_1, ", %+F ", cp)); } - /* collect all CopyKeeps */ - foreach_pset(entry->copy_keeps, cp) { - nodes[n++] = cp; - DB((mod, LEVEL_1, ", %+F ", cp)); - } - DB((mod, LEVEL_1, "\n")); /* introduce the copies for the operand and it's copies */ - be_ssa_constr(dom, n, nodes); + be_ssa_constr(dom, NULL, n, nodes); /* Could be that not all CopyKeeps are really needed, */ /* so we transform unnecessary ones into Keeps. */ - foreach_pset(entry->copy_keeps, cp) { - if (get_irn_n_edges(cp) < 1) { + foreach_pset(entry->copies, cp) { + if (be_is_CopyKeep(cp) && get_irn_n_edges(cp) < 1) { ir_node *keep; int n = get_irn_arity(cp); keep = be_new_Keep(arch_get_irn_reg_class(birg->main_env->arch_env, cp, -1), birg->irg, get_nodes_block(cp), n, (ir_node **)&get_irn_in(cp)[1]); sched_add_before(cp, keep); - sched_remove(cp); /* Set all ins (including the block) of the CopyKeep BAD to keep the verifier happy. */ while (--n >= -1) - set_irn_n(cp, n, get_irg_bad(birg->irg)); + set_irn_n(cp, n, new_Bad()); + sched_remove(cp); } } del_pset(entry->copies); - del_pset(entry->copy_keeps); } be_free_dominance_frontiers(dom);