X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbecopyopt.c;h=818bbf0910a055261becd5b6dda2c0af600c37c4;hb=65f6cc39305e6880fe45709a8a2e1c24445395e3;hp=70ebdfcac8f106ca64ab38da74a92be2fb83e804;hpb=31636543e37dbecfb9b33664a1eb981d01f71ab8;p=libfirm diff --git a/ir/be/becopyopt.c b/ir/be/becopyopt.c index 70ebdfcac..818bbf091 100644 --- a/ir/be/becopyopt.c +++ b/ir/be/becopyopt.c @@ -445,10 +445,8 @@ static void co_collect_units(ir_node *irn, void *env) { } unit->nodes = xrealloc(unit->nodes, unit->node_count * sizeof(*unit->nodes)); unit->costs = xrealloc(unit->costs, unit->node_count * sizeof(*unit->costs)); - } else - - /* Proj of a perm with corresponding arg */ - if (is_Perm_Proj(co->aenv, irn)) { + } else if (is_Perm_Proj(co->aenv, irn)) { + /* Proj of a perm with corresponding arg */ assert(!nodes_interfere(co->cenv, irn, get_Perm_src(irn))); unit->nodes = xmalloc(2 * sizeof(*unit->nodes)); unit->costs = xmalloc(2 * sizeof(*unit->costs)); @@ -462,15 +460,44 @@ static void co_collect_units(ir_node *irn, void *env) { /* Src == Tgt of a 2-addr-code instruction */ if (is_2addr_code(req)) { - ir_node *other = get_irn_n(skip_Proj(irn), req->other_same); - if (!arch_irn_is(co->aenv, other, ignore) && - !nodes_interfere(co->cenv, irn, other)) { - unit->nodes = xmalloc(2 * sizeof(*unit->nodes)); - unit->costs = xmalloc(2 * sizeof(*unit->costs)); - unit->node_count = 2; - unit->nodes[0] = irn; - unit->nodes[1] = other; - unit->costs[1] = co->get_costs(co, irn, other, -1); + ir_node *other = get_irn_n(skip_Proj(irn), req->other_same[0]); + ir_node *other2 = NULL; + int count; + + if (arch_irn_is(co->aenv, other, ignore) || + nodes_interfere(co->cenv, irn, other)) { + other = NULL; + } + if (req->other_same[1] != -1) { + other2 = get_irn_n(skip_Proj(irn), req->other_same[1]); + if (arch_irn_is(co->aenv, other2, ignore) || + nodes_interfere(co->cenv, irn, other2)) { + other2 = NULL; + } + } + count = 1 + (other != NULL) + (other2 != NULL && other != other2); + + if (count > 1) { + int i = 0; + + unit->nodes = xmalloc(count * sizeof(*unit->nodes)); + unit->costs = xmalloc(count * sizeof(*unit->costs)); + unit->node_count = count; + unit->nodes[i] = irn; + if (other != NULL) { + ++i; + unit->nodes[i] = other; + unit->costs[i] = co->get_costs(co, irn, other, -1); + } + if (other2 != NULL) { + if (other == other2) { + unit->costs[i] += co->get_costs(co, irn, other2, -1); + } else { + ++i; + unit->nodes[i] = other2; + unit->costs[i] = co->get_costs(co, irn, other2, -1); + } + } } } else { assert(0 && "This is not an optimizable node!"); @@ -765,27 +792,29 @@ static void build_graph_walker(ir_node *irn, void *env) { if (arch_register_type_is(reg, ignore)) return; - /* Phis */ - if (is_Reg_Phi(irn)) + if (is_Reg_Phi(irn)) { /* Phis */ for (pos=0, max=get_irn_arity(irn); posget_costs(co, irn, arg, pos)); } - - /* Perms */ - else if (is_Perm_Proj(co->aenv, irn)) { + } + else if (is_Perm_Proj(co->aenv, irn)) { /* Perms */ ir_node *arg = get_Perm_src(irn); add_edges(co, irn, arg, co->get_costs(co, irn, arg, 0)); } - - /* 2-address code */ - else { - const arch_register_req_t *req = - arch_get_register_req(co->aenv, irn, -1); + else { /* 2-address code */ + const arch_register_req_t *req = arch_get_register_req(co->aenv, irn, -1); if (is_2addr_code(req)) { - ir_node *other = get_irn_n(skip_Proj(irn), req->other_same); - if (! arch_irn_is(co->aenv, other, ignore)) - add_edges(co, irn, other, co->get_costs(co, irn, other, 0)); + const int *i; + for (i = req->other_same; i != ENDOF(req->other_same); ++i) { + ir_node *other; + + if (*i == -1) break; + + other = get_irn_n(skip_Proj(irn), *i); + if (! arch_irn_is(co->aenv, other, ignore)) + add_edges(co, irn, other, co->get_costs(co, irn, other, 0)); + } } } }