#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) {
/* 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);
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#ifdef WITH_ILP
-
#include "becopyilp_t.h"
#include "beifg_t.h"
*****************************************************************************/
-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;
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
free_lpp(ienv->lp);
free(ienv);
}
-
-#else /* WITH_ILP */
-
-static void only_that_you_can_compile_without_WITH_ILP_defined(void) {
-}
-
-#endif /* WITH_ILP */
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));
} 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) {
}
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);
#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;
#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
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 */
};
-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
#include <malloc.h>
#endif
-#include <libcore/lc_timing.h>
-
#include "xmalloc.h"
#include "debug.h"
#include "pmap.h"
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);
-}
*/
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
#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)))
#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;
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);
}
}
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 */
#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"
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();
#define copystat_dump(irg);
#define copystat_dump_pretty(irg);
-#endif /* DO_STAT */
+#endif /* COPYOPT_STAT */
#endif /* _BECOPYSTAT_H */
#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))