From: Daniel Grund Date: Thu, 9 Mar 2006 09:27:15 +0000 (+0000) Subject: Next step of refactoring X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=646d941217399e4bc713359fd5ad393e4db8b905;p=libfirm Next step of refactoring --- diff --git a/ir/be/bechordal_main.c b/ir/be/bechordal_main.c index b301eeebd..98812caef 100644 --- a/ir/be/bechordal_main.c +++ b/ir/be/bechordal_main.c @@ -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); diff --git a/ir/be/becopyilp.c b/ir/be/becopyilp.c index b219b05ad..a064358a3 100644 --- a/ir/be/becopyilp.c +++ b/ir/be/becopyilp.c @@ -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 */ diff --git a/ir/be/becopyilp1.c b/ir/be/becopyilp1.c index 325dfd045..1acc95133 100644 --- a/ir/be/becopyilp1.c +++ b/ir/be/becopyilp1.c @@ -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); diff --git a/ir/be/becopyilp2.c b/ir/be/becopyilp2.c index ff0fcfd88..5cf5556eb 100644 --- a/ir/be/becopyilp2.c +++ b/ir/be/becopyilp2.c @@ -32,37 +32,225 @@ #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; colsr, 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; collp, 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 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; diff --git a/ir/be/becopyilp_t.h b/ir/be/becopyilp_t.h index bf016d6db..349593e88 100644 --- a/ir/be/becopyilp_t.h +++ b/ir/be/becopyilp_t.h @@ -11,18 +11,12 @@ #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 #endif - #ifdef HAVE_MALLOC_H #include #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 diff --git a/ir/be/becopyopt.c b/ir/be/becopyopt.c index 830aa3787..06142dcaa 100644 --- a/ir/be/becopyopt.c +++ b/ir/be/becopyopt.c @@ -14,8 +14,6 @@ #include #endif -#include - #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); -} diff --git a/ir/be/becopyopt.h b/ir/be/becopyopt.h index 1cd7cdd89..61abf8167 100644 --- a/ir/be/becopyopt.h +++ b/ir/be/becopyopt.h @@ -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 diff --git a/ir/be/becopyopt_t.h b/ir/be/becopyopt_t.h index 28fb8dd47..d899e6cd7 100644 --- a/ir/be/becopyopt_t.h +++ b/ir/be/becopyopt_t.h @@ -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))) diff --git a/ir/be/becopystat.c b/ir/be/becopystat.c index 7fa9c069b..467b4647f 100644 --- a/ir/be/becopystat.c +++ b/ir/be/becopystat.c @@ -9,16 +9,20 @@ #endif #include +#include + +#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 */ diff --git a/ir/be/becopystat.h b/ir/be/becopystat.h index 8f0126174..676738889 100644 --- a/ir/be/becopystat.h +++ b/ir/be/becopystat.h @@ -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 */ diff --git a/ir/be/beifg_t.h b/ir/be/beifg_t.h index 8b56a3e0b..10d721a4a 100644 --- a/ir/be/beifg_t.h +++ b/ir/be/beifg_t.h @@ -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))