Refactoring
authorDaniel Grund <grund@cs.uni-saarland.de>
Fri, 10 Mar 2006 15:17:40 +0000 (15:17 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Fri, 10 Mar 2006 15:17:40 +0000 (15:17 +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

index 98812ca..b423b2c 100644 (file)
@@ -310,7 +310,9 @@ static void be_ra_chordal_main(const be_irg_t *bi)
 #else
                {
                copy_opt_t *co = new_copy_opt(&chordal_env, co_get_costs_loop_depth);
+               co_build_ou_structure(co);
                co_solve_heuristic(co);
+               co_free_ou_structure(co);
                free_copy_opt(co);
                }
 #endif
index a064358..22be9d3 100644 (file)
@@ -67,10 +67,9 @@ void sr_remove(size_red_t *sr) {
        void *iter = be_ifg_neighbours_iter_alloca(ifg);
 
        while (redo) {
-               arch_register_req_t req;
                redo = 0;
                be_ifg_foreach_node(ifg, iter, irn) {
-                       if (!sr_is_removed(sr, irn) && !co_is_optimizable(sr->co->aenv, irn, &req) && !co_is_optimizable_arg(sr->co, irn)) {
+                       if (!sr_is_removed(sr, irn) && !co_is_optimizable_root(sr->co, irn) && !co_is_optimizable_arg(sr->co, irn)) {
                        if (sr_is_simplicial(sr, irn)) {
                                        coloring_suffix_t *cs = obstack_alloc(&sr->ob, sizeof(*cs));
 
index 1acc951..7a1af2d 100644 (file)
 #if 0 //temporary
 
 #define PATH_CONSTRAINTS_FOR_CLASSES
-#undef DUMP_MPS
-
-static firm_dbg_module_t *dbg = NULL;
-#define SLOTS_LIVING 32
 
 typedef struct _problem_instance_t {
        const copy_opt_t *co;                   /**< the copy opt problem */
@@ -77,313 +73,6 @@ typedef struct _problem_instance_t {
                        sscanf(var, "x%d_%d", (nnr), (col))
 
 
-/**
- * Add coloring-force conditions
- * Matrix A: knapsack constraint for each node
- */
-static void pi_add_constr_A(problem_instance_t *pi) {
-       pmap_entry *pme;
-
-       DBG((dbg, LEVEL_2, "Add A constraints...\n"));
-       /* iterate over all blocks */
-       pmap_foreach(pi->co->cenv->border_heads, pme) {
-               struct list_head *head = pme->value;
-               border_t *curr;
-               bitset_t *pos_regs = bitset_alloca(pi->co->cenv->cls->n_regs);
-
-               list_for_each_entry_reverse(border_t, curr, head, list)
-                       if (curr->is_def && curr->is_real && !sr_is_removed(pi->sr->curr->irn)) {
-                               int cst_idx, nnr, col;
-
-                               nnr = get_irn_graph_nr(curr->irn);
-                               mangle_cst(pi->buf, 'A', nnr);
-                               cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_equal, 1);
-
-                               /* iterate over all possible colors in order */
-                               bitset_clear_all(pos_regs);
-                               arch_get_allocatable_regs(pi->co->aenv, curr->irn, -1, pos_regs);
-                               bitset_foreach(pos_regs, col) {
-                                       int var_idx;
-                                       mangle_var2(pi->buf, 'x', nnr, col);
-                                       var_idx = lpp_add_var(pi->curr_lp, pi->buf, lpp_binary, 0);
-                                       if (!pi->first_x_var)
-                                               pi->first_x_var = var_idx;
-                                       pi->last_x_var = var_idx;
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
-                               }
-                       }
-       }
-}
-
-/**
- * Checks if all nodes in @p living are live in in block @p block.
- * @return 1 if all are live in
- *         0 else
- */
-static INLINE int all_live_in(ir_node *block, pset *living) {
-       ir_node *n;
-       for (n = pset_first(living); n; n = pset_next(living))
-               if (!is_live_in(block, n)) {
-                       pset_break(living);
-                       return 0;
-               }
-       return 1;
-}
-
-/**
- * Finds cliques in the interference graph, considering only nodes
- * for which the color @p color is possible. Finds only 'maximal-cliques',
- * viz cliques which are not contained in another one.
- * Matrix B: interference constraints using cliques
- */
-static void pi_add_constr_B(problem_instance_t *pi, int color) {
-       enum phase_t {growing, shrinking} phase = growing;
-       border_t *b;
-       pmap_entry *pme;
-       pset *living = pset_new_ptr(SLOTS_LIVING);
-
-       DBG((dbg, LEVEL_2, "Add B constraints (col = %d)...\n", color));
-       /* iterate over all blocks */
-       pmap_foreach(pi->co->cenv->border_heads, pme) {
-               ir_node *block = pme->key;
-               struct list_head *head = pme->value;
-
-               list_for_each_entry_reverse(border_t, b, head, list) {
-                       const ir_node *irn = b->irn;
-                       if (is_removed(irn) || !is_color_possible(irn, color))
-                               continue;
-
-                       if (b->is_def) {
-                               DBG((dbg, LEVEL_2, "Def %n\n", irn));
-                               pset_insert_ptr(living, irn);
-                               phase = growing;
-                       } else { /* is_use */
-                               DBG((dbg, LEVEL_2, "Use %n\n", irn));
-
-                               /* before shrinking the set, store the current 'maximum' clique;
-                                * do NOT if clique is a single node
-                                * do NOT if all values are live_in (in this case they were contained in a live-out clique elsewhere) */
-                               if (phase == growing && pset_count(living) >= 2 && !all_live_in(block, living)) {
-                                       int cst_idx;
-                                       ir_node *n;
-                                       mangle_cst(pi->buf, 'B', pi->cst_counter);
-                                       cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_less, 1);
-                                       for (n = pset_first(living); n; n = pset_next(living)) {
-                                               int var_idx;
-                                               mangle_var_irn(pi->buf, 'x', n, color);
-                                               var_idx = lpp_get_var_idx(pi->curr_lp, pi->buf);
-                                               lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
-                                       }
-                                       pi->cst_counter++;
-                               }
-                               pset_remove_ptr(living, irn);
-                               phase = shrinking;
-                       }
-               }
-       }
-       assert(0 == pset_count(living));
-       del_pset(living);
-}
-
-/**
- * Generates constraints which interrelate x with y variables.
- * x1 and x2 have the different colors ==> y_12 = 1
- */
-static void pi_add_constr_E(problem_instance_t *pi) {
-       unit_t *curr;
-       bitset_t *root_regs, *arg_regs, *work_regs;
-       int cst_counter = 0;
-       unsigned nregs = pi->co->cenv->cls->n_regs;
-       root_regs = bitset_alloca(nregs);
-       arg_regs = bitset_alloca(nregs);
-       work_regs = bitset_alloca(nregs);
-
-       DBG((dbg, LEVEL_2, "Add E constraints...\n"));
-       /* for all roots of optimization units */
-       list_for_each_entry(unit_t, curr, &pi->co->units, units) {
-               ir_node *root, *arg;
-               int rootnr, argnr, color;
-               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->aenv, root, -1, 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->aenv, arg, -1, arg_regs);
-
-                       /* Introduce new variable and set factor in objective function */
-                       mangle_var2(buf, 'y', rootnr, argnr);
-                       y_idx = lpp_add_var(pi->curr_lp, buf, lpp_binary, curr->costs[i]);
-
-                       /* 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_copy(work_regs, root_regs);
-                       bitset_and(work_regs, arg_regs);
-                       bitset_foreach(work_regs, color) {
-                               int root_idx, arg_idx, cst_idx;
-                               mangle_var2(buf, 'x', rootnr, color);
-                               root_idx = lpp_get_var_idx(pi->curr_lp, buf);
-                               mangle_var2(buf, 'x', argnr, color);
-                               arg_idx = lpp_get_var_idx(pi->curr_lp, buf);
-
-                               /* add root-arg-y <= 0 */
-                               mangle_cst(buf, 'E', cst_counter++);
-                               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_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 <= 0 */
-                               mangle_cst(buf, 'E', cst_counter++);
-                               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_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);
-                       }
-                       /* For all colors root and arg have "disjunct", add 1 constraints to E.
-                        * If root gets a color the arg is not possible to get then they will
-                        * definetly get different colors. So y has to be 1.
-                        * Vice versa for arg.
-                        */
-                       bitset_copy(work_regs, root_regs);
-                       bitset_xor(work_regs, arg_regs);
-                       bitset_foreach(work_regs, color) {
-                               int root_idx, arg_idx, cst_idx;
-                               mangle_var2(buf, 'x', rootnr, color);
-                               root_idx = lpp_get_var_idx(pi->curr_lp, buf);
-                               mangle_var2(buf, 'x', argnr, color);
-                               arg_idx = lpp_get_var_idx(pi->curr_lp, buf);
-
-                               mangle_cst(buf, 'E', cst_counter++);
-                               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_less, 0);
-                               if (bitset_is_set(root_regs, color)) {
-                                       /* add root-y <= 0 */
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, root_idx, 1);
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1);
-                               } else {
-                                       assert(bitset_is_set(arg_regs, color) && "bitset_xor is buggy");
-                                       /* add arg-y <= 0 */
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, arg_idx, 1);
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1);
-                               }
-                       }
-               }
-       }
-}
-
-static void clique_path_walker(ir_node *block, void *env) {
-       problem_instance_t *pi = env;
-       int count, arity, row, col, other_row, *costs;
-       ir_node **phis, *phi, *irn, **phi_matrix;
-       pset *done;
-       bitset_t *candidates;
-
-       /* Count all phi nodes of this block */
-       for (count=0, irn = sched_first(block); is_Phi(irn); irn = sched_next(irn))
-               count++;
-
-       /* We at least 2 phi nodes for this class of inequalities */
-       if (count < 2)
-               return;
-
-       /* Build the \Phi-Matrix */
-       arity = get_irn_arity(sched_first(block));
-       phis = alloca(count * sizeof(*phis));
-       costs = alloca(count * sizeof(costs));
-       phi_matrix = alloca(count*arity * sizeof(*phi_matrix));
-       candidates = bitset_alloca(count);
-
-       phi = sched_first(block);
-       for (row=0; row<count; ++row) {
-               phis[row] = phi;
-               for (col=0; col<arity; ++col) {
-                       ir_node *arg = get_irn_n(phi, col);
-                       /* Sort out all arguments interfering with its phi */
-                       if (nodes_interfere(pi->co->cenv, phi, arg)) {
-                               phi_matrix[row*arity + col] =  NULL;
-                       } else
-                               phi_matrix[row*arity + col] =  arg;
-               }
-               phi = sched_next(phi);
-       }
-
-       /* Now find the interesting patterns in the matrix:
-        * All nodes which are used at least twice in a column. */
-       /* columnwise ... */
-       for (col=0; col<arity; ++col) {
-               done = pset_new_ptr_default();
-               for (row=0; row<count; ++row) {
-                       irn = phi_matrix[row*arity + col];
-                       /*
-                        * is this an interfering arg (NULL)
-                        * or has the irn already been processed in this col?
-                        */
-                       if (!irn || pset_find_ptr(done, irn))
-                               continue;
-                       else
-                               pset_insert_ptr(done, irn);
-
-                       /* insert irn in candidates */
-                       bitset_clear_all(candidates);
-                       bitset_set(candidates, row);
-                       /* search the irn in the rows below */
-                       for (other_row = row+1; other_row<count; ++other_row)
-                               if (irn == phi_matrix[other_row*arity + col]) {
-                                       /* found the irn in the same col in another row */
-                                       bitset_set(candidates, other_row);
-                               }
-
-                       /* now we know all occurences of irn in this col */
-                       if (bitset_popcnt(candidates) < 2)
-                               continue;
-
-                       /* generate an unequation finally.
-                        * phis are indexed in the bitset,
-                        * shared argument is irn
-                        * rhs is phi_count - 1 */
-                       {
-                               char buf[32];
-                               ir_node *root;
-                               int pos, irnnr, rootnr, cst_idx, y_idx, cst_counter = 0;
-                               int minimal_unequal_count = bitset_popcnt(candidates)-1;
-
-                               irnnr = get_irn_graph_nr(irn);
-                               mangle_cst(buf, 'M', cst_counter++);
-                               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, minimal_unequal_count);
-
-                               /* for all phis */
-                               bitset_foreach(candidates, pos) {
-                                       root = phis[pos];
-                                       rootnr = get_irn_graph_nr(root);
-                                       mangle_var2(buf, 'y', rootnr, irnnr);
-                                       y_idx = lpp_get_var_idx(pi->curr_lp, buf);
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, 1);
-                               }
-                       }
-               }
-               del_pset(done); /* clear set for next row */
-       } /*next col*/
-}
-
-/**
- * Matrix M: Multi-Arg-Use. Interrelates different \phi-functions
- * in the same block, iff they use the same arg at the same pos.
- * Only one of the phis can get the arg.
- */
-static void pi_add_clique_path_cstr(problem_instance_t *pi) {
-       DBG((dbg, LEVEL_2, "Adding clique path constraints...\n"));
-       dom_tree_walk_irg(pi->co->irg, clique_path_walker, NULL, pi);
-}
-
 #ifndef PATH_CONSTRAINTS_FOR_CLASSES
 /**
  * Matrix P: Path contraints.
@@ -578,163 +267,11 @@ static void pi_add_path_cstr_for_classes(problem_instance_t *pi) {
 }
 #endif
 
-
-
-/**
- * Generate the initial problem matrices and vectors.
- */
-static problem_instance_t *new_pi(const copy_opt_t *co) {
-       problem_instance_t *pi;
-       int col;
-
-       DBG((dbg, LEVEL_2, "Generating new instance...\n"));
-       pi = xcalloc(1, sizeof(*pi));
-       pi->co  = co;
-       pi->sr  = new_size_red(co);
-       pi->lp  = new_lpp(co->name, lpp_minimize);
-
-       return pi;
-}
-
 static void pi_construct(problem_instance_t *pi) {
-       pi_add_constr_A(pi);
-       for (col = 0; col < pi->co->cls->n_regs; ++col)
-               pi_add_constr_B(pi, col);
-       pi_add_constr_E(pi);
-
-#ifdef PATH_CONSTRAINTS_FOR_CLASSES
        pi_add_path_cstr_for_classes(pi);
-#else
        pi_add_path_cstr(pi);
-#endif
        pi_add_clique_path_cstr(pi);
 }
-
-/**
- * Clean the problem instance
- */
-static void free_pi(problem_instance_t *pi) {
-       simpl_t *simpl, *tmp;
-
-       DBG((dbg, LEVEL_2, "Free instance...\n"));
-       free_lpp(pi->lp);
-       free_size_red(pi->sr);
-       free(pi);
-}
-
-
-/**
- * Set starting values for the mip problem according
- * to the current coloring of the graph.
- */
-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=pi->first_x_var; i<=pi->last_x_var; ++i) {
-               int nnr, col;
-               double val;
-               /* get variable name */
-               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;
-                       lpp_set_start_value(pi->curr_lp, i, val);
-               } 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, double time_limit) {
-       double lower_bound;
-#ifdef DUMP_MPS
-       char buf[512];
-       snprintf(buf, sizeof(buf), "%s.ilp1", co->name);
-       lpp_dump(pi->lp, buf);
-#endif
-
-       pi_set_start_sol(pi);
-
-       lower_bound = co_get_lower_bound(pi->co) - co_get_inevit_copy_costs(pi->co);
-       lpp_set_bound(pi->curr_lp, lower_bound);
-
-       lpp_set_time_limit(pi->curr_lp, time_limit);
-
-#ifdef LPP_SOLVE_REMOTE
-       lpp_solve_net(pi->curr_lp, LPP_HOST, LPP_SOLVER);
-#else
-       lpp_solve_cplex(pi->curr_lp);
-#endif
-       DBG((dbg, LEVEL_1, "Solution time: %.2f\n", pi->curr_lp->sol_time));
-}
-
-
-/**
- * Sets the colors of irns according to the values of variables
- * provided by the solution of the solver.
- */
-static int pi_apply_solution(problem_instance_t *pi) {
-       int res = 1, i;
-       double *sol;
-       lpp_sol_state_t state;
-       DBG((dbg, LEVEL_2, "Applying solution...\n"));
-
-#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));
-       copystat_add_ilp_iter(lpp_get_iter_cnt(pi->curr_lp));
-#endif
-
-       sol = xmalloc((pi->last_x_var - pi->first_x_var + 1) * sizeof(*sol));
-       state = lpp_get_solution(pi->curr_lp, sol, pi->first_x_var, pi->last_x_var);
-       if (state != lpp_optimal) {
-               printf("WARNING %s: Solution state is not 'optimal': %d\n", pi->co->name, state);
-               assert(state >= lpp_feasible && "The solution should at least be feasible!");
-               res = 0;
-       }
-       for (i=0; i<pi->last_x_var - pi->first_x_var + 1; ++i) {
-               int nnr, col;
-               char var_name[64];
-
-               if (sol[i] > 1-EPSILON) { /* split varibale name into components */
-                       lpp_get_var_name(pi->curr_lp, pi->first_x_var+i, var_name, sizeof(var_name));
-                       if (split_var(var_name, &nnr, &col) == 2) {
-                               DBG((dbg, LEVEL_2, "Irn %n  Idx %d  Var %s  Val %f\n", get_irn_for_graph_nr(pi->co->irg, nnr), i, var_name, sol[i]));
-                               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);
-                       } else
-                               assert(0 && "This should be a x-var");
-               }
-       }
-       return res;
-}
-
-
-int co_solve_ilp11(copy_opt_t *co, double time_limit) {
-       int res = 1;
-       problem_instance_t *pi;
-
-       dbg = firm_dbg_register("ir.be.copyoptilp1");
-
-       pi = new_pi(co);
-
-       sr_remove(pi->sr);                              /* problem size reduction */
-       pi_construct(pi);                               /* set up the problem */
-       pi_solve_ilp(pi, time_limit);   /* solve it */
-       res = pi_apply_solution(pi);    /* apply solution */
-       sr_reinsert(pi->sr);                    /* complete the partial solution */
-
-       free_pi(pi);
-       return res;
-}
 #endif
 
 #include "becopyilp_t.h"
@@ -756,22 +293,7 @@ static void ilp1_apply(ilp_env_t *ienv) {
 }
 
 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.coilp1");
-
-       firm_dbg_set_mask(dbg, DEBUG_LVL);
-
-       // my.bla = TODO
-
-       ienv = new_ilp_env(co, ilp1_build, ilp1_apply, &my);
-
-       sol_state = ilp_go(ienv);
-
-       free_ilp_env(ienv);
-
-       return sol_state == lpp_optimal;
+       return 1;
 }
 
 
index 18be998..93cb741 100644 (file)
@@ -4,25 +4,26 @@
  * Copyright:   (c) Universitaet Karlsruhe
  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
  *
+ *
  * ILP formalization using G=(V, E, Q):
- *  - 1 class of variables: equal color vars
+ *  - 2 class of variables: coloring vars x_ic   and   equal color vars y_ij
  *  - Path constraints
- *  - Clique path constraints
+ *  - Clique-star constraints
  *
  *
  *     \min \sum_{ (i,j) \in Q }  w_ij y_ij
  *
- *             y_ij                            =  1                    (i,j) \in E
+ *             \sum_c x_nc                     =  1                    n \in N, c \in C
  *
- *             \sum_c y_nc                     =  |C| - 1              n \in N, c \in C
+ *             x_nc                            =  0                    n \in N, c \not\in C(n)
  *
- *             y_nc                            =  1                    n \in N, c \not\in C(n)
+ *             \sum x_nc                       <= 1                    x_nc \in Clique \in AllCliques,  c \in C
  *
  *             \sum_{e \in p} y_e      >= 1                    p \in P         path constraints
  *
- *             \sum_{e \in cp} y_e     >= |cp| - 1             cp \in CP       clique-path constraints
+ *             \sum_{e \in cs} y_e     >= |cs| - 1             cs \in CP       clique-star constraints
  *
- *             y_ij \in N,   w_ij \in R^+
+ *             x_nc, y_ij \in N,   w_ij \in R^+
  */
 
 #ifdef HAVE_CONFIG_H
 
 #ifdef WITH_ILP
 
+#include "irtools.h"
+#include "irgwalk.h"
 #include "becopyilp_t.h"
 #include "beifg_t.h"
-#include "irtools.h"
+#include "besched_t.h"
 
 #define DEBUG_LVL 1
 
@@ -169,11 +172,17 @@ static void build_affinity_cstr(ilp_env_t *ienv) {
        }
 }
 
-static void build_path_cstr(ilp_env_t *ienv) {
+/**
+ *
+ */
+static void build_clique_star_cstr(ilp_env_t *ienv) {
 
 }
 
-static void build_clique_path_cstr(ilp_env_t *ienv) {
+/**
+ *
+ */
+static void build_path_cstr(ilp_env_t *ienv) {
 
 }
 
@@ -185,8 +194,8 @@ static void ilp2_build(ilp_env_t *ienv) {
        build_coloring_cstr(ienv);
        build_interference_cstr(ienv);
        build_affinity_cstr(ienv);
+       build_clique_star_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);
index 5d5600c..f2454b6 100644 (file)
@@ -134,7 +134,6 @@ struct _ilp_env_t {
        void *env;
        ilp_callback build;
        ilp_callback apply;
-
 };
 
 ilp_env_t *new_ilp_env(copy_opt_t *co, ilp_callback build, ilp_callback apply, void *env);
index 06142dc..3526c17 100644 (file)
 
 #include "bearch.h"
 #include "beutil.h"
+#include "beifg_t.h"
 #include "becopyopt_t.h"
 #include "becopystat.h"
 
+/******************************************************************************
+    _____                           _
+   / ____|                         | |
+  | |  __  ___ _ __   ___ _ __ __ _| |
+  | | |_ |/ _ \ '_ \ / _ \ '__/ _` | |
+  | |__| |  __/ | | |  __/ | | (_| | |
+   \_____|\___|_| |_|\___|_|  \__,_|_|
+
+ ******************************************************************************/
 
 static firm_dbg_module_t *dbg = NULL;
 
+void be_copy_opt_init(void) {
+}
+
+copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, int (*get_costs)(ir_node*, ir_node*, int)) {
+       const char *s1, *s2, *s3;
+       int len;
+       copy_opt_t *co;
+
+       dbg = firm_dbg_register("ir.be.copyopt");
+
+       co = xcalloc(1, sizeof(*co));
+       co->cenv      = chordal_env;
+       co->aenv      = chordal_env->birg->main_env->arch_env;
+       co->irg       = chordal_env->irg;
+       co->cls       = chordal_env->cls;
+       co->get_costs = get_costs;
+
+       s1 = get_irp_prog_name();
+       s2 = get_entity_name(get_irg_entity(co->irg));
+       s3 = chordal_env->cls->name;
+       len = strlen(s1) + strlen(s2) + strlen(s3) + 5;
+       co->name = xmalloc(len);
+       snprintf(co->name, len, "%s__%s__%s", s1, s2, s3);
+
+       return co;
+}
+
+void free_copy_opt(copy_opt_t *co) {
+       xfree(co->name);
+}
+
+int co_is_optimizable_root(const copy_opt_t *co, ir_node *irn) {
+       arch_register_req_t req;
+
+       if (arch_irn_is_ignore(co->aenv, irn))
+               return 0;
+
+       if (is_Reg_Phi(irn) || is_Perm_Proj(co->aenv, irn) || is_2addr_code(co->aenv, irn, &req))
+               return 1;
+
+       return 0;
+}
+
+int co_is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
+       const ir_edge_t *edge;
+
+       if (arch_irn_is_ignore(co->aenv, irn))
+               return 0;
+
+       foreach_out_edge(irn, edge) {
+               ir_node *n = edge->src;
+
+               if (!nodes_interfere(co->cenv, irn, n) || irn == n) {
+                       arch_register_req_t req;
+                       arch_get_register_req(co->aenv, &req, n, -1);
+
+                       if(is_Reg_Phi(n) ||
+                          is_Perm(co->aenv, n) ||
+                          (arch_register_req_is(&req, should_be_same) && req.other_same == irn)
+                         )
+                               return 1;
+               }
+       }
+
+       return 0;
+}
+
+int co_get_costs_loop_depth(ir_node *root, ir_node* arg, int pos) {
+       int cost = 0;
+       ir_loop *loop;
+       ir_node *root_block = get_nodes_block(root);
+
+       if (is_Phi(root)) {
+               /* for phis the copies are placed in the corresponding pred-block */
+               loop = get_irn_loop(get_Block_cfgpred_block(root_block, pos));
+       } else {
+               /* a perm places the copy in the same block as it resides */
+               loop = get_irn_loop(root_block);
+       }
+       if (loop) {
+               int d = get_loop_depth(loop);
+               cost = d*d;
+       }
+       return cost+1;
+}
+
+int co_get_costs_all_one(ir_node *root, ir_node* arg, int pos) {
+       return 1;
+}
+
+/******************************************************************************
+   ____        _   _    _       _ _          _____ _
+  / __ \      | | | |  | |     (_) |        / ____| |
+ | |  | |_ __ | |_| |  | |_ __  _| |_ ___  | (___ | |_ ___  _ __ __ _  __ _  ___
+ | |  | | '_ \| __| |  | | '_ \| | __/ __|  \___ \| __/ _ \| '__/ _` |/ _` |/ _ \
+ | |__| | |_) | |_| |__| | | | | | |_\__ \  ____) | || (_) | | | (_| | (_| |  __/
+  \____/| .__/ \__|\____/|_| |_|_|\__|___/ |_____/ \__\___/|_|  \__,_|\__, |\___|
+        | |                                                            __/ |
+        |_|                                                           |___/
+ ******************************************************************************/
+
 /**
  * Determines a maximum weighted independent set with respect to
  * the interference and conflict edges of all nodes in a qnode.
@@ -126,7 +237,7 @@ static void co_collect_units(ir_node *irn, void *env) {
 
        if (!is_curr_reg_class(co, irn))
                return;
-       if (!co_is_optimizable(co->aenv, irn, &req))
+       if (!co_is_optimizable_root(co, irn))
                return;
 
        /* Init a new unit */
@@ -185,12 +296,12 @@ static void co_collect_units(ir_node *irn, void *env) {
 
        /* Proj of a perm with corresponding arg */
        if (is_Perm_Proj(co->aenv, irn)) {
-               assert(!nodes_interfere(co->cenv, irn, get_Copy_src(irn)));
+               assert(!nodes_interfere(co->cenv, irn, get_Perm_src(irn)));
                unit->nodes = xmalloc(2 * sizeof(*unit->nodes));
                unit->costs = xmalloc(2 * sizeof(*unit->costs));
                unit->node_count = 2;
                unit->nodes[0] = irn;
-               unit->nodes[1] = get_Copy_src(irn);
+               unit->nodes[1] = get_Perm_src(irn);
                unit->costs[1] = co->get_costs(irn, unit->nodes[1], -1);
        } else
 
@@ -232,40 +343,14 @@ static void co_collect_units(ir_node *irn, void *env) {
        }
 }
 
-void be_copy_opt_init(void) {
-       dbg = firm_dbg_register("ir.be.copyoptmain");
-}
-
-copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, int (*get_costs)(ir_node*, ir_node*, int)) {
-       const char *s1, *s2, *s3;
-       int len;
-       copy_opt_t *co;
-
-       dbg = firm_dbg_register("ir.be.copyopt");
-
-       co = xcalloc(1, sizeof(*co));
-       co->cenv = chordal_env;
-       co->aenv = chordal_env->birg->main_env->arch_env;
-       co->irg = chordal_env->irg;
-       co->cls = chordal_env->cls;
-       co->get_costs = get_costs;
-
-       s1 = get_irp_prog_name();
-       s2 = get_entity_name(get_irg_entity(co->irg));
-       s3 = chordal_env->cls->name;
-       len = strlen(s1) + strlen(s2) + strlen(s3) + 5;
-       co->name = xmalloc(len);
-       snprintf(co->name, len, "%s__%s__%s", s1, s2, s3);
-
+void co_build_ou_structure(copy_opt_t *co) {
        DBG((dbg, LEVEL_1, "\tCollecting optimization units\n"));
        INIT_LIST_HEAD(&co->units);
        irg_walk_graph(co->irg, co_collect_units, NULL, co);
-       return co;
 }
 
-void free_copy_opt(copy_opt_t *co) {
+void co_free_ou_structure(copy_opt_t *co) {
        unit_t *curr, *tmp;
-       xfree(co->name);
        list_for_each_entry_safe(unit_t, curr, tmp, &co->units, units) {
                xfree(curr->nodes);
                xfree(curr->costs);
@@ -273,52 +358,7 @@ void free_copy_opt(copy_opt_t *co) {
        }
 }
 
-int co_is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
-       const ir_edge_t *edge;
-
-       if (arch_irn_is_ignore(co->aenv, irn))
-               return 0;
-
-       foreach_out_edge(irn, edge) {
-               ir_node *n = edge->src;
-
-               if (!nodes_interfere(co->cenv, irn, n) || irn == n) {
-                       arch_register_req_t req;
-                       arch_get_register_req(co->aenv, &req, n, -1);
-
-                       if(is_Reg_Phi(n) ||
-                          is_Perm(co->aenv, n) ||
-                          (arch_register_req_is(&req, should_be_same) && req.other_same == irn)
-                         )
-                               return 1;
-               }
-       }
-
-       return 0;
-}
-
-int co_get_costs_loop_depth(ir_node *root, ir_node* arg, int pos) {
-       int cost = 0;
-       ir_loop *loop;
-       ir_node *root_block = get_nodes_block(root);
-
-       if (is_Phi(root)) {
-               /* for phis the copies are placed in the corresponding pred-block */
-               loop = get_irn_loop(get_Block_cfgpred_block(root_block, pos));
-       } else {
-               /* a perm places the copy in the same block as it resides */
-               loop = get_irn_loop(root_block);
-       }
-       if (loop) {
-               int d = get_loop_depth(loop);
-               cost = d*d;
-       }
-       return cost+1;
-}
-
-int co_get_costs_all_one(ir_node *root, ir_node* arg, int pos) {
-       return 1;
-}
+/* co_solve_heuristic() is implemented in becopyheur.c */
 
 int co_get_max_copy_costs(const copy_opt_t *co) {
        int i, res = 0;
@@ -367,3 +407,107 @@ int co_get_lower_bound(const copy_opt_t *co) {
                res += curr->inevitable_costs + curr->min_nodes_costs;
        return res;
 }
+
+/******************************************************************************
+   _____                 _        _____ _
+  / ____|               | |      / ____| |
+ | |  __ _ __ __ _ _ __ | |__   | (___ | |_ ___  _ __ __ _  __ _  ___
+ | | |_ | '__/ _` | '_ \| '_ \   \___ \| __/ _ \| '__/ _` |/ _` |/ _ \
+ | |__| | | | (_| | |_) | | | |  ____) | || (_) | | | (_| | (_| |  __/
+  \_____|_|  \__,_| .__/|_| |_| |_____/ \__\___/|_|  \__,_|\__, |\___|
+                  | |                                       __/ |
+                  |_|                                      |___/
+ ******************************************************************************/
+
+static int compare_node_t(const void *k1, const void *k2, size_t size) {
+       const node_t *n1 = k1;
+       const node_t *n2 = k2;
+
+       return (n1->irn != n2->irn);
+}
+
+static void add_edge(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs) {
+       node_t new_node, *node;
+       neighb_t new_nbr, *nbr;
+       int allocnew;
+
+       new_node.irn        = n1;
+       new_node.count      = 0;
+       new_node.neighbours = NULL;
+       node = set_insert(co->nodes, new_node.irn, sizeof(new_node), HASH_PTR(new_node.irn));
+
+       allocnew = 1;
+       for (nbr = node->neighbours; nbr; nbr = nbr->next)
+               if (nbr->irn == n2) {
+                       allocnew = 0;
+                       break;
+               }
+
+       /* if we did not find n2 in n1's neighbourhood insert it */
+       if (allocnew) {
+               obstack_grow(&co->obst, &new_nbr, sizeof(new_nbr));
+               nbr = obstack_finish(&co->obst);
+               nbr->irn   = n2;
+               nbr->costs = 0;
+               nbr->next  = node->neighbours;
+               node->neighbours = nbr;
+               node->count++;
+       }
+
+       /* now nbr points to n1's neighbour-entry of n2 */
+       nbr->costs += costs;
+}
+
+static INLINE void add_edges(copy_opt_t *co, ir_node *n1, ir_node *n2, int costs) {
+       if (! be_ifg_connected(co->cenv->ifg, n1, n2)) {
+               add_edge(co, n1, n2, costs);
+               add_edge(co, n2, n1, costs);
+       }
+}
+
+static void build_graph_walker(ir_node *irn, void *env) {
+       copy_opt_t *co = env;
+       int pos, max;
+       arch_register_req_t req;
+
+       if (!is_curr_reg_class(co, irn) || arch_irn_is_ignore(co->aenv, irn))
+               return;
+
+       /* Phis */
+       if (is_Reg_Phi(irn))
+               for (pos=0, max=get_irn_arity(irn); pos<max; ++pos) {
+                       ir_node *arg = get_irn_n(irn, pos);
+                       add_edges(co, irn, arg, co->get_costs(irn, arg, pos));
+               }
+
+       /* Perms */
+       else if (is_Perm_Proj(co->aenv, irn)) {
+               ir_node *arg = get_Perm_src(irn);
+               add_edges(co, irn, arg, co->get_costs(irn, arg, 0));
+       }
+
+       /* 2-address code */
+       else if (is_2addr_code(co->aenv, irn, &req))
+               add_edges(co, irn, req.other_same, co->get_costs(irn, req.other_same, 0));
+}
+
+void co_build_graph_structure(copy_opt_t *co) {
+       obstack_init(&co->obst);
+       co->nodes = new_set(compare_node_t, 32);
+
+       irg_walk_graph(co->irg, build_graph_walker, NULL, co);
+}
+
+void co_free_graph_structure(copy_opt_t *co) {
+       del_set(co->nodes);
+       obstack_free(&co->obst, NULL);
+}
+
+/* co_solve_ilp1() co_solve_ilp2() are implemented in becopyilpX.c */
+
+int co_gs_is_optimizable(copy_opt_t *co, ir_node *irn) {
+       node_t new_node;
+
+       new_node.irn        = irn;
+       return (int)set_find(co->nodes, new_node.irn, sizeof(new_node), HASH_PTR(new_node.irn));
+}
index 61abf81..93dc762 100644 (file)
 #include "irnode.h"
 #include "bechordal.h"
 
-
-typedef int(*cost_fct_t)(ir_node*, ir_node*, int);
-
-typedef struct _copy_opt_t copy_opt_t;
-
 /**
  * Has to be called during the firm init phase
  */
 void be_copy_opt_init(void);
 
+typedef int(*cost_fct_t)(ir_node*, ir_node*, int);
+
+typedef struct _copy_opt_t copy_opt_t;
+
 /**
  * Generate the problem. Collect all information and optimizable nodes.
  */
@@ -36,6 +35,19 @@ copy_opt_t *new_copy_opt(be_chordal_env_t *chordal_env, cost_fct_t get_costs);
  */
 void free_copy_opt(copy_opt_t *co);
 
+/**
+ * Checks if a node is optimizable, viz. has somthing to do with coalescing
+ * @param arch The architecture environment
+ * @param irn  The irn to check
+ * @param req  A register_requirement structure (used to check for 2-addr-code)
+ */
+int co_is_optimizable_root(const copy_opt_t *co, ir_node *irn);
+
+/**
+ * Checks if the irn is a non-interfering argument of a node which 'is_optimizable'
+ */
+int co_is_optimizable_arg(const copy_opt_t *co, ir_node *irn);
+
 /**
  * Computes the costs of a copy according to loop depth
  * @param pos: the argument position of arg in the root arguments
@@ -49,11 +61,66 @@ int co_get_costs_loop_depth(ir_node *root, ir_node* arg, int pos);
  */
 int co_get_costs_all_one(ir_node *root, ir_node* arg, int pos);
 
+
+
+
+/**
+ * Build internal optimization units structure
+ */
+void co_build_ou_structure(copy_opt_t *co);
+
+/**
+ * Frees the space used by the opt unit representation.
+ * Does NOT free the whole copyopt structure
+ */
+void co_free_ou_structure(copy_opt_t *co);
+
 /**
  * Solves the problem using a heuristic approach
  */
 int co_solve_heuristic(copy_opt_t *co);
 
+/**
+ * Returns the maximal costs possible, i.e. the costs if all
+ * pairs would be assigned different registers.
+ */
+int co_get_max_copy_costs(const copy_opt_t *co);
+
+/**
+ * Returns the inevitable costs, i.e. the costs of
+ * all copy pairs which interfere.
+ */
+int co_get_inevit_copy_costs(const copy_opt_t *co);
+
+/**
+ * Returns the current costs the copies are causing.
+ * The result includes inevitable costs and the costs
+ * of the copies regarding the current register allocation
+ */
+int co_get_copy_costs(const copy_opt_t *co);
+
+/**
+ * Returns a lower bound for the costs of copies in this ou.
+ * The result includes inevitable costs and the costs of a
+ * minimal costs caused by the nodes of the ou.
+ */
+int co_get_lower_bound(const copy_opt_t *co);
+
+
+
+
+
+/**
+ * Constructs another internal representation of the affinity edges
+ */
+void co_build_graph_structure(copy_opt_t *co);
+
+/**
+ * Frees the space used by the graph representation.
+ * Does NOT free the whole copyopt structure
+ */
+void co_free_graph_structure(copy_opt_t *co);
+
 /**
  * Solves the problem using mixed integer programming
  * @returns 1 iff solution state was optimal
@@ -66,4 +133,10 @@ int co_solve_ilp1(copy_opt_t *co, double time_limit);
  */
 int co_solve_ilp2(copy_opt_t *co, double time_limit);
 
+/**
+ * Checks if a node is optimizable, viz. has somthing to do with coalescing.
+ * Uses the graph representation
+ */
+int co_gs_is_optimizable(copy_opt_t *co, ir_node *irn);
+
 #endif
index d899e6c..9d16e88 100644 (file)
 #ifndef _BECOPYOPT_T_H
 #define _BECOPYOPT_T_H
 
+#include <obstack.h>
 #include "list.h"
 #include "bearch.h"
 #include "bechordal_t.h"
 #include "becopyopt.h"
 
-#define MIS_HEUR_TRIGGER 8
-
 /**
  * Data representing the problem of copy minimization.
  */
@@ -26,15 +25,48 @@ struct _copy_opt_t {
        const arch_env_t *aenv;
        ir_graph *irg;
        char *name;                                             /**< ProgName__IrgName__RegClassName */
+       cost_fct_t get_costs;                   /**< function ptr used to get costs for copies */
 
+       /** Representation as optimization units */
        struct list_head units;                 /**< all units to optimize in specific order */
-       cost_fct_t get_costs;                   /**< function ptr used to get costs for copies */
-       struct obstack ob;
+
+       /** Representation in graph structure. Only build on demand */
+       struct obstack obst;
+       set *nodes;
 };
 
-/**
- * A single unit of optimization. Lots of these form a copy-opt problem
- */
+/* Helpers */
+#define get_irn_col(co, irn)           arch_register_get_index(arch_get_irn_register((co)->aenv, irn))
+#define set_irn_col(co, irn, col)      arch_set_irn_register((co)->aenv, irn, arch_register_for_index((co)->cls, col))
+#define is_curr_reg_class(co, irn)     (arch_get_irn_reg_class((co)->aenv, irn, -1) == (co)->cls)
+
+#define MIN(a,b) ((a<b)?(a):(b))
+#define MAX(a,b) ((a<b)?(b):(a))
+
+#define list_entry_units(lh) list_entry(lh, unit_t, units)
+
+#define is_Reg_Phi(irn)                                                (is_Phi(irn) && mode_is_data(get_irn_mode(irn)))
+
+#define get_Perm_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_Perm_Proj(arch_env, irn)                    (is_Proj(irn) && is_Perm(arch_env, get_Proj_pred(irn)))
+
+#define is_2addr_code(arch_env, irn, req)      (arch_get_register_req(arch_env, req, irn, -1)->type == arch_register_req_type_should_be_same)
+
+
+/******************************************************************************
+   ____        _   _    _       _ _          _____ _
+  / __ \      | | | |  | |     (_) |        / ____| |
+ | |  | |_ __ | |_| |  | |_ __  _| |_ ___  | (___ | |_ ___  _ __ __ _  __ _  ___
+ | |  | | '_ \| __| |  | | '_ \| | __/ __|  \___ \| __/ _ \| '__/ _` |/ _` |/ _ \
+ | |__| | |_) | |_| |__| | | | | | |_\__ \  ____) | || (_) | | | (_| | (_| |  __/
+  \____/| .__/ \__|\____/|_| |_|_|\__|___/ |_____/ \__\___/|_|  \__,_|\__, |\___|
+        | |                                                            __/ |
+        |_|                                                           |___/
+ ******************************************************************************/
+
+#define MIS_HEUR_TRIGGER 8
+
 typedef struct _unit_t {
        struct list_head units;         /**< chain for all units */
        copy_opt_t *co;                         /**< the copy_opt this unit belongs to */
@@ -50,60 +82,32 @@ typedef struct _unit_t {
        struct list_head queue;         /**< list of qn's sorted by weight of qn-mis */
 } unit_t;
 
-/* Helpers */
-#define get_irn_col(co, irn)           arch_register_get_index(arch_get_irn_register((co)->aenv, irn))
-#define set_irn_col(co, irn, col)      arch_set_irn_register((co)->aenv, irn, arch_register_for_index((co)->cls, col))
-#define is_curr_reg_class(co, irn)     (arch_get_irn_reg_class((co)->aenv, irn, -1) == (co)->cls)
-
-#define MIN(a,b) ((a<b)?(a):(b))
-#define MAX(a,b) ((a<b)?(b):(a))
-
-#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 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)))
-#define is_2addr_code(arch_env, irn, req)      (arch_get_register_req(arch_env, req, irn, -1)->type == arch_register_req_type_should_be_same)
 
-/**
- * Checks if a node is optimizable, viz. has somthing to do with coalescing
- * @param arch The architecture environment
- * @param irn  The irn to check
- * @param req  A register_requirement structure (used to check for 2-addr-code)
- */
-#define co_is_optimizable(arch, irn, req) (!arch_irn_is_ignore(arch, irn) && (is_Reg_Phi(irn) || is_Perm_Proj(arch, irn) || is_2addr_code(arch, irn, req)))
 
-/**
- * Checks if the irn is a non-interfering argument of a node which 'is_optimizable'
- */
-int co_is_optimizable_arg(const copy_opt_t *co, ir_node *irn);
-
-/**
- * Returns the maximal costs possible, i.e. the costs if all
- * pairs would be assigned different registers.
*/
-int co_get_max_copy_costs(const copy_opt_t *co);
+/******************************************************************************
+   _____                 _        _____ _
+  / ____|               | |      / ____| |
+ | |  __ _ __ __ _ _ __ | |__   | (___ | |_ ___  _ __ __ _  __ _  ___
+ | | |_ | '__/ _` | '_ \| '_ \   \___ \| __/ _ \| '__/ _` |/ _` |/ _ \
+ | |__| | | | (_| | |_) | | | |  ____) | || (_) | | | (_| | (_| |  __/
+  \_____|_|  \__,_| .__/|_| |_| |_____/ \__\___/|_|  \__,_|\__, |\___|
+                  | |                                       __/ |
                 |_|                                      |___/
+ ******************************************************************************/
 
-/**
- * Returns the inevitable costs, i.e. the costs of
- * all copy pairs which interfere.
- */
-int co_get_inevit_copy_costs(const copy_opt_t *co);
+typedef struct _neighb_t neighb_t;
 
-/**
- * Returns the current costs the copies are causing.
- * The result includes inevitable costs and the costs
- * of the copies regarding the current register allocation
- */
-int co_get_copy_costs(const copy_opt_t *co);
+struct _neighb_t {
+       neighb_t *next;                 /** the next neighbour entry*/
+       ir_node *irn;                   /** the neighbour itself */
+       int costs;                              /** the costs of the edge (node_t->irn, neighb_t->irn) */
+};
 
-/**
- * Returns a lower bound for the costs of copies in this ou.
- * The result includes inevitable costs and the costs of a
- * minimal costs caused by the nodes of the ou.
- */
-int co_get_lower_bound(const copy_opt_t *co);
+typedef struct _node_t {
+       ir_node *irn;                   /** a node with affinity edges */
+       int count;                              /** number of affinity edges in the linked list below */
+       neighb_t *neighbours;   /** a linked list of all affinity neighbours */
+} node_t;
 
 
 #endif
index 467b464..3350548 100644 (file)
 
 #ifdef COPYOPT_STAT
 
+#define DO_HEUR
+#undef DO_ILP1
+#define DO_ILP2
+
 #define DEBUG_LVL SET_LEVEL_1
 static firm_dbg_module_t *dbg = NULL;
 
@@ -221,7 +225,7 @@ static void stat_phi_node(be_chordal_env_t *chordal_env, ir_node *phi) {
 static void stat_copy_node(be_chordal_env_t *chordal_env, ir_node *root) {
        curr_vals[I_CPY_CNT]++;
        curr_vals[I_COPIES_MAX]++;
-       if (nodes_interfere(chordal_env, root, get_Copy_src(root))) {
+       if (nodes_interfere(chordal_env, root, get_Perm_src(root))) {
                curr_vals[I_COPIES_IF]++;
                assert(0 && "A Perm pair (in/out) should never interfere!");
        }
@@ -456,9 +460,12 @@ void co_compare_solvers(be_chordal_env_t *chordal_env) {
        color_save_t saver;
        int costs_inevit, costs_init, costs_heur, costs_ilp1, costs_ilp2, lower_bound;
 
+       phi_class_compute(chordal_env->irg);
+
        co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
+       co_build_ou_structure(co);
+       co_build_graph_structure(co);
        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;
@@ -519,6 +526,8 @@ void co_compare_solvers(be_chordal_env_t *chordal_env) {
 #endif /* DO_ILP2 */
 
        pmap_destroy(saver.saved_colors);
+       co_free_graph_structure(co);
+       co_free_ou_structure(co);
        free_copy_opt(co);
 }
 
index cb804a6..d5f5f20 100644 (file)
 
 #ifdef COPYOPT_STAT
 
-#define DO_HEUR
-#define DO_ILP1
-#define DO_ILP2
-
 #include "irgraph.h"
 #include "bearch.h"
 #include "bechordal_t.h"