X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbecopyheur.c;h=be203051dcd66c03e0704aa840bc513f53e25a09;hb=7039e499eb395a6c98b66c38353025490604a256;hp=dbb638ca2fdae99c2f6a845a7674b5e9883d430d;hpb=e207fc73a24963b86a235d59cd18fac481f8d1d3;p=libfirm diff --git a/ir/be/becopyheur.c b/ir/be/becopyheur.c index dbb638ca2..be203051d 100644 --- a/ir/be/becopyheur.c +++ b/ir/be/becopyheur.c @@ -57,8 +57,8 @@ typedef struct conflict_t { */ typedef struct node_stat_t { ir_node *irn; - int new_color; - int pinned_local :1; + int new_color; + unsigned pinned_local :1; } node_stat_t; /** @@ -66,7 +66,6 @@ typedef struct node_stat_t { */ typedef struct qnode_t { struct list_head queue; /**< chaining of unit_t->queue */ - const unit_t *ou; /**< the opt unit this node belongs to */ int color; /**< target color */ set *conflicts; /**< contains conflict_t's. All internal conflicts */ int mis_costs; /**< costs of nodes/copies in the mis. */ @@ -113,7 +112,7 @@ static inline int qnode_are_conflicting(const qnode_t *qn, const ir_node *n1, co conflict_t c; /* search for live range interference */ if (n1 != n2) { - be_lv_t *const lv = be_get_irg_liveness(qn->ou->co->irg); + be_lv_t *const lv = be_get_irg_liveness(get_irn_irg(n1)); if (be_values_interfere(lv, n1, n2)) return 1; } @@ -230,15 +229,10 @@ static inline void qnode_pin_local(const qnode_t *qn, ir_node *irn) * Else the first conflicting ir_node encountered is returned. * */ -static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const ir_node *trigger) +static ir_node *qnode_color_irn(qnode_t const *const qn, ir_node *const irn, int const col, ir_node const *const trigger, bitset_t const *const allocatable_regs, be_ifg_t *const ifg) { - copy_opt_t *co = qn->ou->co; - const be_chordal_env_t *chordal_env = co->cenv; - const arch_register_class_t *cls = co->cls; int irn_col = qnode_get_new_color(qn, irn); - be_ifg_t *ifg = chordal_env->ifg; neighbours_iter_t iter; - const arch_register_req_t *req; DBG((dbg, LEVEL_3, "\t %+F \tcaused col(%+F) \t%2d --> %2d\n", trigger, irn, irn_col, col)); @@ -254,7 +248,8 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const return irn; } - req = arch_get_irn_register_req(irn); + arch_register_req_t const *const req = arch_get_irn_register_req(irn); + arch_register_class_t const *const cls = req->cls; #ifdef SEARCH_FREE_COLORS /* If we resolve conflicts (recursive calls) we can use any unused color. * In case of the first call @p col must be used. @@ -264,14 +259,11 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const int free_col; /* Get all possible colors */ - bitset_copy(free_cols, co->cenv->allocatable_regs); + bitset_copy(free_cols, allocatable_regs); /* Exclude colors not assignable to the irn */ - if (arch_register_req_is(req, limited)) { - bitset_t *limited = bitset_alloca(cls->n_regs); - rbitset_copy_to_bitset(req->limited, limited); - bitset_and(free_cols, limited); - } + if (arch_register_req_is(req, limited)) + rbitset_and(free_cols->data, req->limited, free_cols->size); /* Exclude the color of the irn, because it must _change_ its color */ bitset_clear(free_cols, irn_col); @@ -302,7 +294,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const be_ifg_foreach_neighbour(ifg, &iter, irn, curr) { DBG((dbg, LEVEL_3, "\t Confl %+F(%d)\n", curr, qnode_get_new_color(qn, curr))); if (qnode_get_new_color(qn, curr) == col && curr != trigger) { - ir_node *const sub_res = qnode_color_irn(qn, curr, irn_col, irn); + ir_node *const sub_res = qnode_color_irn(qn, curr, irn_col, irn, allocatable_regs, ifg); if (sub_res != CHANGE_SAVE) { be_ifg_neighbours_break(&iter); return sub_res; @@ -325,7 +317,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const * @returns 1 iff all members colors could be set * 0 else */ -static int qnode_try_color(const qnode_t *qn) +static int qnode_try_color(qnode_t const *const qn, bitset_t const *const allocatable_regs, be_ifg_t *const ifg) { int i; for (i=0; imis_size; ++i) { @@ -333,7 +325,7 @@ static int qnode_try_color(const qnode_t *qn) test_node = qn->mis[i]; DBG((dbg, LEVEL_3, "\t Testing %+F\n", test_node)); - confl_node = qnode_color_irn(qn, test_node, qn->color, test_node); + confl_node = qnode_color_irn(qn, test_node, qn->color, test_node, allocatable_regs, ifg); if (confl_node == CHANGE_SAVE) { DBG((dbg, LEVEL_3, "\t Save --> pin local\n")); @@ -345,7 +337,7 @@ static int qnode_try_color(const qnode_t *qn) } else { if (qnode_is_pinned_local(qn, confl_node)) { /* changing test_node would change back a node of current ou */ - if (confl_node == qn->ou->nodes[0]) { + if (confl_node == qn->mis[0]) { /* Adding a conflict edge between testnode and conflnode * would introduce a root -- arg interference. * So remove the arg of the qn */ @@ -471,7 +463,6 @@ no_stable_set: static inline qnode_t *new_qnode(const unit_t *ou, int color) { qnode_t *qn = XMALLOC(qnode_t); - qn->ou = ou; qn->color = color; qn->mis = XMALLOCN(ir_node*, ou->node_count); qn->conflicts = new_set(set_cmp_conflict_t, SLOTS_CONFLICTS); @@ -524,29 +515,21 @@ static inline void ou_insert_qnode(unit_t *ou, qnode_t *qn) * case for approximately 80% of all phi classes and 100% of register constrained * nodes. (All other phi classes are reduced to this case.) */ -static void ou_optimize(unit_t *ou) +static void ou_optimize(unit_t *ou, bitset_t const *const allocatable_regs, be_ifg_t *const ifg) { - qnode_t *curr = NULL; - const arch_register_req_t *req; - bitset_t const* allocatable_regs; - unsigned n_regs; - unsigned idx; - int i; - DBG((dbg, LEVEL_1, "\tOptimizing unit:\n")); - for (i=0; inode_count; ++i) + for (int i = 0; i < ou->node_count; ++i) DBG((dbg, LEVEL_1, "\t %+F\n", ou->nodes[i])); /* init queue */ INIT_LIST_HEAD(&ou->queue); - req = arch_get_irn_register_req(ou->nodes[0]); - allocatable_regs = ou->co->cenv->allocatable_regs; - n_regs = req->cls->n_regs; + arch_register_req_t const *const req = arch_get_irn_register_req(ou->nodes[0]); + unsigned const n_regs = req->cls->n_regs; if (arch_register_req_is(req, limited)) { unsigned const* limited = req->limited; - for (idx = 0; idx != n_regs; ++idx) { + for (unsigned idx = 0; idx != n_regs; ++idx) { if (!bitset_is_set(allocatable_regs, idx)) continue; if (!rbitset_is_set(limited, idx)) @@ -555,7 +538,7 @@ static void ou_optimize(unit_t *ou) ou_insert_qnode(ou, new_qnode(ou, idx)); } } else { - for (idx = 0; idx != n_regs; ++idx) { + for (unsigned idx = 0; idx != n_regs; ++idx) { if (!bitset_is_set(allocatable_regs, idx)) continue; @@ -564,6 +547,7 @@ static void ou_optimize(unit_t *ou) } /* search best */ + qnode_t *curr; for (;;) { assert(!list_empty(&ou->queue)); /* get head of queue */ @@ -572,7 +556,7 @@ static void ou_optimize(unit_t *ou) DBG((dbg, LEVEL_2, "\t Examine qnode color %d with cost %d\n", curr->color, curr->mis_costs)); /* try */ - if (qnode_try_color(curr)) + if (qnode_try_color(curr, allocatable_regs, ifg)) break; /* no success, so re-insert */ @@ -587,7 +571,7 @@ static void ou_optimize(unit_t *ou) DBG((dbg, LEVEL_1, "\t Best color: %d Costs: %d << %d << %d\n", curr->color, ou->min_nodes_costs, ou->all_nodes_costs - curr->mis_costs, ou->all_nodes_costs)); /* globally pin root and all args which have the same color */ pset_insert_ptr(pinned_global, ou->nodes[0]); - for (i=1; inode_count; ++i) { + for (int i = 1; i < ou->node_count; ++i) { ir_node *irn = ou->nodes[i]; int nc = qnode_get_new_color(curr, irn); if (nc != NO_COLOR && nc == root_col) @@ -599,7 +583,7 @@ static void ou_optimize(unit_t *ou) /* NO_COLOR is possible, if we had an undo */ if (ns->new_color != NO_COLOR) { DBG((dbg, LEVEL_1, "\t color(%+F) := %d\n", ns->irn, ns->new_color)); - set_irn_col(ou->co->cls, ns->irn, ns->new_color); + set_irn_col(req->cls, ns->irn, ns->new_color); } } } @@ -619,9 +603,12 @@ int co_solve_heuristic(copy_opt_t *co) ASSERT_OU_AVAIL(co); pinned_global = pset_new_ptr(SLOTS_PINNED_GLOBAL); - list_for_each_entry(unit_t, curr, &co->units, units) + bitset_t const *const allocatable_regs = co->cenv->allocatable_regs; + be_ifg_t *const ifg = co->cenv->ifg; + list_for_each_entry(unit_t, curr, &co->units, units) { if (curr->node_count > 1) - ou_optimize(curr); + ou_optimize(curr, allocatable_regs, ifg); + } del_pset(pinned_global); return 0;