becopyilp: Do not advertise the switch to dump the solution, because this is not...
[libfirm] / ir / be / becopyheur2.c
index 517ec8d..c0dccb8 100644 (file)
@@ -94,13 +94,13 @@ typedef struct {
 } 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;
@@ -111,7 +111,7 @@ struct co2_irn_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;
@@ -172,6 +172,9 @@ static co2_irn_t *get_co2_irn(co2_t *env, const ir_node *node)
                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;
@@ -241,52 +244,20 @@ static inline int color_is_fix(co2_t *env, const ir_node *irn)
        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);
                        }
@@ -314,10 +285,6 @@ static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *co
        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;
@@ -330,7 +297,7 @@ static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *co
                                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);
                }
        }
 
@@ -340,17 +307,16 @@ static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *co
                        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)
@@ -364,7 +330,7 @@ static void single_color_cost(co2_t *env, co2_irn_t *ci, col_t col, col_cost_pai
        }
 
        (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;
@@ -441,11 +407,12 @@ static int recolor(co2_t *env, const ir_node *irn, col_cost_pair_t *col_list, st
                                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
@@ -530,7 +497,7 @@ static int change_color_single(co2_t *env, const ir_node *irn, col_t tgt_col, st
                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);
 
@@ -581,34 +548,30 @@ static int examine_subtree_coloring(co2_cloud_irn_t *ci, col_t col)
  */
 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);
 }
 
 /**
@@ -669,13 +632,13 @@ static int coalesce_top_down(co2_cloud_irn_t *ci, int child_nr, int depth)
                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. */
@@ -763,7 +726,7 @@ static void populate_cloud(co2_t *env, co2_cloud_t *cloud, affinity_node_t *a, i
        /* 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. */
@@ -1036,12 +999,11 @@ static int co_solve_heuristic_new(copy_opt_t *co)
 
        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);