X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbechordal.c;h=d58e6d3131cec0251ce2003cdc023c1d66d77249;hb=d07cec1341e61a5321ec44d93455bbbac312be75;hp=1fa973b35fe5bf273f0ddaa6e803d0dccadf9643;hpb=96abe08d09881b7876b07ea66620407974b5e2fa;p=libfirm diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index 1fa973b35..d58e6d313 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -415,6 +415,12 @@ static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t if (smallest >= 0) { be_operand_t *partner = &insn->ops[smallest]; + + for(i = insn->use_start; i < insn->n_ops; ++i) { + if(insn->ops[i].carrier == partner->carrier) + insn->ops[i].partner = out_op; + } + out_op->partner = partner; partner->partner = out_op; } @@ -491,7 +497,8 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, return perm; } -static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *irn, int *silent) +static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, + ir_node *irn, int *silent) { const arch_env_t *aenv; int n_regs; @@ -501,7 +508,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i int *assignment; pmap *partners; int i, n_alloc; - long col; + bitset_pos_t col; const ir_edge_t *edge; ir_node *perm = NULL; int match_res, cost; @@ -571,16 +578,31 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i set of admissible registers via a bipartite graph. */ if(!op->partner || !pmap_contains(partners, op->partner->carrier)) { + ir_node *partner = op->partner ? op->partner->carrier : NULL; + pmap_insert(partners, op->carrier, partner); + if(partner != NULL) + pmap_insert(partners, partner, op->carrier); + + /* don't insert a node twice */ + int i; + for(i = 0; i < n_alloc; ++i) { + if(alloc_nodes[i] == op->carrier) { + break; + } + } + if(i < n_alloc) + continue; - pmap_insert(partners, op->carrier, op->partner ? op->partner->carrier : NULL); alloc_nodes[n_alloc] = op->carrier; - DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, op->partner ? op->partner->carrier : NULL)); + DBG((dbg, LEVEL_2, "\tassociating %+F and %+F\n", op->carrier, + partner)); bitset_clear_all(bs); get_decisive_partner_regs(bs, op, op->partner); - DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, bs)); + DBG((dbg, LEVEL_2, "\tallowed registers for %+F: %B\n", op->carrier, + bs)); bitset_foreach(bs, col) { hungarian_add(bp, n_alloc, col, 1); @@ -597,6 +619,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i */ if(perm != NULL) { foreach_out_edge(perm, edge) { + int i; ir_node *proj = get_edge_src_irn(edge); assert(is_Proj(proj)); @@ -604,7 +627,18 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i if(!values_interfere(birg, proj, irn) || pmap_contains(partners, proj)) continue; + /* don't insert a node twice */ + for(i = 0; i < n_alloc; ++i) { + if(alloc_nodes[i] == proj) { + break; + } + } + if(i < n_alloc) + continue; + + assert(n_alloc < n_regs); + alloc_nodes[n_alloc] = proj; pmap_insert(partners, proj, NULL); @@ -642,6 +676,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i if(!nodes[j]) continue; + assert(! (reg->type & arch_register_type_ignore)); arch_set_irn_register(aenv, nodes[j], reg); (void) pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]); DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name)); @@ -740,11 +775,10 @@ static void pressure(ir_node *block, void *env_ptr) be_lv_t *lv = env->birg->lv; int i, n; + bitset_pos_t elm; unsigned step = 0; unsigned pressure = 0; struct list_head *head; - pset *live_in = be_lv_pset_put_in(lv, block, pset_new_ptr_default()); - pset *live_end = be_lv_pset_put_end(lv, block, pset_new_ptr_default()); DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block)); bitset_clear_all(live); @@ -759,7 +793,8 @@ static void pressure(ir_node *block, void *env_ptr) * Make final uses of all values live out of the block. * They are necessary to build up real intervals. */ - foreach_pset(live_end, irn) { + be_lv_foreach(lv, block, be_lv_state_end, i) { + ir_node *irn = be_lv_get_irn(lv, block, i); if(has_reg_class(env, irn)) { DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_idx(irn))); bitset_set(live, get_irn_idx(irn)); @@ -776,6 +811,26 @@ static void pressure(ir_node *block, void *env_ptr) DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure)); DBG((dbg, LEVEL_2, "\tlive: %B\n", live)); +#ifndef SCHEDULE_PROJS + if (get_irn_mode(irn) == mode_T) { + const ir_edge_t *edge; + + foreach_out_edge(irn, edge) { + ir_node *proj = get_edge_src_irn(edge); + + /* + * If the node defines some value, which can put into a + * register of the current class, make a border for it. + */ + if(has_reg_class(env, proj)) { + int nr = get_irn_idx(proj); + + bitset_clear(live, nr); + border_def(proj, step, 1); + } + } + } +#endif /* * If the node defines some value, which can put into a * register of the current class, make a border for it. @@ -811,22 +866,11 @@ static void pressure(ir_node *block, void *env_ptr) ++step; } - /* - * Add initial defs for all values live in. - */ - foreach_pset(live_in, irn) { - if(has_reg_class(env, irn)) { - - /* Mark the value live in. */ - bitset_set(live, get_irn_idx(irn)); - - /* Add the def */ + bitset_foreach(live, elm) { + ir_node *irn = get_idx_irn(env->irg, elm); + if (be_is_live_in(lv, block, irn)) border_def(irn, step, 0); - } } - - del_pset(live_in); - del_pset(live_end); } static void assign(ir_node *block, void *env_ptr) @@ -950,7 +994,6 @@ static void assign_new(ir_node *block, be_chordal_alloc_env_t *alloc_env, bitset bitset_t *live = bitset_irg_malloc(env->irg); const arch_env_t *arch_env = env->birg->main_env->arch_env; be_irg_t *birg = env->birg; - lv_chk_t *lv = be_get_birg_liveness_chk(birg); bitset_pos_t elm; ir_node *irn; @@ -968,7 +1011,7 @@ static void assign_new(ir_node *block, be_chordal_alloc_env_t *alloc_env, bitset */ bitset_foreach (live_end_dom, elm) { ir_node *irn = get_idx_irn(env->irg, elm); - if (lv_chk_bl_in(lv, block, irn)) { + if (be_is_live_in(birg->lv, block, irn)) { const arch_register_t *reg = arch_get_irn_register(arch_env, irn); int col; @@ -1066,6 +1109,7 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env) { be_chordal_alloc_env_t env; char buf[256]; + be_lv_t *lv; be_irg_t *birg = chordal_env->birg; const arch_register_class_t *cls = chordal_env->cls; @@ -1078,7 +1122,10 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env) return; be_assure_dom_front(birg); - be_assure_liveness(birg); + lv = be_assure_liveness(birg); + be_liveness_assure_sets(lv); + be_liveness_assure_chk(lv); + assure_doms(irg); env.chordal_env = chordal_env;