Next step of refactoring
authorDaniel Grund <grund@cs.uni-saarland.de>
Thu, 9 Mar 2006 09:27:15 +0000 (09:27 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Thu, 9 Mar 2006 09:27:15 +0000 (09:27 +0000)
ir/be/bechordal_main.c
ir/be/becopyilp.c
ir/be/becopyilp1.c
ir/be/becopyilp2.c
ir/be/becopyilp_t.h
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/becopyopt_t.h
ir/be/becopystat.c
ir/be/becopystat.h
ir/be/beifg_t.h

index b301eee..98812ca 100644 (file)
@@ -49,9 +49,9 @@
 #include "bespillilp.h"
 #endif /* WITH_ILP */
 
+#include "becopystat.h"
 #include "becopyopt.h"
 #include "bessadestr.h"
-#include "becopystat.h"
 
 
 void be_ra_chordal_check(be_chordal_env_t *chordal_env) {
@@ -305,7 +305,15 @@ static void be_ra_chordal_main(const be_irg_t *bi)
 
                /* copy minimization */
                copystat_collect_cls(&chordal_env);
+#ifdef COPYOPT_STAT
                co_compare_solvers(&chordal_env);
+#else
+               {
+               copy_opt_t *co = new_copy_opt(&chordal_env, co_get_costs_loop_depth);
+               co_solve_heuristic(co);
+               free_copy_opt(co);
+               }
+#endif
                dump(BE_CH_DUMP_COPYMIN, irg, chordal_env.cls, "-copymin", dump_ir_block_graph_sched);
                be_ra_chordal_check(&chordal_env);
 
index b219b05..a064358 100644 (file)
@@ -8,12 +8,6 @@
  *
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#ifdef WITH_ILP
-
 #include "becopyilp_t.h"
 #include "beifg_t.h"
 
@@ -137,12 +131,11 @@ void free_size_red(size_red_t *sr) {
 
  *****************************************************************************/
 
-ilp_env_t *new_ilp_env(copy_opt_t *co, firm_dbg_module_t *dbg, ilp_callback build, ilp_callback apply, void *env) {
+ilp_env_t *new_ilp_env(copy_opt_t *co, ilp_callback build, ilp_callback apply, void *env) {
        ilp_env_t *res = malloc(sizeof(*res));
        assert(res);
 
        res->co = co;
-       res->dbg = dbg;
        res->build = build;
        res->apply = apply;
        res->env = env;
@@ -151,13 +144,11 @@ ilp_env_t *new_ilp_env(copy_opt_t *co, firm_dbg_module_t *dbg, ilp_callback buil
        return res;
 }
 
-lpp_sol_state_t ilp_go(ilp_env_t *ienv, double time_limit) {
+lpp_sol_state_t ilp_go(ilp_env_t *ienv) {
        sr_remove(ienv->sr);
 
        ienv->build(ienv);
 
-       lpp_set_time_limit(ienv->lp, time_limit);
-
 #ifdef LPP_SOLVE_NET
        lpp_solve_net(ienv->lp, LPP_HOST, LPP_SOLVER);
 #else
@@ -176,10 +167,3 @@ void free_ilp_env(ilp_env_t *ienv) {
        free_lpp(ienv->lp);
        free(ienv);
 }
-
-#else /* WITH_ILP */
-
-static void only_that_you_can_compile_without_WITH_ILP_defined(void) {
-}
-
-#endif /* WITH_ILP */
index 325dfd0..1acc951 100644 (file)
@@ -686,7 +686,7 @@ static int pi_apply_solution(problem_instance_t *pi) {
        lpp_sol_state_t state;
        DBG((dbg, LEVEL_2, "Applying solution...\n"));
 
-#ifdef DO_STAT
+#ifdef COPYOPT_STAT
        copystat_add_ilp_time((int)(1000.0*lpp_get_sol_time(pi->curr_lp)));  //now we have ms
        copystat_add_ilp_vars(lpp_get_var_count(pi->curr_lp));
        copystat_add_ilp_csts(lpp_get_cst_count(pi->curr_lp));
@@ -746,12 +746,12 @@ typedef struct _my_env_t {
 } my_env_t;
 
 
-static void ilp2_build(ilp_env_t *ienv) {
+static void ilp1_build(ilp_env_t *ienv) {
        ienv->lp = new_lpp(ienv->co->name, lpp_minimize);
 
 }
 
-static void ilp2_apply(ilp_env_t *ienv) {
+static void ilp1_apply(ilp_env_t *ienv) {
 
 }
 
@@ -759,15 +759,15 @@ int co_solve_ilp1(copy_opt_t *co, double time_limit) {
        lpp_sol_state_t sol_state;
        ilp_env_t *ienv;
        my_env_t my;
-       firm_dbg_module_t *dbg = firm_dbg_register("ir.be.coilp2");
+       firm_dbg_module_t *dbg = firm_dbg_register("ir.be.coilp1");
 
        firm_dbg_set_mask(dbg, DEBUG_LVL);
 
        // my.bla = TODO
 
-       ienv = new_ilp_env(co, dbg, ilp2_build, ilp2_apply, &my);
+       ienv = new_ilp_env(co, ilp1_build, ilp1_apply, &my);
 
-       sol_state = ilp_go(ienv, time_limit);
+       sol_state = ilp_go(ienv);
 
        free_ilp_env(ienv);
 
index ff0fcfd..5cf5556 100644 (file)
 #ifdef WITH_ILP
 
 #include "becopyilp_t.h"
+#include "beifg_t.h"
+#include "irtools.h"
 
 #define DEBUG_LVL 1
 
-typedef struct _my_env_t {
-       int foo;
-} my_env_t;
+typedef struct _local_env_t {
+       firm_dbg_module_t *dbg;
+       double time_limit;
+       int first_x_var, last_x_var;
+       pmap *nr_2_irn;
+} 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);
+       bitset_t *colors;
+       ir_node *irn;
+       char buf[16];
+
+       colors = bitset_alloca(arch_register_class_n_regs(ienv->co->cls));
+
+       be_ifg_foreach_node(ifg, iter, irn)
+               if (!sr_is_removed(ienv->sr, irn)) {
+                       int col, cst_idx;
+                       arch_register_req_t req;
+                       int curr_node_color = get_irn_col(ienv->co, irn);
+                       int node_nr = (int)get_irn_node_nr(irn);
+                       local_env_t *lenv = ienv->env;
+
+                       pmap_insert(lenv->nr_2_irn, INT_TO_PTR(node_nr), irn);
+
+                       arch_get_register_req(ienv->co->aenv, &req, irn, -1);
+
+                       /* get assignable colors */
+                       if (arch_register_req_is(&req, limited))
+                               req.limited(req.limited_env, colors);
+                       else
+                               arch_put_non_ignore_regs(ienv->co->aenv, req.cls, colors);
+
+                       /* add the coloring constraint */
+                       cst_idx = lpp_add_cst(ienv->lp, NULL, lpp_equal, 1.0);
+
+                       bitset_foreach(colors, col) {
+                               int var_idx = lpp_add_var(ienv->lp, name_cdd(buf, 'x', node_nr, col), lpp_binary, 0.0);
+                               lpp_set_start_value(ienv->lp, var_idx, (col == curr_node_color) ? 1.0 : 0.0);
+                               lpp_set_factor_fast(ienv->lp, cst_idx, var_idx, 1);
+
+                               lenv->last_x_var = var_idx;
+                               if (lenv->first_x_var == -1)
+                                       lenv->first_x_var = var_idx;
+                       }
+
+                       /* add register constraint constraints */
+                       bitset_foreach_clear(colors, col) {
+                               int cst_idx = lpp_add_cst(ienv->lp, NULL, lpp_equal, 0.0);
+                               int var_idx = lpp_add_var(ienv->lp, name_cdd(buf, 'x', node_nr, col), lpp_binary, 0.0);
+                               lpp_set_start_value(ienv->lp, var_idx, 0.0);
+                               lpp_set_factor_fast(ienv->lp, cst_idx, var_idx, 1);
+
+                               lenv->last_x_var = var_idx;
+                       }
+               }
+}
+
+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);
+       int i, col;
+
+       void *iter = be_ifg_cliques_iter_alloca(ifg);
+       ir_node *clique = alloca(sizeof(*clique) * n_colors);
+       int size;
+
+       char buf[16];
+
+       /* for each maximal clique */
+       be_ifg_foreach_clique(ifg, iter, &clique, &size) {
+
+               if (size < 2)
+                       continue;
+
+               /* for all colors */
+               for (col=0; col<n_colors; ++col) {
+                       int cst_idx = lpp_add_cst(lpp, NULL, lpp_less, 1.0);
+
+                       /* for each member of this clique */
+                       for (i=0; i<size, ++i) {
+                               ir_node *irn = clique[i];
+
+                               if (!sr_is_removed(ienv->sr, irn)) {
+                                       int var_idx = lpp_get_var_idx(lpp, name_cdd(buf, 'x', (int)get_irn_node_nr(irn), col));
+                                       lpp_set_factor_fast(lpp, cst_idx, var_idx, 1);
+                               }
+                       }
+               }
+       }
+}
+
+static void build_affinity_cstr(ilp_env_t *ienv) {
+       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) {
+               ir_node *root, *arg;
+               int root_nr, arg_nr, i, col, y_idx, root_idx, arg_idx;
+               char buf[16];
+               int root_col, arg_col;
+
+               root = curr->nodes[0];
+               root_nr = (int) get_irn_node_nr(root);
+               root_col = get_irn_col(ienv->co, root);
+
+               for (i = 1; i < curr->node_count; ++i) {
+                       arg = curr->nodes[i];
+                       arg_nr = (int) get_irn_node_nr(arg);
+                       arg_col = get_irn_col(ienv->co, arg);
+
+                       /* add a new affinity variable */
+                       y_idx = lpp_add_var(ienv->lp, name_cdd_sorted(buf, 'y', root_nr, arg_nr), lpp_binary, curr->costs[i]);
+                       lpp_set_start_value(ienv->lp, y_idx, (root_col==arg_col) ? 0.0 : 1.0);
+
+                       /* add constraints relating the affinity var to the color vars */
+                       for (col=0; col<n_colors; ++col) {
+                               int cst_idx = lpp_add_cst(ienv->lp, NULL, lpp_less, 0.0);
+                               root_idx = lpp_get_var_idx(ienv->lp, name_cdd(buf, 'x', root_nr, col));
+                               arg_idx  = lpp_get_var_idx(ienv->lp, name_cdd(buf, 'x', arg_nr,  col));
+
+                               lpp_set_factor_fast(ienv->lp, cst_idx, root_idx,  1.0);
+                               lpp_set_factor_fast(ienv->lp, cst_idx, arg_idx,  -1.0);
+                               lpp_set_factor_fast(ienv->lp, cst_idx, root_idx, -1.0);
+                       }
+               }
+       }
+}
+
+static void build_path_cstr(ilp_env_t *ienv) {
+
+}
+
+static void build_clique_path_cstr(ilp_env_t *ienv) {
+
+}
 
 static void ilp2_build(ilp_env_t *ienv) {
+       local_env_t *lenv = ienv->env;
+       int lower_bound;
+
        ienv->lp = new_lpp(ienv->co->name, lpp_minimize);
+       build_coloring_cstr(ienv);
+       build_interference_cstr(ienv);
+       build_affinity_cstr(ienv);
+       build_path_cstr(ienv);
+       build_clique_path_cstr(ienv);
 
+       lower_bound = co_get_lower_bound(ienv->co) - co_get_inevit_copy_costs(ienv->co);
+       lpp_set_bound(ienv->lp, lower_bound);
+       lpp_set_time_limit(ienv->lp, lenv->time_limit);
 }
 
 static void ilp2_apply(ilp_env_t *ienv) {
+       local_env_t *lenv = ienv->env;
+       double sol[];
+       lpp_sol_state_t state;
+       int count;
+
+       count = lenv->last_x_var - lenv->first_x_var + 1;
+       sol = xmalloc(count * sizeof(sol[0]));
+       state = lpp_get_solution(ienv->lp, sol, lenv->first_x_var, lenv->last_x_var);
+       if (state != lpp_optimal) {
+               printf("WARNING %s: Solution state is not 'optimal': %d\n", ienv->co->name, state);
+               assert(state >= lpp_feasible && "The solution should at least be feasible!");
+       }
 
+       for (i=0; i<count; ++i) {
+               char c;
+               int nodenr, color;
+               char var_name[16];
+
+               if (sol[i] > 1-EPSILON) { /* split variable name into components */
+                       lpp_get_var_name(ienv->lp, lenv->first_x_var+i, var_name, sizeof(var_name));
+
+                       if (sscanf(var_name, "x_%d_%d", &nodenr, &color) == 2) {
+                               ir_node *irn = pmap_get(lenv->nr_2_irn, INT_TO_PTR(nodenr));
+                               assert(irn && "This node number must be present in the map");
+
+                               set_irn_col(ienv->co, irn, color);
+                       } else
+                               assert(0 && "This should be a x-var");
+               }
+       }
+
+#ifdef COPYOPT_STAT
+       /* TODO adapt to multiple possible ILPs */
+       copystat_add_ilp_time((int)(1000.0*lpp_get_sol_time(pi->curr_lp)));  //now we have ms
+       copystat_add_ilp_vars(lpp_get_var_count(pi->curr_lp));
+       copystat_add_ilp_csts(lpp_get_cst_count(pi->curr_lp));
+       copystat_add_ilp_iter(lpp_get_iter_cnt(pi->curr_lp));
+#endif
 }
 
 int co_solve_ilp2(copy_opt_t *co, double time_limit) {
        lpp_sol_state_t sol_state;
        ilp_env_t *ienv;
-       my_env_t my;
-       firm_dbg_module_t *dbg = firm_dbg_register("ir.be.coilp2");
-
-       firm_dbg_set_mask(dbg, DEBUG_LVL);
+       local_env_t my;
 
-       // my.bla = TODO
+       my.time_limit  = time_limit;
+       my.first_x_var = -1;
+       my.last_x_var  = -1;
+       my.nr_2_irn    = pmap_create();
+       my.dbg         = firm_dbg_register("ir.be.coilp2");
+       firm_dbg_set_mask(my.dbg, DEBUG_LVL);
 
-       ienv = new_ilp_env(co, dbg, ilp2_build, ilp2_apply, &my);
+       ienv = new_ilp_env(co, ilp2_build, ilp2_apply, &my);
 
-       sol_state = ilp_go(ienv, time_limit);
+       sol_state = ilp_go(ienv);
 
+       pmap_destroy(my.nr_2_irn);
        free_ilp_env(ienv);
 
        return sol_state == lpp_optimal;
index bf016d6..349593e 100644 (file)
 #ifndef _BECOPYILP_T_H
 #define _BECOPYILP_T_H
 
-#include "firm_config.h"
-
-#ifndef _WIN32
- #ifndef HAVE_ALLOCA_H
-  #define HAVE_ALLOCA_H 1
- #endif /* HAVE_ALLOC_H */
-#endif /* _WIN32 */
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #endif
-
 #ifdef HAVE_MALLOC_H
 #include <malloc.h>
 #endif
@@ -134,7 +128,6 @@ typedef struct _ilp_env_t ilp_env_t;
 typedef void(*ilp_callback)(ilp_env_t*);
 
 struct _ilp_env_t {
-       firm_dbg_module_t *dbg;
        const copy_opt_t *co;                   /**< the copy opt problem */
        size_red_t *sr;                                 /**< problem size reduction. removes simple nodes */
        lpp_t *lp;                                              /**< the linear programming problem */
@@ -144,16 +137,17 @@ struct _ilp_env_t {
 
 };
 
-ilp_env_t *new_ilp_env(copy_opt_t *co, firm_dbg_module_t *dbg, ilp_callback build, ilp_callback apply, void *env);
+ilp_env_t *new_ilp_env(copy_opt_t *co, ilp_callback build, ilp_callback apply, void *env);
 
-lpp_sol_state_t ilp_go(ilp_env_t *ienv, double time_limit);
+lpp_sol_state_t ilp_go(ilp_env_t *ienv);
 
 void free_ilp_env(ilp_env_t *ienv);
 
 
-/******************************************************************************
-
+#define name_cdd(buf, char1, int1, int2) \
+                       (snprintf(buf, sizeof(buf), "%c_%d_%d", char1, int1, int2), buf)
 
- *****************************************************************************/
+#define name_cdd_sorted(buf, char1, int1, int2) \
+                       name_cdd(buf, char1, MIN(int1, int2), MAX(int1, int2))
 
-#endif /* _BECOPYILP_T_H */
+#endif
index 830aa37..06142dc 100644 (file)
@@ -14,8 +14,6 @@
 #include <malloc.h>
 #endif
 
-#include <libcore/lc_timing.h>
-
 #include "xmalloc.h"
 #include "debug.h"
 #include "pmap.h"
@@ -369,155 +367,3 @@ int co_get_lower_bound(const copy_opt_t *co) {
                res += curr->inevitable_costs + curr->min_nodes_costs;
        return res;
 }
-
-
-
-#define DO_HEUR
-#undef DO_CLASSES
-#undef DO_ILP
-
-
-/**
- * Helpers for saving and restoring colors of nodes.
- * Used to get dependable and comparable benchmark results.
- */
-#if (defined(DO_HEUR) && defined(DO_BETTER)) || (defined(DO_HEUR) && defined(DO_ILP)) || (defined(DO_BETTER) && defined(DO_ILP))
-
-typedef struct color_saver {
-       arch_env_t *arch_env;
-       be_chordal_env_t *chordal_env;
-       pmap *saved_colors;
-       int flag; /* 0 save, 1 load */
-} color_save_t;
-
-static void save_load(ir_node *irn, void *env) {
-       color_save_t *saver = env;
-       if (saver->chordal_env->cls == arch_get_irn_reg_class(saver->arch_env, irn, -1)) {
-               if (saver->flag == 0) { /* save */
-                       const arch_register_t *reg = arch_get_irn_register(saver->arch_env, irn);
-                       pmap_insert(saver->saved_colors, irn, (void *) reg);
-               } else { /*load */
-                       arch_register_t *reg = pmap_get(saver->saved_colors, irn);
-                       arch_set_irn_register(saver->arch_env, irn, reg);
-               }
-       }
-}
-
-static void save_colors(color_save_t *color_saver) {
-       color_saver->flag = 0;
-       irg_walk_graph(color_saver->chordal_env->irg, save_load, NULL, color_saver);
-}
-
-static void load_colors(color_save_t *color_saver) {
-       color_saver->flag = 1;
-       irg_walk_graph(color_saver->chordal_env->irg, save_load, NULL, color_saver);
-}
-
-#endif /* Need save/load stuff */
-
-
-
-void co_compare_solvers(be_chordal_env_t *chordal_env) {
-       copy_opt_t *co;
-
-#ifdef DO_STAT
-       lc_timer_t *timer;
-       color_save_t saver;
-       int costs, costs_inevit, costs_init, costs_heur, costs_classes, costs_ilp, lower_bound;
-#endif
-
-       co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
-       DBG((dbg, LEVEL_1, "----> CO: %s\n", co->name));
-       phi_class_compute(chordal_env->irg);
-
-
-#ifdef DO_STAT
-#if (defined(DO_HEUR) && defined(DO_BETTER)) || (defined(DO_HEUR) && defined(DO_ILP)) || (defined(DO_BETTER) && defined(DO_ILP))
-               saver.arch_env = chordal_env->main_env->arch_env;
-               saver.chordal_env = chordal_env;
-               saver.saved_colors = pmap_create();
-               save_colors(&saver);
-#endif
-
-               costs_inevit = co_get_inevit_copy_costs(co);
-               lower_bound  = co_get_lower_bound(co);
-               costs_init   = co_get_copy_costs(co);
-
-               DBG((dbg, LEVEL_1, "Inevit Costs: %3d\n", costs_inevit));
-               DBG((dbg, LEVEL_1, "Lower Bound: %3d\n", lower_bound));
-               DBG((dbg, LEVEL_1, "Init costs: %3d\n", costs_init));
-
-               copystat_add_inevit_costs(costs_inevit);
-               copystat_add_init_costs(costs_init);
-               copystat_add_max_costs(co_get_max_copy_costs(co));
-#endif
-
-
-#ifdef DO_HEUR
-#ifdef DO_STAT
-       timer = lc_timer_register("heur", NULL);
-       lc_timer_reset_and_start(timer);
-#endif
-
-       co_solve_heuristic(co);
-
-#ifdef DO_STAT
-       lc_timer_stop(timer);
-       costs_heur = co_get_copy_costs(co);
-       DBG((dbg, LEVEL_1, "Heur costs: %3d\n", costs_heur));
-       copystat_add_heur_time(lc_timer_elapsed_msec(timer));
-       copystat_add_heur_costs(costs_heur);
-       assert(lower_bound <= costs_heur);
-#endif
-#endif /* DO_HEUR */
-
-
-
-#ifdef DO_CLASSES
-#ifdef DO_STAT
-#ifdef DO_HEUR
-       load_colors(&saver);
-#endif
-       timer = lc_timer_register("classes", NULL);
-       lc_timer_reset_and_start(timer);
-#endif
-
-       co_classes_opt(co);
-
-#ifdef DO_STAT
-       lc_timer_stop(timer);
-       costs_classes = co_get_copy_costs(co);
-       DBG((dbg, LEVEL_1, "Classes costs: %3d\n", costs_classes));
-       copystat_add_classes_time(lc_timer_elapsed_msec(timer));
-       copystat_add_classes_costs(costs_heur);
-       assert(lower_bound <= costs_classes);
-#endif
-#endif /* DO_CLASSES */
-
-
-
-#ifdef DO_ILP
-#ifdef DO_STAT
-#if defined(DO_HEUR) || defined(DO_CLASSES)
-       load_colors(&saver);
-#endif
-#endif
-
-       co_solve_ilp1(co, 60.0);
-
-#ifdef DO_STAT
-       costs_ilp = co_get_copy_costs(co);
-       DBG((dbg, LEVEL_1, "Opt  costs: %3d\n", costs_ilp));
-       copystat_add_opt_costs(costs_ilp);
-       assert(lower_bound <= costs_ilp);
-#endif
-#endif /* DO_ILP */
-
-
-#ifdef DO_STAT
-#if (defined(DO_HEUR) && defined(DO_BETTER)) || (defined(DO_HEUR) && defined(DO_ILP)) || (defined(DO_BETTER) && defined(DO_ILP))
-       pmap_destroy(saver.saved_colors);
-#endif
-#endif
-       free_copy_opt(co);
-}
index 1cd7cdd..61abf81 100644 (file)
@@ -66,9 +66,4 @@ int co_solve_ilp1(copy_opt_t *co, double time_limit);
  */
 int co_solve_ilp2(copy_opt_t *co, double time_limit);
 
-/**
- * Compares different solutions of the same problem
- */
-void co_compare_solvers(be_chordal_env_t *chordal_env);
-
 #endif
index 28fb8dd..d899e6c 100644 (file)
@@ -60,8 +60,7 @@ typedef struct _unit_t {
 
 #define list_entry_units(lh) list_entry(lh, unit_t, units)
 
-
-#define get_Copy_src(irn) (get_irn_n(get_Proj_pred(irn), get_Proj_proj(irn)))
+#define get_Copy_src(irn)                   (get_irn_n(get_Proj_pred(irn), get_Proj_proj(irn)))
 #define is_Perm(arch_env, irn)                         (arch_irn_classify(arch_env, irn) == arch_irn_class_perm)
 #define is_Reg_Phi(irn)                                                (is_Phi(irn) && mode_is_data(get_irn_mode(irn)))
 #define is_Perm_Proj(arch_env, irn)                    (is_Proj(irn) && is_Perm(arch_env, get_Proj_pred(irn)))
index 7fa9c06..467b464 100644 (file)
@@ -9,16 +9,20 @@
 #endif
 
 #include <string.h>
+#include <libcore/lc_timing.h>
+
+#include "xmalloc.h"
 #include "irgraph.h"
+#include "irgwalk.h"
 #include "irprog.h"
-#include "iredges.h"
+#include "iredges_t.h"
 #include "phiclass_t.h"
+#include "bechordal_t.h"
 #include "beutil.h"
-#include "becopyopt.h"
+#include "becopyopt_t.h"
 #include "becopystat.h"
-#include "xmalloc.h"
 
-#ifdef DO_STAT
+#ifdef COPYOPT_STAT
 
 #define DEBUG_LVL SET_LEVEL_1
 static firm_dbg_module_t *dbg = NULL;
@@ -275,33 +279,30 @@ static void stat_phi_class(be_chordal_env_t *chordal_env, pset *pc) {
        xfree(members);
 }
 
-#define is_curr_reg_class(irn) \
-  (arch_get_irn_reg_class(chordal_env->main_env->arch_env, irn, \
-                          -1) == chordal_env->cls)
-
-void copystat_collect_cls(be_chordal_env_t *chordal_env) {
+void copystat_collect_cls(be_chordal_env_t *cenv) {
        ir_node *n;
        pset *pc;
-       ir_graph *irg = chordal_env->irg;
+       ir_graph *irg = cenv->irg;
+       arch_env_t *aenv = cenv->birg->main_env->arch_env;
 
        if (last_irg != irg) {
                copystat_reset();
-               copystat_collect_irg(irg, chordal_env->main_env->arch_env);
+               copystat_collect_irg(irg, aenv);
        }
 
        for (n = pset_first(all_phi_nodes); n; n = pset_next(all_phi_nodes))
-               if (is_curr_reg_class(n))
-                       stat_phi_node(chordal_env, n);
+               if (arch_get_irn_reg_class(aenv, n, -1) == cenv->cls)
+                       stat_phi_node(cenv, n);
 
        for (n = pset_first(all_copy_nodes); n; n = pset_next(all_copy_nodes))
-               if (is_curr_reg_class(n))
-                       stat_copy_node(chordal_env, n);
+               if (arch_get_irn_reg_class(aenv, n, -1) == cenv->cls)
+                       stat_copy_node(cenv, n);
 
        for (pc = pset_first(all_phi_classes); pc; pc = pset_next(all_phi_classes)) {
                ir_node *member = pset_first(pc);
                pset_break(pc);
-               if (is_curr_reg_class(member))
-                       stat_phi_class(chordal_env, pc);
+               if (arch_get_irn_reg_class(aenv, member, -1) == cenv->cls)
+                       stat_phi_class(cenv, pc);
        }
 }
 
@@ -412,4 +413,114 @@ void copystat_dump_pretty(ir_graph *irg) {
        fclose(out);
 }
 
-#endif
+/**
+ * Helpers for saving and restoring colors of nodes.
+ * Used to get dependable and comparable benchmark results.
+ */
+typedef struct color_saver {
+       arch_env_t *arch_env;
+       be_chordal_env_t *chordal_env;
+       pmap *saved_colors;
+       int flag; /* 0 save, 1 load */
+} color_save_t;
+
+static void save_load(ir_node *irn, void *env) {
+       color_save_t *saver = env;
+       if (saver->chordal_env->cls == arch_get_irn_reg_class(saver->arch_env, irn, -1)) {
+               if (saver->flag == 0) { /* save */
+                       const arch_register_t *reg = arch_get_irn_register(saver->arch_env, irn);
+                       pmap_insert(saver->saved_colors, irn, (void *) reg);
+               } else { /*load */
+                       arch_register_t *reg = pmap_get(saver->saved_colors, irn);
+                       arch_set_irn_register(saver->arch_env, irn, reg);
+               }
+       }
+}
+
+static void save_colors(color_save_t *color_saver) {
+       color_saver->flag = 0;
+       irg_walk_graph(color_saver->chordal_env->irg, save_load, NULL, color_saver);
+}
+
+static void load_colors(color_save_t *color_saver) {
+       color_saver->flag = 1;
+       irg_walk_graph(color_saver->chordal_env->irg, save_load, NULL, color_saver);
+}
+
+/**
+ * Main compare routine
+ */
+void co_compare_solvers(be_chordal_env_t *chordal_env) {
+       copy_opt_t *co;
+       lc_timer_t *timer;
+       color_save_t saver;
+       int costs_inevit, costs_init, costs_heur, costs_ilp1, costs_ilp2, lower_bound;
+
+       co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
+       DBG((dbg, LEVEL_1, "----> CO: %s\n", co->name));
+       phi_class_compute(chordal_env->irg);
+
+       /* save colors */
+       saver.arch_env = chordal_env->birg->main_env->arch_env;
+       saver.chordal_env = chordal_env;
+       saver.saved_colors = pmap_create();
+       save_colors(&saver);
+
+       /* initial values */
+       costs_inevit = co_get_inevit_copy_costs(co);
+       lower_bound  = co_get_lower_bound(co);
+       costs_init   = co_get_copy_costs(co);
+
+       DBG((dbg, LEVEL_1, "Inevit Costs: %3d\n", costs_inevit));
+       DBG((dbg, LEVEL_1, "Lower Bound: %3d\n", lower_bound));
+       DBG((dbg, LEVEL_1, "Init costs: %3d\n", costs_init));
+
+       copystat_add_inevit_costs(costs_inevit);
+       copystat_add_init_costs(costs_init);
+       copystat_add_max_costs(co_get_max_copy_costs(co));
+
+
+#ifdef DO_HEUR
+       timer = lc_timer_register("heur", NULL);
+       lc_timer_reset_and_start(timer);
+
+       co_solve_heuristic(co);
+
+       lc_timer_stop(timer);
+       costs_heur = co_get_copy_costs(co);
+       DBG((dbg, LEVEL_1, "HEUR costs: %3d\n", costs_heur));
+       copystat_add_heur_time(lc_timer_elapsed_msec(timer));
+       copystat_add_heur_costs(costs_heur);
+       assert(lower_bound <= costs_heur);
+#endif /* DO_HEUR */
+
+
+#ifdef DO_ILP1
+       load_colors(&saver);
+
+       co_solve_ilp1(co, 60.0);
+
+       costs_ilp1 = co_get_copy_costs(co);
+       DBG((dbg, LEVEL_1, "ILP1 costs: %3d\n", costs_ilp1));
+       copystat_add_opt_costs(costs_ilp1); /*TODO ADAPT */
+       assert(lower_bound <= costs_ilp1);
+#endif /* DO_ILP1 */
+
+
+#ifdef DO_ILP2
+       load_colors(&saver);
+
+       co_solve_ilp2(co, 60.0);
+
+       costs_ilp2 = co_get_copy_costs(co);
+       DBG((dbg, LEVEL_1, "ILP2 costs: %3d\n", costs_ilp2));
+       copystat_add_opt_costs(costs_ilp2); /*TODO ADAPT */
+       assert(lower_bound <= costs_ilp2);
+#endif /* DO_ILP2 */
+
+       pmap_destroy(saver.saved_colors);
+       free_copy_opt(co);
+}
+
+
+#endif /* COPYOPT_STAT */
index 8f01261..6767388 100644 (file)
@@ -7,9 +7,13 @@
 #ifndef _BECOPYSTAT_H
 #define _BECOPYSTAT_H
 
-#undef DO_STAT
+#define COPYOPT_STAT
 
-#ifdef DO_STAT
+#ifdef COPYOPT_STAT
+
+#define DO_HEUR
+#define DO_ILP1
+#define DO_ILP2
 
 #include "irgraph.h"
 #include "bearch.h"
@@ -33,7 +37,12 @@ void copystat_add_ilp_iter(int iters);
 void copystat_dump(ir_graph *irg);
 void copystat_dump_pretty(ir_graph *irg);
 
-#else /* DO_STAT */
+/**
+ * Compares different solutions of the same problem
+ */
+void co_compare_solvers(be_chordal_env_t *chordal_env);
+
+#else /* COPYOPT_STAT */
 
 #define copystat_init();
 #define        copystat_reset();
@@ -54,6 +63,6 @@ void copystat_dump_pretty(ir_graph *irg);
 #define copystat_dump(irg);
 #define copystat_dump_pretty(irg);
 
-#endif /* DO_STAT */
+#endif /* COPYOPT_STAT */
 
 #endif /* _BECOPYSTAT_H */
index 8b56a3e..10d721a 100644 (file)
@@ -41,6 +41,7 @@ struct _be_ifg_t {
 
 #define be_ifg_nodes_iter_size(self)              ((self)->impl->nodes_iter_size)
 #define be_ifg_neighbours_iter_size(self)         ((self)->impl->neighbours_iter_size)
+#define be_ifg_cliques_iter_size(self)            ((self)->impl->cliques_iter_size)
 
 #define be_ifg_free(self)                         ((self)->impl->free(self))
 #define be_ifg_connected(self,a,b)                ((self)->impl->connected(self, a, b))