X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbelower.c;h=ea016785dd8bb14a5a8f6182815b6ed2fa7e61a5;hb=89dc24503c04139bb05504059b291d6d89f99661;hp=edea7aef42030d4697d46ae607616d11ea35775f;hpb=a35bce53baad90c17ca9887acfb83e29af4e4a6a;p=libfirm diff --git a/ir/be/belower.c b/ir/be/belower.c index edea7aef4..ea016785d 100644 --- a/ir/be/belower.c +++ b/ir/be/belower.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. * @@ -45,7 +45,6 @@ #include "besched_t.h" #include "bestat.h" #include "bessaconstr.h" -#include "benodesets.h" #include "beintlive_t.h" #undef KEEP_ALIVE_COPYKEEP_HACK @@ -178,14 +177,14 @@ static int get_pairidx_for_regidx(reg_pair_t *pairs, int n, int reg_idx, int in_ if (in_out) { for (i = 0; i < n; i++) { /* out register matches */ - if (pairs[i].out_reg->index == reg_idx) + if ((int) pairs[i].out_reg->index == reg_idx) return i; } } else { for (i = 0; i < n; i++) { /* in register matches */ - if (pairs[i].in_reg->index == reg_idx) + if ((int) pairs[i].in_reg->index == reg_idx) return i; } } @@ -599,8 +598,8 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, sched_add_after(irn, keep); /* insert the other different and it's copies into the set */ - key.op = other_different; - entry = pset_find(op_set, &key, nodeset_hash(other_different)); + key.op = other_different; + entry = pset_find(op_set, &key, hash_irn(other_different)); if (! entry) { entry = obstack_alloc(&env->obst, sizeof(*entry)); @@ -617,7 +616,7 @@ static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, ir_nodeset_insert(&entry->copies, keep); } - pset_insert(op_set, entry, nodeset_hash(other_different)); + pset_insert(op_set, entry, hash_irn(other_different)); } /** @@ -631,12 +630,14 @@ static void assure_different_constraints(ir_node *irn, constraint_env_t *env) { req = arch_get_register_req(arch_env, irn, -1); if (arch_register_req_is(req, should_be_different)) { - ir_node *different_from = get_irn_n(belower_skip_proj(irn), req->other_different); - gen_assure_different_pattern(irn, different_from, env); - } else if (arch_register_req_is(req, should_be_different_from_all)) { - int i, n = get_irn_arity(belower_skip_proj(irn)); - for (i = 0; i < n; i++) { - gen_assure_different_pattern(irn, get_irn_n(belower_skip_proj(irn), i), env); + const unsigned other = req->other_different; + int i; + + for (i = 0; 1U << i <= other; ++i) { + if (other & (1U << i)) { + ir_node *different_from = get_irn_n(belower_skip_proj(irn), i); + gen_assure_different_pattern(irn, different_from, env); + } } } } @@ -754,21 +755,18 @@ static void melt_copykeeps(constraint_env_t *cenv) { new_ck = be_new_CopyKeep(entry->cls, irg, get_nodes_block(ref), be_get_CopyKeep_op(ref), n_melt, new_ck_in, get_irn_mode(ref)); #endif /* KEEP_ALIVE_COPYKEEP_HACK */ - /* set register class for all keeped inputs */ + /* set register class for all kept inputs */ for (j = 1; j <= n_melt; ++j) be_node_set_reg_class(new_ck, j, entry->cls); ir_nodeset_insert(&entry->copies, new_ck); /* find scheduling point */ - if (get_irn_mode(ref_mode_T) == mode_T) { - /* walk along the Projs */ - for (sched_pt = sched_next(ref_mode_T); is_Proj(sched_pt) || be_is_Keep(sched_pt) || be_is_CopyKeep(sched_pt); sched_pt = sched_next(sched_pt)) - /* just walk along the schedule until a non-Proj/Keep/CopyKeep node is found*/ ; - } - else { - sched_pt = ref_mode_T; - } + sched_pt = ref_mode_T; + do { + /* just walk along the schedule until a non-Keep/CopyKeep node is found */ + sched_pt = sched_next(sched_pt); + } while (be_is_Keep(sched_pt) || be_is_CopyKeep(sched_pt)); sched_add_before(sched_pt, new_ck); DBG((cenv->dbg, LEVEL_1, "created %+F, scheduled before %+F\n", new_ck, sched_pt)); @@ -882,6 +880,7 @@ static int push_through_perm(ir_node *perm, void *data) ir_graph *irg = get_irn_irg(perm); ir_node *bl = get_nodes_block(perm); + ir_node *node; int arity = get_irn_arity(perm); int *map; int *proj_map; @@ -893,8 +892,8 @@ static int push_through_perm(ir_node *perm, void *data) int i, n; const ir_edge_t *edge; - ir_node *last_proj, *irn; - const arch_register_class_t *cls; + ir_node *last_proj = NULL, *irn; + const arch_register_class_t *cls = NULL; DBG((mod, LEVEL_1, "perm move %+F irg %+F\n", perm, irg)); @@ -925,11 +924,12 @@ found_front: DBG((mod, LEVEL_2, "\tfrontier: %+F\n", frontier)); - ir_node *node = sched_prev(perm); + node = sched_prev(perm); n_moved = 0; while(!sched_is_begin(node)) { - int input = -1; - ir_node *proj; + const arch_register_req_t *req; + int input = -1; + ir_node *proj; foreach_out_edge(perm, edge) { ir_node *out = get_edge_src_irn(edge); @@ -948,6 +948,14 @@ found_front: break; if(arch_irn_is(aenv, node, modify_flags)) break; + if(is_Proj(node)) { + req = arch_get_register_req(aenv, get_Proj_pred(node), + -1 - get_Proj_proj(node)); + } else { + req = arch_get_register_req(aenv, node, -1); + } + if(req->type != arch_register_req_type_normal) + break; for(i = get_irn_arity(node) - 1; i >= 0; --i) { ir_node *opop = get_irn_n(node, i); if (arch_irn_consider_in_reg_alloc(aenv, cls, opop)) {