} col_cost_pair_t;
typedef struct {
- ir_nodemap map;
- struct obstack obst;
- copy_opt_t *co;
- bitset_t *allocatable_regs;
- co2_irn_t *touched;
- int visited;
- int n_regs;
+ ir_nodemap map;
+ struct obstack obst;
+ copy_opt_t *co;
+ unsigned const *allocatable_regs;
+ co2_irn_t *touched;
+ int visited;
+ int n_regs;
struct list_head cloud_head;
DEBUG_ONLY(firm_dbg_module_t *dbg;)
} co2_t;
co2_irn_t *touched_next;
col_t tmp_col;
col_t orig_col;
- bitset_t *adm_cache;
+ unsigned const *admissible;
unsigned fixed : 1;
unsigned tmp_fixed : 1;
struct list_head changed_list;
ci->irn = node;
ci->aff = NULL;
+ arch_register_req_t const *const req = arch_get_irn_register_req(node);
+ ci->admissible = arch_register_req_is(req, limited) ? req->limited : env->allocatable_regs;
+
ir_nodemap_insert(&env->map, node, ci);
}
return ci;
return ci->fixed || ci->tmp_fixed;
}
-static inline bitset_t *get_adm(co2_t *env, co2_irn_t *ci)
-{
- if (ci->adm_cache == NULL) {
- const arch_register_req_t *req;
- ci->adm_cache = bitset_obstack_alloc(&env->obst, env->n_regs);
- req = arch_get_irn_register_req(ci->irn);
-
- if (arch_register_req_is(req, limited)) {
- int i, n;
-
- n = env->n_regs;
- for (i = 0; i < n; ++i) {
- if (rbitset_is_set(req->limited, i))
- bitset_set(ci->adm_cache, i);
- }
- } else {
- bitset_copy(ci->adm_cache, env->allocatable_regs);
- }
- }
-
- return ci->adm_cache;
-}
-
-static inline bitset_t *admissible_colors(co2_t *env, co2_irn_t *ci, bitset_t *bs)
-{
- bitset_copy(bs, get_adm(env, ci));
- return bs;
-}
-
-static inline int is_color_admissible(co2_t *env, co2_irn_t *ci, col_t col)
+static inline int is_color_admissible(co2_irn_t *const ci, col_t const col)
{
- bitset_t *bs = get_adm(env, ci);
- return bitset_is_set(bs, col);
+ unsigned const *const bs = ci->admissible;
+ return rbitset_is_set(bs, col);
}
-static void incur_constraint_costs(co2_t *env, const ir_node *irn, col_cost_pair_t *col_costs, int costs)
+static void incur_constraint_costs(ir_node const *const irn, col_cost_pair_t *const col_costs, int const costs)
{
const arch_register_req_t *req = arch_get_irn_register_req(irn);
if (arch_register_req_is(req, limited)) {
- unsigned n_regs = env->co->cls->n_regs;
- unsigned n_constr = 0;
- unsigned i;
-
- n_constr = rbitset_popcount(req->limited, n_regs);
- for (i = 0; i < n_regs; ++i) {
+ unsigned const n_regs = req->cls->n_regs;
+ unsigned const n_constr = rbitset_popcount(req->limited, n_regs);
+ for (unsigned i = 0; i < n_regs; ++i) {
if (rbitset_is_set(req->limited, i)) {
col_costs[i].costs = add_saturated(col_costs[i].costs, costs / n_constr);
}
neighbours_iter_t it;
int i;
- /* Put all forbidden colors into the aux bitset. */
- bitset_t *const admissible = bitset_alloca(n_regs);
- admissible_colors(env, ci, admissible);
-
for (i = 0; i < n_regs; ++i) {
col_costs[i].col = i;
col_costs[i].costs = 0;
col_costs[col].costs = add_saturated(col_costs[col].costs, -n->costs * 128);
}
- incur_constraint_costs(env, n->irn, col_costs, -n->costs);
+ incur_constraint_costs(n->irn, col_costs, -n->costs);
}
}
col_costs[col].costs = INT_MAX;
}
else {
- incur_constraint_costs(env, pos, col_costs, INT_MAX);
+ incur_constraint_costs(pos, col_costs, INT_MAX);
col_costs[col].costs = add_saturated(col_costs[col].costs, 8 * be_ifg_degree(ifg, pos));
}
}
- be_ifg_neighbours_break(&it);
/* Set the costs to infinity for each color which is not allowed at this node. */
- bitset_foreach_clear(admissible, elm) {
+ unsigned const *const admissible = ci->admissible;
+ rbitset_foreach_clear(admissible, n_regs, elm) {
col_costs[elm].costs = INT_MAX;
}
-
}
static void single_color_cost(co2_t *env, co2_irn_t *ci, col_t col, col_cost_pair_t *seq)
}
(void) ci;
- assert(is_color_admissible(env, ci, col));
+ assert(is_color_admissible(ci, col));
seq[col].col = 0;
seq[0].col = col;
seq[0].costs = 0;
INIT_LIST_HEAD(&tmp);
neigh_ok = change_color_not(env, n, tgt_col, &tmp, depth + 1);
list_splice(&tmp, &changed);
- if (!neigh_ok)
+ if (!neigh_ok) {
+ be_ifg_neighbours_break(&it);
break;
+ }
}
}
- be_ifg_neighbours_break(&it);
/*
We managed to assign the target color to all neighbors, so from the perspective
goto end;
}
- if (!color_is_fix(env, irn) && is_color_admissible(env, ci, tgt_col)) {
+ if (!color_is_fix(env, irn) && is_color_admissible(ci, tgt_col)) {
int n_regs = env->co->cls->n_regs;
col_cost_pair_t *seq = ALLOCAN(col_cost_pair_t, n_regs);
*/
static void node_color_badness(co2_cloud_irn_t *ci, int *badness)
{
- co2_t *env = ci->cloud->env;
- co2_irn_t *ir = &ci->inh;
- int n_regs = env->n_regs;
- be_ifg_t *ifg = env->co->cenv->ifg;
- bitset_t *bs = bitset_alloca(n_regs);
+ co2_t *const env = ci->cloud->env;
+ size_t const n_regs = env->n_regs;
neighbours_iter_t it;
- admissible_colors(env, &ci->inh, bs);
- bitset_foreach_clear(bs, elm)
- badness[elm] = ci->costs;
+ {
+ unsigned const *const bs = ci->inh.admissible;
+ rbitset_foreach_clear(bs, n_regs, elm)
+ badness[elm] = ci->costs;
+ }
/* Use constrained/fixed interfering neighbors to influence the color badness */
- be_ifg_foreach_neighbour(ifg, &it, ir->irn, irn) {
+ be_ifg_foreach_neighbour(env->co->cenv->ifg, &it, ci->inh.irn, irn) {
co2_irn_t *ni = get_co2_irn(env, irn);
- admissible_colors(env, ni, bs);
- if (bitset_popcount(bs) == 1) {
- size_t c = bitset_next_set(bs, 0);
+ unsigned const *const bs = ni->admissible;
+ if (rbitset_popcount(bs, n_regs) == 1) {
+ size_t const c = rbitset_next_max(bs, 0, n_regs, true);
badness[c] += ci->costs;
- }
-
- else if (ni->fixed) {
+ } else if (ni->fixed) {
col_t c = get_col(env, ni->irn);
badness[c] += ci->costs;
}
}
- be_ifg_neighbours_break(&it);
}
/**
int badness = ci->color_badness[i];
seq[i].col = i;
- seq[i].costs = is_color_admissible(env, &ci->inh, i) ? badness : INT_MAX;
+ seq[i].costs = is_color_admissible(&ci->inh, i) ? badness : INT_MAX;
min_badness = MIN(min_badness, badness);
}
/* If we are not the root and the parent's color is allowed for this node give it top prio. */
- if (!is_root && is_color_admissible(env, &ci->inh, parent_col))
+ if (!is_root && is_color_admissible(&ci->inh, parent_col))
seq[parent_col].costs = min_badness - 1;
/* Sort the colors. The will be processed in that ordering. */
/* add the node's cost to the total costs of the cloud. */
ci->costs = costs;
cloud->costs += costs;
- cloud->freedom += bitset_popcount(get_adm(env, &ci->inh));
+ cloud->freedom += rbitset_popcount(ci->inh.admissible, env->n_regs);
cloud->n_memb += 1;
/* If this is the heaviest node in the cloud, set it as the cloud's master. */
ir_nodemap_init(&env.map, co->irg);
obstack_init(&env.obst);
- env.touched = NULL;
- env.visited = 0;
- env.co = co;
- env.n_regs = co->cls->n_regs;
- env.allocatable_regs = bitset_alloca(co->cls->n_regs);
- be_put_allocatable_regs(co->irg, co->cls, env.allocatable_regs);
+ env.touched = NULL;
+ env.visited = 0;
+ env.co = co;
+ env.n_regs = co->cls->n_regs;
+ env.allocatable_regs = co->cenv->allocatable_regs->data;
FIRM_DBG_REGISTER(env.dbg, "firm.be.co2");
INIT_LIST_HEAD(&env.cloud_head);