Some heur4 tweaks
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Mon, 22 Oct 2007 13:13:07 +0000 (13:13 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Mon, 22 Oct 2007 13:13:07 +0000 (13:13 +0000)
ILP coalescing should work again
changed include of config.h to firm_config.h since WITH_ILP is defined there

[r16304]

ir/be/becopyheur4.c
ir/be/becopyilp2.c
ir/be/bemodule.c

index 48786e4..94af23e 100644 (file)
@@ -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
index d6d4b75..befc618 100644 (file)
 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);
index 1a678c7..5fad515 100644 (file)
@@ -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 <stdlib.h>
 
@@ -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