Bugfixes, adaption to new lpp.
authorDaniel Grund <grund@cs.uni-saarland.de>
Tue, 7 Jun 2005 09:09:59 +0000 (09:09 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Tue, 7 Jun 2005 09:09:59 +0000 (09:09 +0000)
ir/be/Makefile.in
ir/be/becopyheur.c
ir/be/becopyilp.c
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/becopyoptmain.c
ir/be/becopyoptmain.h
ir/be/bemain.c

index 50968cb..5ab4dbc 100644 (file)
@@ -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
 
index 9365393..4621ff1 100644 (file)
@@ -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; i<ou->node_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));
 
index 6f7f75b..687b5a4 100644 (file)
 #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; i<pi->last_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);
 }
index 57b5d4d..0c40454 100644 (file)
@@ -7,6 +7,9 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
 
 #include "irprog.h"
 
 #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) ((a<b)?(a):(b))
+
+/**
+ * Computes a 'max independent set' wrt. ifg-edges only (no coloring conflicts, no register constraints)
+ * @return The size of such a mis
+ * NOTE: Code adapted from becopyheur
+ * BETTER: Here we can be sure having a chordal graph to work on, so for 'larger' opt-units we
+ *         could use a special algorithm.
+ */
+static int get_ifg_mis_size(unit_t *ou) {
+       int all_size, curr_size, i, o;
+       int *which;
+       ir_node **curr, **all = alloca(ou->node_count * sizeof(*all));
+
+       /* all contains all nodes */
+       all_size = 0;
+       for (i=0; i<ou->node_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_size<all_size; ++curr_size)
+               which[curr_size] = curr_size;
+
+       /* stores the currently examined set */
+       curr = alloca(all_size*sizeof(*curr));
+
+       while (1) { /* this loop will terminate because at least a single node will be a max indep. set */
+               /* build current set */
+               for (i=0; i<curr_size; ++i)
+                       curr[i] = all[which[all_size-curr_size+i]];
+
+               /* check current set */
+               for (i=0; i<curr_size; ++i)
+                       for (o=i+1; o<curr_size; ++o)
+                               if (nodes_interfere(ou->co->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<curr_size; ++i)
+                               which[all_size-curr_size+i] = i;
+               } else {
+                       int redo = 1;
+                       while (redo) {
+                               int pos = all_size;
+                               do {
+                                       pos--;
+                               } while (!(which[pos] = (which[pos]+1) % all_size));
+
+                               for (i=pos+1; i<all_size; ++i)
+                                       which[i] = MIN(which[i-1]+1, all_size-1);
+
+                               redo = 0;
+                               for (i=all_size-curr_size; i<all_size-1; ++i)
+                                       if (which[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!");
                        }
        }
index 65ae75a..cf49abd 100644 (file)
  */
 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...
index e00c888..26828d8 100644 (file)
 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);
 
index e26803b..832a57d 100644 (file)
@@ -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
index 85c6904..0af6076 100644 (file)
@@ -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