From: Sebastian Hack Date: Mon, 22 Oct 2007 13:13:07 +0000 (+0000) Subject: Some heur4 tweaks X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=29439abe8fe6f9d4e7bb754cb3774e81929e9fec;p=libfirm Some heur4 tweaks ILP coalescing should work again changed include of config.h to firm_config.h since WITH_ILP is defined there [r16304] --- diff --git a/ir/be/becopyheur4.c b/ir/be/becopyheur4.c index 48786e45d..94af23e30 100644 --- a/ir/be/becopyheur4.c +++ b/ir/be/becopyheur4.c @@ -49,6 +49,8 @@ #include "error.h" #include "list.h" +#include "irbitset.h" + #include "bearch.h" #include "beifg.h" #include "be_t.h" @@ -624,6 +626,71 @@ static void build_affinity_chunks(co_mst_env_t *env) { DEL_ARR_F(edges); } +static void chunk_order_nodes(co_mst_env_t *env, aff_chunk_t *chunk) +{ + pqueue *grow = new_pqueue(); + int i; + int max_weight = 0; + ir_node *max_node = NULL; + + for (i = ARR_LEN(chunk->n) - 1; i >= 0; i--) { + ir_node *irn = chunk->n[i]; + affinity_node_t *an = get_affinity_info(env->co, irn); + int w = 0; + neighb_t *neigh; + + if (arch_irn_is(env->aenv, irn, ignore)) + continue; + + if (an) { + co_gs_foreach_neighb(an, neigh) + w += neigh->costs; + + if (w > max_weight) { + max_weight = w; + max_node = irn; + } + } + } + + if (max_node) { + bitset_t *visited = bitset_irg_malloc(env->co->irg); + + for (i = ARR_LEN(chunk->n) - 1; i >= 0; --i) + bitset_add_irn(visited, chunk->n[i]); + + pqueue_put(grow, max_node, max_weight); + bitset_remv_irn(visited, max_node); + i = 0; + while (!pqueue_empty(grow)) { + ir_node *irn = pqueue_get(grow); + affinity_node_t *an = get_affinity_info(env->co, irn); + neighb_t *neigh; + + if (arch_irn_is(env->aenv, irn, ignore)) + continue; + + assert(i <= ARR_LEN(chunk->n)); + chunk->n[i++] = irn; + + assert(an); + + /* build the affinity edges */ + co_gs_foreach_neighb(an, neigh) { + co_mst_irn_t *node = get_co_mst_irn(env, neigh->irn); + + if (bitset_contains_irn(visited, node->irn)) { + pqueue_put(grow, neigh->irn, neigh->costs); + bitset_remv_irn(visited, node->irn); + } + } + } + + del_pqueue(grow); + bitset_free(visited); + } +} + /** * Greedy collect affinity neighbours into thew new chunk @p chunk starting at node @p node. */ @@ -878,6 +945,27 @@ static void determine_color_costs(co_mst_env_t *env, co_mst_irn_t *node, col_cos costs[idx].cost = COL_COST_INFEASIBLE; } +static col_cost_t *add_constr_costs(co_mst_env_t *env, col_cost_t *costs, double factor, const co_mst_irn_t *node) +{ + int col = get_mst_irn_col(node); + int col_cnt = bitset_popcnt(node->adm_colors); + int idx; + + if (col_cnt < env->k) { + /* calculate costs for constrained interfering nodebours */ + double ratio = 1.0 - (double) col_cnt / env->k; + + bitset_foreach_clear(node->adm_colors, idx) { + /* check only explicitly forbidden colors (skip global forbidden ones) */ + if (! bitset_is_set(env->ignore_regs, idx)) { + costs[col].cost += ratio * factor; + } + } + } + return costs; +} + + /* need forward declaration due to recursive call */ static int recolor_nodes(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs, struct list_head *changed_ones); @@ -1050,6 +1138,7 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { int did_all = 0; waitq *tmp_chunks = new_waitq(); waitq *best_starts = NULL; + col_cost_t *order = alloca(env->n_regs * sizeof(*order)); bitset_t *visited; int col, idx, len; struct list_head changed_ones; @@ -1058,6 +1147,26 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) { DBG_AFF_CHUNK(env, LEVEL_2, c); DB((dbg, LEVEL_2, "\n")); + for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) { + ir_node *irn = c->n[idx]; + co_mst_irn_t *node = get_co_mst_irn(env, irn); + int i; + + add_constr_costs(env, order, -1.0, node); + for (i = node->n_neighs - 1; i >= 0; --i) { + co_mst_irn_t *neigh = get_co_mst_irn(env, node->int_neighs[i]); + add_constr_costs(env, order, 1.0, neigh); + } + } + + for (col = 0; col < env->n_regs; ++col) { + order[col].col = col; + if (bitset_is_set(env->ignore_regs, col)) + order[col].cost = COL_COST_INFEASIBLE; + } + + qsort(order, env->n_regs, sizeof(order[0]), cmp_col_cost); + chunk_order_nodes(env, c); /* check which color is the "best" for the given chunk. * if we found a color which was ok for all nodes, we take it diff --git a/ir/be/becopyilp2.c b/ir/be/becopyilp2.c index d6d4b755e..befc61877 100644 --- a/ir/be/becopyilp2.c +++ b/ir/be/becopyilp2.c @@ -68,13 +68,16 @@ typedef struct _local_env_t { double time_limit; int first_x_var, last_x_var; + int n_colors; + bitset_t *normal_colors; pmap *nr_2_irn; DEBUG_ONLY(firm_dbg_module_t *dbg;) } local_env_t; static void build_coloring_cstr(ilp_env_t *ienv) { - be_ifg_t *ifg = ienv->co->cenv->ifg; - void *iter = be_ifg_nodes_iter_alloca(ifg); + local_env_t *lenv = ienv->env; + be_ifg_t *ifg = ienv->co->cenv->ifg; + void *iter = be_ifg_nodes_iter_alloca(ifg); bitset_t *colors; ir_node *irn; char buf[16]; @@ -94,12 +97,13 @@ static void build_coloring_cstr(ilp_env_t *ienv) { req = arch_get_register_req(ienv->co->aenv, irn, -1); + bitset_clear_all(colors); + /* get assignable colors */ if (arch_register_req_is(req, limited)) { rbitset_copy_to_bitset(req->limited, colors); } else { - arch_register_class_put(req->cls, colors); - // bitset_andnot(colors, ienv->co->cenv->ignore_colors); + bitset_copy(colors, lenv->normal_colors); } /* add the coloring constraint */ @@ -128,9 +132,10 @@ static void build_coloring_cstr(ilp_env_t *ienv) { } static void build_interference_cstr(ilp_env_t *ienv) { - lpp_t *lpp = ienv->lp; - be_ifg_t *ifg = ienv->co->cenv->ifg; - int n_colors = arch_register_class_n_regs(ienv->co->cls); + lpp_t *lpp = ienv->lp; + local_env_t *lenv = ienv->env; + be_ifg_t *ifg = ienv->co->cenv->ifg; + int n_colors = lenv->n_colors; int i, col; void *iter = be_ifg_cliques_iter_alloca(ifg); @@ -174,8 +179,9 @@ static void build_interference_cstr(ilp_env_t *ienv) { * does not provide this walker, yet. */ static void build_affinity_cstr(ilp_env_t *ienv) { + local_env_t *lenv = ienv->env; + int n_colors = lenv->n_colors; unit_t *curr; - int n_colors = arch_register_class_n_regs(ienv->co->cls); /* for all optimization units */ list_for_each_entry(unit_t, curr, &ienv->co->units, units) { @@ -544,6 +550,11 @@ int co_solve_ilp2(copy_opt_t *co) { my.nr_2_irn = pmap_create(); FIRM_DBG_REGISTER(my.dbg, "firm.be.coilp2"); + my.normal_colors = bitset_alloca(arch_register_class_n_regs(co->cls)); + bitset_clear_all(my.normal_colors); + arch_put_non_ignore_regs(co->aenv, co->cls, my.normal_colors); + my.n_colors = bitset_popcnt(my.normal_colors); + ienv = new_ilp_env(co, ilp2_build, ilp2_apply, &my); sol_state = ilp_go(ienv); diff --git a/ir/be/bemodule.c b/ir/be/bemodule.c index 1a678c706..5fad5159f 100644 --- a/ir/be/bemodule.c +++ b/ir/be/bemodule.c @@ -24,9 +24,8 @@ * @date 29.09.2005 * @version $Id$ */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ + +#include "firm_config.h" #include @@ -45,6 +44,7 @@ void be_init_copycoal(void); void be_init_copyheur2(void); void be_init_copyheur3(void); void be_init_copyheur4(void); +void be_init_copyheur5(void); void be_init_copystat(void); void be_init_daemelspill(void); void be_init_arch_ia32(void); @@ -60,7 +60,6 @@ void be_init_peephole(void); void be_init_ra(void); void be_init_spillbelady(void); void be_init_spillbelady2(void); -void be_init_spillremat(void); void be_init_ssaconstr(void); void be_init_ifg(void); void be_init_irgmod(void); @@ -98,6 +97,7 @@ void be_init_modules(void) be_init_copycoal(); be_init_copyheur2(); be_init_copyheur4(); + be_init_copyheur5(); be_init_copystat(); be_init_peephole(); be_init_ra(); @@ -117,7 +117,6 @@ void be_init_modules(void) #ifdef WITH_ILP be_init_ilpsched(); be_init_copyilp(); - be_init_spillremat(); #endif /* WITH_ILP */ #ifdef WITH_JVM