From: Daniel Grund Date: Tue, 7 Jun 2005 09:09:59 +0000 (+0000) Subject: Bugfixes, adaption to new lpp. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=8b804cbbf9f18aa5e4295efca0e92e46cd1da6c9;p=libfirm Bugfixes, adaption to new lpp. --- diff --git a/ir/be/Makefile.in b/ir/be/Makefile.in index 50968cb63..5ab4dbc25 100644 --- a/ir/be/Makefile.in +++ b/ir/be/Makefile.in @@ -25,7 +25,9 @@ SOURCES += Makefile.in besched.h belistsched.h belistsched.c \ bera.h bechordalspill.c beasm_dump_globals.c beasm_asm_gnu.c \ sp_matrix.c becopyoptmain.c becopyopt.c becopyheur.c \ becopyilp.c becopystat.c bearch_firm.c bearch.c bechordal_draw.c \ - bechordal_draw.h beirgmod.c beirgmod.h benode.c benode_t.h lpp_rzcpx.c + bechordal_draw.h beirgmod.c beirgmod.h benode.c benode_t.h \ + mps.c lpp.c lpp_local.c lpp_remote.c +#bessadestr.c include $(topdir)/MakeRules diff --git a/ir/be/becopyheur.c b/ir/be/becopyheur.c index 93653938c..4621ff110 100644 --- a/ir/be/becopyheur.c +++ b/ir/be/becopyheur.c @@ -6,10 +6,11 @@ * Heuristic for minimizing copies using a queue which holds 'qnodes' not yet * examined. A qnode has a 'target color', nodes out of the opt unit and - * a 'conflict graph'. A 'max indep set' is determined form these. We try to - * color this mis using a color-exchanging mechanism. Occuring conflicts are - * modeled with 'conflict edges' and the qnode is reinserted in the queue. The - * first qnode colored without conflicts is the best one. + * a 'conflict graph'. 'Conflict graph' = "Interference graph' + 'conflict edges' + * A 'max indep set' is determined form these. We try to color this mis using a + * color-exchanging mechanism. Occuring conflicts are modeled with 'conflict edges' + * and the qnode is reinserted in the queue. The first qnode colored without + * conflicts is the best one. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -205,8 +206,9 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const struct obstack confl_ob; ir_node **confl, *cn; int i, irn_col; - const arch_env_t *arch_env = qn->ou->co->env; - const be_chordal_env_t *chordal_env = qn->ou->co->chordal_env; + const be_chordal_env_t *chordal_env = qn->ou->co->chordal_env; + const arch_env_t *arch_env = chordal_env->arch_env; + const arch_register_class_t *cls = chordal_env->cls; DBG((dbg, LEVEL_3, "\t %n \tcaused col(%n) \t%2d --> %2d\n", trigger, irn, qnode_get_new_color(qn, irn), col)); obstack_init(&confl_ob); @@ -221,7 +223,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const if (!arch_reg_is_allocatable(arch_env, irn, arch_pos_make_out(0), - arch_register_for_index(qn->ou->co->cls, col))) + arch_register_for_index(cls, col))) goto ret_imposs; /* get all nodes which would conflict with this change */ @@ -237,7 +239,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const ir_node *n; pset *live_ins = get_live_in(irn_bl); for (n = pset_first(live_ins); n; n = pset_next(live_ins)) - if (arch_irn_has_reg_class(arch_env, n, arch_pos_make_out(0), qn->ou->co->cls) + if (arch_irn_has_reg_class(arch_env, n, arch_pos_make_out(0), cls) && n != trigger && qnode_get_new_color(qn, n) == col && nodes_interfere(chordal_env, irn, n)) { @@ -267,7 +269,7 @@ static ir_node *qnode_color_irn(const qnode_t *qn, ir_node *irn, int col, const * the target color and interfere with the irn */ for (i = 0, max = get_irn_n_outs(curr_bl); i < max; ++i) { ir_node *n = get_irn_out(curr_bl, i); - if (arch_irn_has_reg_class(arch_env, n, arch_pos_make_out(0), qn->ou->co->cls) + if (arch_irn_has_reg_class(arch_env, n, arch_pos_make_out(0), cls) && n != trigger && qnode_get_new_color(qn, n) == col && nodes_interfere(chordal_env, irn, n)) { @@ -466,11 +468,6 @@ static INLINE void ou_insert_qnode(unit_t *ou, qnode_t *qn) { } qnode_max_ind_set(qn, ou); - - /* set ou->mis_size for lower bound compution */ - if (ou->mis_size < qn->mis_size) - ou->mis_size = qn->mis_size; - /* do the insertion */ DBG((dbg, LEVEL_4, "\t Insert qnode color %d with size %d\n", qn->color, qn->mis_size)); lh = &ou->queue; @@ -493,7 +490,7 @@ static INLINE void ou_insert_qnode(unit_t *ou, qnode_t *qn) { static void ou_optimize(unit_t *ou) { int i; qnode_t *curr, *tmp; - bitset_t *pos_regs = bitset_alloca(ou->co->cls->n_regs); + bitset_t *pos_regs = bitset_alloca(ou->co->chordal_env->cls->n_regs); DBG((dbg, LEVEL_1, "\tOptimizing unit:\n")); for (i=0; inode_count; ++i) @@ -501,7 +498,7 @@ static void ou_optimize(unit_t *ou) { /* init queue */ INIT_LIST_HEAD(&ou->queue); - arch_get_allocatable_regs(ou->co->env, ou->nodes[0], arch_pos_make_out(0), ou->co->cls, pos_regs); + arch_get_allocatable_regs(ou->co->chordal_env->arch_env, ou->nodes[0], arch_pos_make_out(0), ou->co->chordal_env->cls, pos_regs); bitset_foreach(pos_regs, i) ou_insert_qnode(ou, new_qnode(ou, i)); diff --git a/ir/be/becopyilp.c b/ir/be/becopyilp.c index 6f7f75bf2..687b5a46f 100644 --- a/ir/be/becopyilp.c +++ b/ir/be/becopyilp.c @@ -18,10 +18,13 @@ #include "irprog.h" #include "lpp.h" +#include "lpp_local.h" +#include "lpp_remote.h" #include "xmalloc.h" #include "becopyopt.h" #include "becopystat.h" +#define DUMP_MPS #define DEBUG_LVL SET_LEVEL_1 static firm_dbg_module_t *dbg = NULL; @@ -39,7 +42,7 @@ typedef struct _simpl_t { } simpl_t; typedef struct _problem_instance_t { - const copy_opt_t *co; /** the original copy_opt problem */ + const copy_opt_t *co; /** the copy_opt problem */ /* problem size reduction removing simple nodes */ struct list_head simplicials; /**< holds all simpl_t's in right order to color*/ pset *removed; /**< holds all removed simplicial irns */ @@ -49,9 +52,13 @@ typedef struct _problem_instance_t { lpp_t *curr_lp; /**< points to the problem currently used */ int curr_color, cst_counter, last_x_var; char buf[32]; + int all_simplicial; } problem_instance_t; #define is_removed(irn) pset_find_ptr(pi->removed, irn) + +#define is_color_possible(irn,color) arch_reg_is_allocatable(pi->co->chordal_env->arch_env, irn, arch_pos_make_out(0), arch_register_for_index(pi->co->chordal_env->cls, color)) + /* * Some stuff for variable name handling. */ @@ -101,11 +108,13 @@ static void pi_find_simplicials(problem_instance_t *pi) { if_node_t *ifn; int redo = 1; + DBG((dbg, LEVEL_2, "Find simlicials...\n")); + if_nodes = be_ra_get_ifg_nodes(pi->co->chordal_env); while (redo) { redo = 0; for (ifn = set_first(if_nodes); ifn; ifn = set_next(if_nodes)) { - ir_node *irn = get_irn_for_graph_nr(pi->co->irg, ifn->nnr); + ir_node *irn = get_irn_for_graph_nr(pi->co->chordal_env->irg, ifn->nnr); if (!is_removed(irn) && !is_optimizable(irn) && !is_optimizable_arg(pi->co, irn) && pi_is_simplicial(pi, ifn)) { simpl_t *s = xmalloc(sizeof(*s)); @@ -126,7 +135,7 @@ static void pi_add_constr_A(ir_node *block, void *env) { problem_instance_t *pi = env; struct list_head *head = get_block_border_head(pi->co->chordal_env, block); border_t *curr; - bitset_t *pos_regs = bitset_alloca(pi->co->cls->n_regs); + bitset_t *pos_regs = bitset_alloca(pi->co->chordal_env->cls->n_regs); list_for_each_entry_reverse(border_t, curr, head, list) if (curr->is_def && curr->is_real && !is_removed(curr->irn)) { @@ -138,7 +147,7 @@ static void pi_add_constr_A(ir_node *block, void *env) { // iterate over all possible colors in order bitset_clear_all(pos_regs); - arch_get_allocatable_regs(pi->co->env, curr->irn, arch_pos_make_out(0), pi->co->cls, pos_regs); + arch_get_allocatable_regs(pi->co->chordal_env->arch_env, curr->irn, arch_pos_make_out(0), pi->co->chordal_env->cls, pos_regs); bitset_foreach(pos_regs, col) { int var_idx; mangle_var(pi->buf, 'x', nnr, col); @@ -169,7 +178,6 @@ static INLINE int all_live_in(ir_node *block, pset *living) { * for which the color pi->curr_color is possible. Finds only 'maximal-cliques', * viz cliques which are not contained in another one. * This is used for the matrix B. - * TODO check color */ static void pi_add_constr_B(ir_node *block, void *env) { problem_instance_t *pi = env; @@ -180,7 +188,7 @@ static void pi_add_constr_B(ir_node *block, void *env) { list_for_each_entry_reverse(border_t, b, head, list) { const ir_node *irn = b->irn; - if (is_removed(irn)) + if (is_removed(irn) || !is_color_possible(irn, pi->curr_color)) continue; if (b->is_def) { @@ -202,7 +210,6 @@ static void pi_add_constr_B(ir_node *block, void *env) { int var_idx; mangle_var_irn(pi->buf, 'x', n, pi->curr_color); var_idx = lpp_get_var_idx(pi->curr_lp, pi->buf); - assert(var_idx>=1); lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1); } pi->cst_counter++; @@ -218,30 +225,35 @@ static void pi_add_constr_B(ir_node *block, void *env) { static void pi_add_constr_E(problem_instance_t *pi) { unit_t *curr; bitset_t *root_regs, *arg_regs; - root_regs = bitset_alloca(pi->co->cls->n_regs); - arg_regs = bitset_alloca(pi->co->cls->n_regs); + int cst_counter = 0; + unsigned nregs = pi->co->chordal_env->cls->n_regs; + root_regs = bitset_alloca(nregs); + arg_regs = bitset_alloca(nregs); /* for all roots of optimization units */ list_for_each_entry(unit_t, curr, &pi->co->units, units) { const ir_node *root, *arg; int rootnr, argnr, color; - int y_idx, i, cst_counter = 0; + int y_idx, i; char buf[32]; root = curr->nodes[0]; rootnr = get_irn_graph_nr(root); bitset_clear_all(root_regs); - arch_get_allocatable_regs(pi->co->env, root, arch_pos_make_out(0), pi->co->cls, root_regs); + arch_get_allocatable_regs(pi->co->chordal_env->arch_env, root, arch_pos_make_out(0), pi->co->chordal_env->cls, root_regs); /* for all arguments of root */ for (i = 1; i < curr->node_count; ++i) { arg = curr->nodes[i]; argnr = get_irn_graph_nr(arg); bitset_clear_all(arg_regs); - arch_get_allocatable_regs(pi->co->env, arg, arch_pos_make_out(0), pi->co->cls, arg_regs); + arch_get_allocatable_regs(pi->co->chordal_env->arch_env, arg, arch_pos_make_out(0), pi->co->chordal_env->cls, arg_regs); /* Introduce new variable and set factor in objective function */ - y_idx = lpp_add_var(pi->curr_lp, NULL, real, get_weight(root, arg)); + mangle_var(buf, 'y', rootnr, argnr); + y_idx = lpp_add_var(pi->curr_lp, buf, continous, get_weight(root, arg)); + /* set starting value */ + //lpp_set_start_value(pi->curr_lp, y_idx, (get_irn_col(pi->co, root) != get_irn_col(pi->co, arg))); /* For all colors root and arg have in common, add 2 constraints to E */ bitset_and(arg_regs, root_regs); @@ -252,14 +264,14 @@ static void pi_add_constr_E(problem_instance_t *pi) { mangle_var(buf, 'x', argnr, color); arg_idx = lpp_get_var_idx(pi->curr_lp, buf); - /* add root-arg+y <= 1 */ + /* add root-arg-y <= 0 */ mangle_cst(buf, 'E', cst_counter++); cst_idx = lpp_add_cst(pi->curr_lp, buf, less, 0); lpp_set_factor_fast(pi->curr_lp, cst_idx, root_idx, 1); lpp_set_factor_fast(pi->curr_lp, cst_idx, arg_idx, -1); lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1); - /* add arg-root+y <= 1 */ + /* add arg-root-y <= 0 */ mangle_cst(buf, 'E', cst_counter++); cst_idx = lpp_add_cst(pi->curr_lp, buf, less, 0); lpp_set_factor_fast(pi->curr_lp, cst_idx, root_idx, -1); @@ -270,32 +282,75 @@ static void pi_add_constr_E(problem_instance_t *pi) { } } +/** + * Sum(y_root_arg, arg \in Args) <= max_indep_set_size - 1 + */ +static void pi_add_constr_M(problem_instance_t *pi) { + unit_t *curr; + int cst_counter = 0; + + /* for all optimization units */ + list_for_each_entry(unit_t, curr, &pi->co->units, units) { + const ir_node *root, *arg; + int rootnr, argnr; + int cst_idx, y_idx, i; + char buf[32]; + + if (curr->ifg_mis_size == curr->node_count) + continue; + + root = curr->nodes[0]; + rootnr = get_irn_graph_nr(root); + mangle_cst(buf, 'M', cst_counter++); + cst_idx = lpp_add_cst(pi->curr_lp, buf, greater, curr->node_count - curr->ifg_mis_size); + + /* for all arguments */ + for (i = 1; i < curr->node_count; ++i) { + arg = curr->nodes[i]; + argnr = get_irn_graph_nr(arg); + mangle_var(buf, 'y', rootnr, argnr); + y_idx = lpp_get_var_idx(pi->curr_lp, buf); + lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, 1); + } + } +} + /** * Generate the initial problem matrices and vectors. */ static problem_instance_t *new_pi(const copy_opt_t *co) { problem_instance_t *pi; - DBG((dbg, LEVEL_1, "Generating new instance...\n")); + DBG((dbg, LEVEL_2, "Generating new instance...\n")); pi = xcalloc(1, sizeof(*pi)); pi->co = co; pi->removed = pset_new_ptr_default(); INIT_LIST_HEAD(&pi->simplicials); pi->dilp = new_lpp(co->name, minimize); + pi->last_x_var = -1; /* problem size reduction */ pi_find_simplicials(pi); //TODO dump_ifg_w/o_removed + if (set_count(be_ra_get_ifg_nodes(pi->co->chordal_env)) == pset_count(pi->removed)) + pi->all_simplicial = 1; pi->curr_lp = pi->dilp; /* Matrix A: knapsack constraint for each node */ - dom_tree_walk_irg(co->irg, pi_add_constr_A, NULL, pi); + DBG((dbg, LEVEL_2, "Add A constraints...\n")); + dom_tree_walk_irg(co->chordal_env->irg, pi_add_constr_A, NULL, pi); /* Matrix B: interference constraints using cliques */ - for (pi->curr_color = 0; pi->curr_color < pi->co->cls->n_regs; ++pi->curr_color) - dom_tree_walk_irg(co->irg, pi_add_constr_B, NULL, pi); - /* Matrix E weights for the 'same-color-optimization' target */ + DBG((dbg, LEVEL_2, "Add B constraints...\n")); + for (pi->curr_color = 0; pi->curr_color < pi->co->chordal_env->cls->n_regs; ++pi->curr_color) + dom_tree_walk_irg(co->chordal_env->irg, pi_add_constr_B, NULL, pi); + /* Matrix E: interrelate x with y variables */ + DBG((dbg, LEVEL_2, "Add E constraints...\n")); pi_add_constr_E(pi); + /* Matrix M: maximum independent set constraints */ + DBG((dbg, LEVEL_2, "Add M constraints...\n")); + //pi_add_constr_M(pi); + return pi; } @@ -303,7 +358,7 @@ static problem_instance_t *new_pi(const copy_opt_t *co) { * Clean the problem instance */ static void free_pi(problem_instance_t *pi) { - DBG((dbg, LEVEL_1, "Free instance...\n")); + DBG((dbg, LEVEL_2, "Free instance...\n")); /* pi->simplicials get freed during apply_solution */ free_lpp(pi->dilp); del_pset(pi->removed); @@ -316,27 +371,32 @@ static void free_pi(problem_instance_t *pi) { */ static void pi_set_start_sol(problem_instance_t *pi) { int i; + char var_name[64]; + DBG((dbg, LEVEL_2, "Set start solution...\n")); for (i=1; i<=pi->last_x_var; ++i) { int nnr, col; double val; /* get variable name */ - const char *var_name = lpp_get_var_name(pi->curr_lp, i); + lpp_get_var_name(pi->curr_lp, i, var_name, sizeof(var_name)); /* split into components */ if (split_var(var_name, &nnr, &col) == 2) { - assert(get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->irg, nnr)) != -1); - val = (get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->irg, nnr)) == col) ? 1 : 0; + assert(get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr)) != -1); + val = (get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr)) == col) ? 1 : 0; lpp_set_start_value(pi->curr_lp, i, val); - } else + } else { + fprintf(stderr, "Variable name is: %s\n", var_name); assert(0 && "x vars always look like this 'x123_45'"); + } } } /** * Invoke a solver */ -static void pi_solve_ilp(problem_instance_t *pi) { +static void pi_solve_ilp(problem_instance_t *pi, void (*lpp_solve)(lpp_t *)) { pi_set_start_sol(pi); - lpp_solve(pi->curr_lp, 1); + lpp_solve(pi->curr_lp); + DBG((dbg, LEVEL_1, "Solution time: %f\n", lpp_get_sol_time(pi->curr_lp))); } /** @@ -345,8 +405,9 @@ static void pi_solve_ilp(problem_instance_t *pi) { */ static void pi_set_simplicials(problem_instance_t *pi) { simpl_t *simpl, *tmp; - bitset_t *used_cols = bitset_alloca(arch_register_class_n_regs(pi->co->cls)); + bitset_t *used_cols = bitset_alloca(arch_register_class_n_regs(pi->co->chordal_env->cls)); + DBG((dbg, LEVEL_2, "Set simplicials...\n")); /* color the simplicial nodes in right order */ list_for_each_entry_safe(simpl_t, simpl, tmp, &pi->simplicials, chain) { int free_col; @@ -355,10 +416,10 @@ static void pi_set_simplicials(problem_instance_t *pi) { /* get free color by inspecting all neighbors */ ifn = simpl->ifn; - irn = get_irn_for_graph_nr(pi->co->irg, ifn->nnr); + irn = get_irn_for_graph_nr(pi->co->chordal_env->irg, ifn->nnr); bitset_clear_all(used_cols); foreach_neighb(ifn, other) { - other_irn = get_irn_for_graph_nr(pi->co->irg, other->nnr); + other_irn = get_irn_for_graph_nr(pi->co->chordal_env->irg, other->nnr); if (!is_removed(other_irn)) /* only inspect nodes which are in graph right now */ bitset_set(used_cols, get_irn_col(pi->co, other_irn)); } @@ -377,33 +438,38 @@ static void pi_set_simplicials(problem_instance_t *pi) { * provided by the solution of the solver. */ static void pi_apply_solution(problem_instance_t *pi) { -// else if (vars_section && sscanf(buf, "x%d_%d %d", &num, &col, &val) == 3 && val == 1) { -// set_irn_col(lpp, get_irn_for_graph_nr(lpp->irg, num), col); int i; double *sol; - DBG((dbg, LEVEL_1, "Applying solution...\n")); + sol_state_t state; + DBG((dbg, LEVEL_2, "Applying solution...\n")); #ifdef DO_STAT - //TODO + //TODO stat #endif - sol = xmalloc(pi->last_x_var * sizeof(*sol)); - lpp_get_solution(pi->curr_lp, sol, 1, pi->last_x_var); + sol = xmalloc((pi->last_x_var+1) * sizeof(*sol)); + state = lpp_get_solution(pi->curr_lp, sol, 1, pi->last_x_var); + if (state != optimal) { + printf("Solution state is not 'optimal': %d\n", state); + if (state < feasible) + assert(0); + } for (i=0; ilast_x_var; ++i) - if (sol[i] == 1) { /* split varibale name into components */ + if (sol[i] == 1.0) { /* split varibale name into components */ int nnr, col; - const char *var_name = lpp_get_var_name(pi->curr_lp, 1+i); + char var_name[64]; + lpp_get_var_name(pi->curr_lp, 1+i, var_name, sizeof(var_name)); if (split_var(var_name, &nnr, &col) == 2) { DBG((dbg, LEVEL_2, " x%d = %d\n", nnr, col)); - set_irn_col(pi->co, get_irn_for_graph_nr(pi->co->irg, nnr), col); + set_irn_col(pi->co, get_irn_for_graph_nr(pi->co->chordal_env->irg, nnr), col); } else - assert(0 && "this should be a x-var"); - } - pi_set_simplicials(pi); + assert(0 && "This should be a x-var"); + } } void co_ilp_opt(copy_opt_t *co) { problem_instance_t *pi; + dbg = firm_dbg_register("ir.be.copyoptilp"); if (!strcmp(co->name, DEBUG_IRG)) firm_dbg_set_mask(dbg, -1); @@ -411,7 +477,15 @@ void co_ilp_opt(copy_opt_t *co) { firm_dbg_set_mask(dbg, DEBUG_LVL); pi = new_pi(co); - pi_solve_ilp(pi); - pi_apply_solution(pi); + if (!pi->all_simplicial) { +#ifdef DUMP_MPS + char buf[512]; + snprintf(buf, sizeof(buf), "%s.mps", co->name); + lpp_dump(pi->curr_lp, buf); +#endif + pi_solve_ilp(pi, lpp_solve_local); + pi_apply_solution(pi); + } + pi_set_simplicials(pi); free_pi(pi); } diff --git a/ir/be/becopyopt.c b/ir/be/becopyopt.c index 57b5d4dcd..0c404544e 100644 --- a/ir/be/becopyopt.c +++ b/ir/be/becopyopt.c @@ -7,6 +7,9 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifdef HAVE_ALLOCA_H +#include +#endif #include "irprog.h" @@ -18,7 +21,77 @@ #define DEBUG_LVL 0 //SET_LEVEL_1 static firm_dbg_module_t *dbg = NULL; -#define is_curr_reg_class(irn) (arch_get_irn_reg_class(co->env, irn, arch_pos_make_out(0)) == co->cls) +#define is_curr_reg_class(irn) (arch_get_irn_reg_class(co->chordal_env->arch_env, irn, arch_pos_make_out(0)) == co->chordal_env->cls) + +#define MIN(a,b) ((anode_count * sizeof(*all)); + + /* all contains all nodes */ + all_size = 0; + for (i=0; inode_count; ++i) + all[all_size++] = ou->nodes[i]; + + /* which[i] says which element to take out of all[] and put into curr[i] */ + which = alloca(all_size*sizeof(*which)); + for (curr_size=0; curr_sizeco->chordal_env, curr[i], curr[o])) + goto conflict_found; + + /* We had no conflict. This is the (one) max indep. set */ + return curr_size; + +conflict_found: + /* We had a conflict. Generate next set */ + if (which[all_size-curr_size+1] == all_size-curr_size+1) { + curr_size--; + for (i=0; i=which[i+1]) { + redo = 1; + break; + } + } + } + } + assert(0 && "How did you get here?"); +} /** * Builds an optimization unit for a given optimizable irn (root). @@ -64,13 +137,8 @@ static void co_append_unit(copy_opt_t *co, ir_node *root) { } unit->nodes = xrealloc(unit->nodes, unit->node_count * sizeof(*unit->nodes)); list_add_tail(&unit->units, &co->units); - /* Init mis_size to node_count. So get_lower_bound returns correct results. - * - Now it can be called even before the heuristic has run. - * - And it will return correct results for units with nodecount 1 which are - * not optimized during the heuristic and have therefor delivered wrong results for get_lower_bound - */ - unit->mis_size = unit->node_count; - + /* Init ifg_mis_size to node_count. So get_lower_bound returns correct results. */ + unit->ifg_mis_size = get_ifg_mis_size(unit); } static void co_collect_in_block(ir_node *block, void *env) { @@ -86,12 +154,11 @@ static void co_collect_in_block(ir_node *block, void *env) { static void co_collect_units(copy_opt_t *co) { DBG((dbg, LEVEL_1, "\tCollecting optimization units\n")); co->roots = pset_new_ptr(64); - dom_tree_walk_irg(co->irg, co_collect_in_block, NULL, co); + dom_tree_walk_irg(co->chordal_env->irg, co_collect_in_block, NULL, co); del_pset(co->roots); } -copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, - const arch_env_t *env, const arch_register_class_t *cls) { +copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env) { const char *s1, *s2, *s3; int len; copy_opt_t *co; @@ -100,15 +167,11 @@ copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, firm_dbg_set_mask(dbg, DEBUG_LVL); co = xcalloc(1, sizeof(*co)); - co->chordal_env = chordal_env; - co->irg = chordal_env->irg; - co->env = env; -// co->isa = env->isa; - co->cls = cls; + co->chordal_env = chordal_env; s1 = get_irp_prog_name(); - s2 = get_entity_name(get_irg_entity(co->irg)); - s3 = cls->name; + s2 = get_entity_name(get_irg_entity(co->chordal_env->irg)); + s3 = chordal_env->cls->name; len = strlen(s1) + strlen(s2) + strlen(s3) + 5; co->name = xmalloc(len); if (!strcmp(co->name, DEBUG_IRG)) @@ -157,7 +220,7 @@ int co_get_lower_bound(const copy_opt_t *co) { int res = 0; unit_t *curr; list_for_each_entry(unit_t, curr, &co->units, units) - res += curr->interf + curr->node_count - curr->mis_size; + res += curr->interf + curr->node_count - curr->ifg_mis_size; return res; } @@ -183,23 +246,26 @@ static void co_collect_for_checker(ir_node *block, void *env) { } /** - * This O(n^2) checker checks, if two ifg-connected nodes have the same color. + * This O(n^2) checker checks if + * two ifg-connected nodes have the same color + * register constraint are satisfied */ void co_check_allocation(copy_opt_t *co) { ir_node **nodes, *n1, *n2; int i, o; obstack_init(&co->ob); - dom_tree_walk_irg(co->irg, co_collect_for_checker, NULL, co); + dom_tree_walk_irg(co->chordal_env->irg, co_collect_for_checker, NULL, co); obstack_ptr_grow(&co->ob, NULL); nodes = (ir_node **) obstack_finish(&co->ob); for (i = 0, n1 = nodes[i]; n1; n1 = nodes[++i]) { + assert(arch_reg_is_allocatable(co->chordal_env->arch_env, n1, arch_pos_make_out(0), + arch_get_irn_register(co->chordal_env->arch_env, n1, 0)) && "Constraint does not hold"); for (o = i+1, n2 = nodes[o]; n2; n2 = nodes[++o]) if (nodes_interfere(co->chordal_env, n1, n2) && get_irn_col(co, n1) == get_irn_col(co, n2)) { - - DBG((dbg, 0, "Error: %n in %n and %n in %n have the same color.\n", n1, get_nodes_block(n1), n2, get_nodes_block(n2))); + DBG((dbg, 0, "Error: %n %d and %n %d have the same color %d.\n", n1, get_irn_graph_nr(n1), n2, get_irn_graph_nr(n2), get_irn_col(co, n1))); assert(0 && "Interfering values have the same color!"); } } diff --git a/ir/be/becopyopt.h b/ir/be/becopyopt.h index 65ae75af0..cf49abdcf 100644 --- a/ir/be/becopyopt.h +++ b/ir/be/becopyopt.h @@ -39,10 +39,7 @@ */ typedef struct _copy_opt_t { be_chordal_env_t *chordal_env; - ir_graph *irg; /**< the irg to process */ char *name; /**< ProgName__IrgName__RegClass */ - const arch_env_t *env; /**< Environment (isa + handlers) */ - const arch_register_class_t *cls; /**< the registerclass all nodes belong to (in this pass) */ struct list_head units; /**< all units to optimize in right order */ pset *roots; /**< used only temporary for detecting multiple appends */ struct obstack ob; @@ -57,25 +54,24 @@ typedef struct _unit_t { int interf; /**< number of nodes dropped due to interference */ int node_count; /**< size of the nodes array */ ir_node **nodes; /**< [0] is the root-node, others are non interfering args of it. */ + int ifg_mis_size; /**< size of a mis considering only ifg (not coloring conflicts) */ /* for heuristic */ - int mis_size; /**< size of a mis considering only ifg (not coloring conflicts) */ struct list_head queue; /**< list of (mis/color) sorted by size of mis */ } unit_t; /* Helpers */ #define set_irn_col(co, irn, col) \ - arch_set_irn_register(co->env, irn, 0, arch_register_for_index(co->cls, col)) + arch_set_irn_register(co->chordal_env->arch_env, irn, 0, arch_register_for_index(co->chordal_env->cls, col)) #define get_irn_col(co, irn) \ - arch_register_get_index(arch_get_irn_register(co->env, irn, 0)) + arch_register_get_index(arch_get_irn_register(co->chordal_env->arch_env, irn, 0)) /** * Generate the problem. Collect all infos and optimizable nodes. */ -copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, - const arch_env_t *env, const arch_register_class_t *cls); +copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env); /** * Free the space... diff --git a/ir/be/becopyoptmain.c b/ir/be/becopyoptmain.c index e00c88894..26828d80b 100644 --- a/ir/be/becopyoptmain.c +++ b/ir/be/becopyoptmain.c @@ -23,16 +23,16 @@ static firm_dbg_module_t *dbg = NULL; void be_copy_opt_init(void) { - dbg = firm_dbg_register("ir.be.copyopt"); - firm_dbg_set_mask(dbg, DEBUG_LVL); } -void be_copy_opt(be_chordal_env_t *chordal_env, - const arch_env_t *env, const arch_register_class_t *cls) { - +void be_copy_opt(be_chordal_env_t *chordal_env) { copy_opt_t *co; int lb, copies; - co = new_copy_opt(chordal_env, env, cls); + + dbg = firm_dbg_register("ir.be.copyopt"); + firm_dbg_set_mask(dbg, DEBUG_LVL); + + co = new_copy_opt(chordal_env); DBG((dbg, LEVEL_1, "\n\n ===> %s <===\n\n", co->name)); co_check_allocation(co); diff --git a/ir/be/becopyoptmain.h b/ir/be/becopyoptmain.h index e26803bcc..832a57dc6 100644 --- a/ir/be/becopyoptmain.h +++ b/ir/be/becopyoptmain.h @@ -21,7 +21,6 @@ #include "bechordal.h" void be_copy_opt_init(void); -void be_copy_opt(be_chordal_env_t *chordal_env, - const arch_env_t *env, const arch_register_class_t *cls); +void be_copy_opt(be_chordal_env_t *chordal_env); #endif diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 85c690428..0af60763c 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -29,6 +29,7 @@ #include "bearch.h" #include "becopyoptmain.h" #include "becopystat.h" +//#include "bessadestr.h" #include "bearch_firm.h" #include "benode_t.h" @@ -70,12 +71,11 @@ static void be_init_arch_env(arch_env_t *env) static void be_main_loop(void) { int i, n; - arch_env_t env; - const arch_isa_if_t *isa; + arch_env_t arch_env; + const arch_isa_if_t *isa; - be_init_arch_env(&env); - - isa = arch_env_get_isa(&env); + be_init_arch_env(&arch_env); + isa = arch_env_get_isa(&arch_env); for(i = 0, n = get_irp_n_irgs(); i < n; ++i) { int j, m; @@ -101,18 +101,19 @@ static void be_main_loop(void) #endif /* Perform the following for each register class. */ for(j = 0, m = isa->get_n_reg_class(); j < m; ++j) { - be_chordal_env_t *chordal_env; + be_chordal_env_t *chordal_env; const arch_register_class_t *cls = isa->get_reg_class(j); - chordal_env = be_ra_chordal(irg, &env, cls); + chordal_env = be_ra_chordal(irg, &arch_env, cls); #ifdef DUMP_ALLOCATED - dump_allocated_irg(&env, irg, ""); + dump_allocated_irg(&arch_env, irg, ""); #endif #ifdef DO_STAT stat_collect_irg(irg); #endif - be_copy_opt(chordal_env, &env, cls); + be_copy_opt(chordal_env); +//TODO be_ssa_destruction(chordal_env); be_ra_chordal_done(chordal_env); } #ifdef DO_STAT