Next step of refactoring
authorDaniel Grund <grund@cs.uni-saarland.de>
Thu, 2 Mar 2006 17:29:23 +0000 (17:29 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Thu, 2 Mar 2006 17:29:23 +0000 (17:29 +0000)
ir/be/becopyheur.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

index 3631a40..1dfb38f 100644 (file)
 #include "becopyopt_t.h"
 #include "becopystat.h"
 #include "bitset.h"
-#include "bearch.h"
 
 static firm_dbg_module_t *dbg = NULL;
 
 #define SEARCH_FREE_COLORS
 
-#define SLOTS_PINNED_GLOBAL 256
+#define SLOTS_PINNED_GLOBAL 64
 #define SLOTS_CONFLICTS 8
 #define SLOTS_CHANGED_NODES 32
 
-#define MIN(a,b) ((a<b)?(a):(b))
 #define list_entry_queue(lh) list_entry(lh, qnode_t, queue)
 #define HASH_CONFLICT(c) (HASH_PTR(c.n1) ^ HASH_PTR(c.n2))
 
index 67adf36..97dd23b 100644 (file)
@@ -8,4 +8,152 @@
  *
  */
 
-#include "becopyilp_t.h"
\ No newline at end of file
+#include "becopyilp_t.h"
+#include "beifg_t.h"
+
+/******************************************************************************
+    _____ _                        _            _   _
+   / ____(_)                      | |          | | (_)
+  | (___  _ _______   _ __ ___  __| |_   _  ___| |_ _  ___  _ __
+   \___ \| |_  / _ \ | '__/ _ \/ _` | | | |/ __| __| |/ _ \| '_ \
+   ____) | |/ /  __/ | | |  __/ (_| | |_| | (__| |_| | (_) | | | |
+  |_____/|_/___\___| |_|  \___|\__,_|\__,_|\___|\__|_|\___/|_| |_|
+
+ *****************************************************************************/
+
+/**
+ * Checks if a node is simplicial in the graph heeding the already removed nodes.
+ */
+static INLINE int sr_is_simplicial(size_red_t *sr, const ir_node *ifn) {
+       int i, o, size = 0;
+       ir_node **all, *curr;
+       be_ifg_t *ifg = sr->co->cenv->ifg;
+       void *iter = be_ifg_neighbours_iter_alloca(ifg);
+
+       all = alloca(be_ifg_degree(ifg, ifn) * sizeof(*all));
+
+       /* get all non-removed neighbors */
+       be_ifg_foreach_neighbour(ifg, iter, ifn, curr)
+               if (!sr_is_removed(sr, curr))
+                       all[size++] = curr;
+
+       /* check if these form a clique */
+       for (i=0; i<size; ++i)
+               for (o=i+1; o<size; ++o)
+                       if (!be_ifg_connected(ifg, all[i], all[o]))
+                               return 0;
+
+       /* all edges exist so this is a clique */
+       return 1;
+}
+
+void sr_remove(size_red_t *sr) {
+       ir_node *irn;
+       int redo = 1;
+       int n_nodes = 0;
+       const be_ifg_t *ifg = sr->co->cenv->ifg;
+       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_simplicial(sr, irn)) {
+                                       coloring_suffix_t *cs = obstack_alloc(&sr->ob, sizeof(*cs));
+
+                                       cs->irn = irn;
+                                       cs->next = sr->col_suff;
+                                       sr->col_suff = cs;
+
+                                       pset_insert_ptr(sr->all_removed, irn);
+
+                                       redo = 1;
+                       }
+                       }
+               }
+       }
+}
+
+void sr_reinsert(size_red_t *sr) {
+       coloring_suffix_t *cs;
+       be_ifg_t *ifg        = sr->co->cenv->ifg;
+       bitset_t *used_cols  = bitset_alloca(arch_register_class_n_regs(sr->co->cls));
+       void *iter           = be_ifg_neighbours_iter_alloca(ifg);
+
+       /* color the removed nodes in right order */
+       for (cs = sr->col_suff; cs; cs = cs->next) {
+               int free_col;
+               ir_node *other, *irn;
+
+               /* get free color by inspecting all neighbors */
+               irn = cs->irn;
+               bitset_clear_all(used_cols);
+
+               be_ifg_foreach_neighbour(ifg, iter, irn, other) {
+                       if (!sr_is_removed(sr, other)) /* only inspect nodes which are in graph right now */
+                               bitset_set(used_cols, get_irn_col(sr->co, other));
+               }
+
+               /* now all bits not set are possible colors */
+               free_col = bitset_next_clear(used_cols, 0);
+               assert(free_col != -1 && "No free color found. This can not be.");
+               set_irn_col(sr->co, irn, free_col);
+               pset_remove_ptr(sr->all_removed, irn); /* irn is back in graph again */
+       }
+}
+
+void free_size_red(size_red_t *sr) {
+       obstack_free(&sr->ob, NULL);
+       free(sr);
+}
+
+/******************************************************************************
+    _____                      _        _____ _      _____
+   / ____|                    (_)      |_   _| |    |  __ \
+  | |  __  ___ _ __   ___ _ __ _  ___    | | | |    | |__) |
+  | | |_ |/ _ \ '_ \ / _ \ '__| |/ __|   | | | |    |  ___/
+  | |__| |  __/ | | |  __/ |  | | (__   _| |_| |____| |
+   \_____|\___|_| |_|\___|_|  |_|\___| |_____|______|_|
+
+ *****************************************************************************/
+
+ilp_env_t *new_ilp_env(copy_opt_t *co, firm_dbg_module_t *dbg, ilp_callback build, ilp_callback apply, void *env) {
+       ilp_env_t *res = malloc(sizeof(*res));
+       assert(res);
+
+       res->co = co;
+       res->dbg = dbg;
+       res->build = build;
+       res->apply = apply;
+       res->env = env;
+       res->sr = new_size_red(co);
+
+       return res;
+}
+
+lpp_sol_state_t ilp_go(ilp_env_t *ienv, double time_limit) {
+       sr_remove(ienv->sr);
+
+       ienv->build(ienv);
+
+       lpp_set_time_limit(ienv->lp, time_limit);
+
+#ifdef LPP_SOLVE_NET
+       lpp_solve_net(ienv->lp, LPP_HOST, LPP_SOLVER);
+#else
+       lpp_solve_cplex(ienv->lp);
+#endif
+
+       ienv->apply(ienv);
+
+       sr_reinsert(ienv->sr);
+
+       return lpp_get_sol_state(ienv->lp);
+}
+
+void free_ilp_env(ilp_env_t *ienv) {
+       free_size_red(ienv->sr);
+       free_lpp(ienv->lp);
+       free(ienv);
+}
index 0f2c33c..81f58de 100644 (file)
 #include "belive_t.h"
 #include "irdom_t.h"
 #include "irgwalk.h"
+#include "xmalloc.h"
+#include "pset.h"
+#include "irprog.h"
+#include "irdom_t.h"
+#include "iredges_t.h"
 
-#define PATH_CONSTRAINTS_FOR_CLASSES
-#undef PRECOLOR_MAX_CLIQUE
-#undef NO_NULL_COLORS
-#undef NO_NULL_COLORS_EXTRA_CSTS
-#undef NO_NULL_COLORS_WITH_COSTS
-#if (defined(NO_NULL_COLORS_EXTRA_CSTS) || defined(NO_NULL_COLORS_WITH_COSTS)) && !defined(NO_NULL_COLORS)
-#error Chose your weapon!
-#endif
+#include "becopystat.h"
+#include "besched_t.h"
+#include "phiclass.h"
+
+#if 0 //temporary
 
+#define PATH_CONSTRAINTS_FOR_CLASSES
 #undef DUMP_MPS
+
 static firm_dbg_module_t *dbg = NULL;
 #define SLOTS_LIVING 32
 
-
-
-typedef struct _simpl_t {
-       struct list_head chain;
-       ir_node *irn;
-} simpl_t;
-
 typedef struct _problem_instance_t {
-       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 */
-       /* lp problem */
-       lpp_t *curr_lp;                                 /**< points to the problem currently used */
-       lpp_t *dilp;                                    /**< problem formulation directly as milp */
-#ifdef NO_NULL_COLORS_EXTRA_CSTS
-       int first_nnc_cst_idx;                  /**< the first index of a constraint belonging to no-null-colors stuff*/
-#endif
-       int first_nnc_var_idx;                  /**< the first index of a constraint belonging to no-null-colors stuff*/
+       const copy_opt_t *co;                   /**< the copy opt problem */
+       size_red_t *sr;                                 /**< problem size reduction. removes simple nodes */
+       lpp_t *lp;                                              /**< the linear programming problem */
 
+       /* Helpers for maintaining indices and finding variables */
+       int first_nnc_var_idx;                  /**< the first index of a constraint belonging to no-null-colors stuff*/
        int cst_counter, first_x_var, last_x_var;
        char buf[32];
-       int all_simplicial;
        pset *done;
 } 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->aenv, irn, -1, arch_register_for_index(pi->co->cls, color))
 
 /*
@@ -83,116 +71,6 @@ typedef struct _problem_instance_t {
                        sscanf(var, "x%d_%d", (nnr), (col))
 
 
-/**
- * Checks if a node is simplicial in the graph
- * heeding the already removed nodes.
- */
-static INLINE int pi_is_simplicial(problem_instance_t *pi, const ir_node *ifn) {
-       int i, o, size = 0;
-       ir_node **all, *curr;
-       be_ifg_t *ifg = pi->co->cenv->ifg;
-       void *iter = be_ifg_neighbours_iter_alloca(ifg);
-
-       all = alloca(be_ifg_degree(ifg, ifn) * sizeof(*all));
-
-       /* get all non-removed neighbors */
-       be_ifg_foreach_neighbour(ifg, iter, ifn, curr)
-               if (!is_removed(curr))
-                       all[size++] = curr;
-
-       /* check if these form a clique */
-       for (i=0; i<size; ++i)
-               for (o=i+1; o<size; ++o)
-                       if (!be_ifg_connected(ifg, all[i], all[o]))
-                               return 0;
-
-       /* all edges exist so this is a clique */
-       return 1;
-}
-
-static int irn_cmp(const void *a, const void *b, size_t n)
-{
-       return a != b;
-}
-
-/**
- * Iterative finds and 'removes' from the graph all nodes which are
- * simplicial AND not member of a equal-color-wish
- */
-static void pi_find_simplicials(problem_instance_t *pi) {
-       ir_node *irn;
-       int redo = 1;
-       int n_nodes = 0;
-       const be_ifg_t *ifg = pi->co->cenv->ifg;
-       void *iter = be_ifg_neighbours_iter_alloca(ifg);
-
-       DBG((dbg, LEVEL_2, "Find simlicials...\n"));
-
-       while (redo) {
-               arch_register_req_t req;
-               redo = 0;
-               be_ifg_foreach_node(ifg, iter, irn) {
-                       if (!is_removed(irn) && !co_is_optimizable(pi->co->aenv, irn, &req) && !co_is_optimizable_arg(pi->co, irn)) {
-                       if (pi_is_simplicial(pi, irn)) {
-                                       simpl_t *s = xmalloc(sizeof(*s));
-                                       s->irn = irn;
-                                       list_add(&s->chain, &pi->simplicials);
-                                       pset_insert_ptr(pi->removed, irn);
-                                       redo = 1;
-                                       DBG((dbg, LEVEL_2, " Removed %+F\n", irn));
-                       }
-                       }
-               }
-       }
-
-       /* TODO: Count inside the last look */
-       be_ifg_foreach_node(ifg, iter, irn) {
-               n_nodes++;
-       }
-
-       if (n_nodes == pset_count(pi->removed))
-               pi->all_simplicial = 1;
-}
-
-#ifdef NO_NULL_COLORS
-static void pi_add_constr_no_null_colors(problem_instance_t *pi) {
-       int cst_counter=0, col, var_idx, cst_idx;
-       int n_colors = pi->co->chordal_env->cls->n_regs;
-       char buf[40];
-
-       for (col = 0; col < n_colors; ++col) {
-               mangle_var1(buf, 'u', col);
-#ifdef NO_NULL_COLORS_WITH_COSTS
-               var_idx = lpp_add_var(pi->curr_lp, buf, lpp_binary, 1.0 / (double) (1 << (col+1)) );
-#else
-               var_idx = lpp_add_var(pi->curr_lp, buf, lpp_binary, 1.0 / (2.0 * n_colors) );
-#endif
-               if (!pi->first_nnc_var_idx)
-                       pi->first_nnc_var_idx = var_idx;
-       }
-
-#ifdef NO_NULL_COLORS_EXTRA_CSTS
-       for (col = 0; col < n_colors; ++col) {
-               mangle_cst(buf, 'U', cst_counter++);
-               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, 0);
-               if (!pi->first_nnc_cst_idx)
-                       pi->first_nnc_cst_idx = cst_idx;
-               lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+col, -1);
-       }
-#endif
-
-#ifndef NO_NULL_COLORS_WITH_COSTS
-       for (col = 0; col < n_colors - 1; ++col) {
-               mangle_cst(buf, 'U', cst_counter++);
-               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, 0);
-               lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+col  ,  1);
-               lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+col+1, -1);
-       }
-#endif
-
-}
-#endif
-
 /**
  * Add coloring-force conditions
  * Matrix A: knapsack constraint for each node
@@ -208,7 +86,7 @@ static void pi_add_constr_A(problem_instance_t *pi) {
                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 && !is_removed(curr->irn)) {
+                       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);
@@ -226,9 +104,6 @@ static void pi_add_constr_A(problem_instance_t *pi) {
                                                pi->first_x_var = var_idx;
                                        pi->last_x_var = var_idx;
                                        lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
-#ifdef NO_NULL_COLORS_EXTRA_CSTS
-                                       lpp_set_factor_fast(pi->curr_lp, pi->first_nnc_cst_idx+col, var_idx, 1);
-#endif
                                }
                        }
        }
@@ -286,20 +161,13 @@ static void pi_add_constr_B(problem_instance_t *pi, int color) {
                                        int cst_idx;
                                        ir_node *n;
                                        mangle_cst(pi->buf, 'B', pi->cst_counter);
-#ifdef NO_NULL_COLORS
-                                       cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_less, 0);
-#else
                                        cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_less, 1);
-#endif
                                        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);
                                        }
-#ifdef NO_NULL_COLORS
-                                       lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+color, -1.0);
-#endif
                                        pi->cst_counter++;
                                }
                                pset_remove_ptr(living, irn);
@@ -406,21 +274,6 @@ static void pi_add_constr_E(problem_instance_t *pi) {
        }
 }
 
-static INLINE int get_costs(problem_instance_t *pi, ir_node *phi, ir_node *irn) {
-       int i;
-       unit_t *curr;
-       /* search optimization unit for phi */
-       list_for_each_entry(unit_t, curr, &pi->co->units, units)
-               if (curr->nodes[0] == phi) {
-                       for (i=1; i<curr->node_count; ++i)
-                               if (curr->nodes[i] == irn)
-                                       return curr->costs[i];
-                       assert(0 && "irn must occur in this ou");
-               }
-       assert(0 && "phi must be found in a ou");
-       return 0;
-}
-
 static void clique_path_walker(ir_node *block, void *env) {
        problem_instance_t *pi = env;
        int count, arity, row, col, other_row, *costs;
@@ -719,83 +572,7 @@ static void pi_add_path_cstr_for_classes(problem_instance_t *pi) {
 }
 #endif
 
-#ifdef PRECOLOR_MAX_CLIQUE
-struct pre_col {
-       problem_instance_t *pi;
-       pset **clique;
-};
-
-static void preColoringWalker(ir_node *bl, void *env) {
-       struct pre_col *e = env;
-       pset **clique = e->clique;
-       pset *max_clique = clique ? *clique : NULL;
-       int max = max_clique ? pset_count(max_clique) : 0;
-       problem_instance_t *pi = e->pi;
-
-       int i, n;
-       pset *live       = pset_new_ptr_default();
-       ir_node *irn;
-       irn_live_t *li;
-
-       /* as always, bring the live end nodes to life here */
-       live_foreach(bl, li) {
-         if(live_is_end(li) && has_reg_class(pi, li->irn)) {
-           pset_insert_ptr(live, irn);
-         }
-       }
-
-       sched_foreach_reverse(bl, irn) {
-               int pres = pset_count(live);
 
-               if(pres > max) {
-                       max = pres;
-                       if(max_clique)
-                               del_pset(max_clique);
-
-                       max_clique = pset_new_ptr_default();
-                       pset_insert_pset_ptr(max_clique, live);
-               }
-
-
-
-               if(has_reg_class(pi, irn))
-                       pset_remove_ptr(live, irn);
-
-               for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
-                       ir_node *op = get_irn_n(irn, i);
-                       if(has_reg_class(pi, op) && !is_Phi(irn))
-                               pset_insert_ptr(live, op);
-               }
-       }
-
-  del_pset(live);
-  *clique = max_clique;
-}
-
-static void pi_add_constr_preColoring(problem_instance_t *pi) {
-       ir_node *irn;
-       int cst_counter, color;
-       struct pre_col pre_col;
-
-       pre_col.clique = NULL;
-       pre_col.pi = pi;
-
-       dom_tree_walk_irg(get_irg(pi->co), preColoringWalker, NULL, &pre_col);
-
-       color = 0;
-       for (irn = pset_first(*pre_col.clique); irn; irn = pset_next(*pre_col.clique)) {
-               int cst_idx, var_idx, nnr = get_irn_graph_nr(irn);
-               char buf[100];
-
-               mangle_cst(buf, 'K', cst_counter++);
-               cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_equal, 1);
-
-               mangle_var2(buf, 'x', nnr, color++);
-               var_idx = lpp_get_var_idx(pi->curr_lp, buf);
-               lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
-       }
-}
-#endif
 
 /**
  * Generate the initial problem matrices and vectors.
@@ -806,21 +583,14 @@ static problem_instance_t *new_pi(const copy_opt_t *co) {
 
        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, lpp_minimize);
-
-       /* problem size reduction */
-       pi_find_simplicials(pi);
-       if (pi->all_simplicial)
-               return pi;
-
-       /* built objective and constraints */
-       pi->curr_lp = pi->dilp;
-#ifdef NO_NULL_COLORS
-       pi_add_constr_no_null_colors(pi);
-#endif
+       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);
@@ -832,11 +602,6 @@ static problem_instance_t *new_pi(const copy_opt_t *co) {
        pi_add_path_cstr(pi);
 #endif
        pi_add_clique_path_cstr(pi);
-#ifdef PRECOLOR_MAX_CLIQUE
-       pi_add_constr_preColoring(pi);
-#endif
-
-       return pi;
 }
 
 /**
@@ -846,13 +611,12 @@ static void free_pi(problem_instance_t *pi) {
        simpl_t *simpl, *tmp;
 
        DBG((dbg, LEVEL_2, "Free instance...\n"));
-       free_lpp(pi->dilp);
-       list_for_each_entry_safe(simpl_t, simpl, tmp, &pi->simplicials, chain)
-               free(simpl);
-       del_pset(pi->removed);
+       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.
@@ -878,52 +642,33 @@ static void pi_set_start_sol(problem_instance_t *pi) {
        }
 }
 
+
 /**
  * Invoke a solver
  */
-static void pi_solve_ilp(problem_instance_t *pi) {
-  double lower_bound;
+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);
-//     lpp_solve_cplex(pi->curr_lp);
+#else
+       lpp_solve_cplex(pi->curr_lp);
+#endif
        DBG((dbg, LEVEL_1, "Solution time: %.2f\n", pi->curr_lp->sol_time));
 }
 
-/**
- * Set the color of all simplicial nodes removed form
- * the graph before transforming it to an ilp.
- */
-static void pi_set_simplicials(problem_instance_t *pi) {
-       simpl_t *simpl, *tmp;
-       be_ifg_t *ifg        = pi->co->cenv->ifg;
-       bitset_t *used_cols  = bitset_alloca(arch_register_class_n_regs(pi->co->cls));
-       void *iter           = be_ifg_neighbours_iter_alloca(ifg);
-
-       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;
-               ir_node *other, *irn;
-
-               /* get free color by inspecting all neighbors */
-               irn = simpl->irn;
-               bitset_clear_all(used_cols);
-
-               be_ifg_foreach_neighbour(ifg, iter, irn, other) {
-                       if (!is_removed(other)) /* only inspect nodes which are in graph right now */
-                               bitset_set(used_cols, get_irn_col(pi->co, other));
-               }
-
-               /* now all bits not set are possible colors */
-               free_col = bitset_next_clear(used_cols, 0);
-               assert(free_col != -1 && "No free color found. This can not be.");
-               set_irn_col(pi->co, irn, free_col);
-               pset_remove_ptr(pi->removed, irn); /* irn is back in graph again */
-       }
-}
 
 /**
  * Sets the colors of irns according to the values of variables
@@ -966,24 +711,59 @@ static int pi_apply_solution(problem_instance_t *pi) {
        return res;
 }
 
-int co_solve_ilp1(copy_opt_t *co, double time_limit) {
+
+int co_solve_ilp11(copy_opt_t *co, double time_limit) {
        int res = 1;
        problem_instance_t *pi;
 
-       dbg = firm_dbg_register("ir.be.copyoptilp");
+       dbg = firm_dbg_register("ir.be.copyoptilp1");
 
        pi = new_pi(co);
-       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
-               lpp_set_time_limit(pi->curr_lp, time_limit);
-               pi_solve_ilp(pi);
-               res = pi_apply_solution(pi);
-               pi_set_simplicials(pi);
-       }
+
+       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"
+
+#define DEBUG_LVL 1
+
+typedef struct _my_env_t {
+       int foo;
+} my_env_t;
+
+
+static void ilp2_build(ilp_env_t *ienv) {
+       ienv->lp = new_lpp(ienv->co->name, lpp_minimize);
+
+}
+
+static void ilp2_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.coilp2");
+
+       firm_dbg_set_mask(dbg, DEBUG_LVL);
+
+       // my.bla = TODO
+
+       ienv = new_ilp_env(co, dbg, ilp2_build, ilp2_apply, &my);
+
+       sol_state = ilp_go(ienv, time_limit);
+
+       free_ilp_env(ienv);
+
+       return sol_state == lpp_optimal;
+}
index 33efd78..8c2f67c 100644 (file)
 
 #include "becopyilp_t.h"
 
+#define DEBUG_LVL 1
+
+typedef struct _my_env_t {
+       int foo;
+} my_env_t;
+
+
+static void ilp2_build(ilp_env_t *ienv) {
+       ienv->lp = new_lpp(ienv->co->name, lpp_minimize);
+
+}
+
+static void ilp2_apply(ilp_env_t *ienv) {
+
+}
+
 int co_solve_ilp2(copy_opt_t *co, double time_limit) {
-       int res = 1;
+       lpp_sol_state_t sol_state;
+       ilp_env_t *ienv;
+       my_env_t my;
+       firm_dbg_module_t *dbg = firm_dbg_register("ir.be.coilp2");
+
+       firm_dbg_set_mask(dbg, DEBUG_LVL);
+
+       // my.bla = TODO
+
+       ienv = new_ilp_env(co, dbg, ilp2_build, ilp2_apply, &my);
+
+       sol_state = ilp_go(ienv, time_limit);
+
+       free_ilp_env(ienv);
 
-       return res;
+       return sol_state == lpp_optimal;
 }
index 54869c5..1c903e5 100644 (file)
@@ -8,6 +8,9 @@
  *
  */
 
+#ifndef _BECOPYILP_T_H
+#define _BECOPYILP_T_H
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 #include <malloc.h>
 #endif
 
-#include <lpp/lpp.h>
-#include <lpp/lpp_net.h>
-#include <lpp/lpp_cplex.h>
-#include <lpp/lpp_remote.h>
-#include "xmalloc.h"
+#include "irnode_t.h"
 #include "pset.h"
-#include "irprog.h"
-#include "irdom_t.h"
-#include "iredges_t.h"
-#include "bechordal_t.h"
 #include "becopyopt_t.h"
-#include "becopystat.h"
-#include "besched_t.h"
-#include "phiclass.h"
 
-#define LPP_HOST "i44pc52"
-#define LPP_SOLVER "cplex"
+/******************************************************************************
+    _____ _                        _            _   _
+   / ____(_)                      | |          | | (_)
+  | (___  _ _______   _ __ ___  __| |_   _  ___| |_ _  ___  _ __
+   \___ \| |_  / _ \ | '__/ _ \/ _` | | | |/ __| __| |/ _ \| '_ \
+   ____) | |/ /  __/ | | |  __/ (_| | |_| | (__| |_| | (_) | | | |
+  |_____/|_/___\___| |_|  \___|\__,_|\__,_|\___|\__|_|\___/|_| |_|
+
+ *****************************************************************************/
+
+typedef struct _coloring_suffix_t coloring_suffix_t;
+
+struct _coloring_suffix_t {
+       coloring_suffix_t *next;
+       ir_node *irn;
+};
+
+typedef struct _size_red_t {
+       copy_opt_t *co;
+       pset *all_removed;                              /**< All nodes removed during problem size reduction */
+       coloring_suffix_t *col_suff;    /**< Coloring suffix. Reverse would be a PEO prefix */
+       struct obstack ob;
+} size_red_t;
+
+/**
+ * Just prepare. Do nothing yet.
+ */
+size_red_t *new_size_red(copy_opt_t *co);
+
+/**
+ * Checks if a node has already been removed
+ */
+#define sr_is_removed(sr, irn)         pset_find_ptr((sr)->all_removed, irn)
+
+/**
+ * Virtually remove all nodes not related to the problem
+ * (simplicial AND not adjacent to a equal-color-edge)
+ */
+void sr_remove(size_red_t *sr);
+
+/**
+ * Virtually reinsert the nodes removed before and color them
+ */
+void sr_reinsert(size_red_t *sr);
+
+/**
+ * Free all space...
+ */
+void free_size_red(size_red_t *sr);
+
+/**
+ * TODO: This search is necessary because during the construction of the
+ *       units (ou's) args could be merged and weights are accumulated.
+ *       Is this necessary?
+ */
+static INLINE int co_ilp_get_costs(copy_opt_t *co, ir_node *root, ir_node *arg) {
+       int i;
+       unit_t *curr;
+
+       /* search optimization unit for phi */
+       list_for_each_entry(unit_t, curr, &co->units, units)
+               if (curr->nodes[0] == root) {
+
+                       for (i=1; i<curr->node_count; ++i)
+                               if (curr->nodes[i] == arg)
+                                       return curr->costs[i];
+
+                               assert(0 && "irn must occur in this ou");
+               }
+
+       assert(0 && "phi must be found in a ou");
+       return 0;
+}
+
+/******************************************************************************
+    _____                      _        _____ _      _____
+   / ____|                    (_)      |_   _| |    |  __ \
+  | |  __  ___ _ __   ___ _ __ _  ___    | | | |    | |__) |
+  | | |_ |/ _ \ '_ \ / _ \ '__| |/ __|   | | | |    |  ___/
+  | |__| |  __/ | | |  __/ |  | | (__   _| |_| |____| |
+   \_____|\___|_| |_|\___|_|  |_|\___| |_____|______|_|
+
+ *****************************************************************************/
+
+#include <lpp/lpp.h>
+
+#undef LPP_SOLVE_NET
+
+#ifdef LPP_SOLVE_NET
+#  include <lpp/lpp_net.h>
+#  define LPP_HOST "i44pc52"
+#  define LPP_SOLVER "cplex"
+#else
+#  include <lpp/lpp_cplex.h>
+#endif
 
-#define MAX(a,b) ((a<b)?(b):(a))
-#define MIN(a,b) ((a<b)?(a):(b))
 #define EPSILON 0.00001
+
+typedef struct _ilp_env_t ilp_env_t;
+
+typedef void(*ilp_callback)(ilp_env_t*);
+
+struct _ilp_env_t {
+       firm_dbg_module_t *dbg;
+       const copy_opt_t *co;                   /**< the copy opt problem */
+       size_red_t *sr;                                 /**< problem size reduction. removes simple nodes */
+       lpp_t *lp;                                              /**< the linear programming problem */
+       void *env;
+       ilp_callback build;
+       ilp_callback apply;
+
+};
+
+ilp_env_t *new_ilp_env(copy_opt_t *co, firm_dbg_module_t *dbg, ilp_callback build, ilp_callback apply, void *env);
+
+lpp_sol_state_t ilp_go(ilp_env_t *ienv, double time_limit);
+
+void free_ilp_env(ilp_env_t *ienv);
+
+
+/******************************************************************************
+
+
+ *****************************************************************************/
+
+#endif
index eb41145..830aa37 100644 (file)
@@ -32,7 +32,6 @@
 #include "becopystat.h"
 
 
-
 static firm_dbg_module_t *dbg = NULL;
 
 /**
@@ -276,7 +275,7 @@ void free_copy_opt(copy_opt_t *co) {
        }
 }
 
-int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
+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))
@@ -300,7 +299,7 @@ int is_optimizable_arg(const copy_opt_t *co, ir_node *irn) {
        return 0;
 }
 
-int get_costs_loop_depth(ir_node *root, ir_node* arg, int pos) {
+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);
@@ -319,7 +318,7 @@ int get_costs_loop_depth(ir_node *root, ir_node* arg, int pos) {
        return cost+1;
 }
 
-int get_costs_all_one(ir_node *root, ir_node* arg, int pos) {
+int co_get_costs_all_one(ir_node *root, ir_node* arg, int pos) {
        return 1;
 }
 
@@ -427,7 +426,7 @@ void co_compare_solvers(be_chordal_env_t *chordal_env) {
        int costs, costs_inevit, costs_init, costs_heur, costs_classes, costs_ilp, lower_bound;
 #endif
 
-       co = new_copy_opt(chordal_env, get_costs_loop_depth);
+       co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
        DBG((dbg, LEVEL_1, "----> CO: %s\n", co->name));
        phi_class_compute(chordal_env->irg);
 
index cc0baa6..1cd7cdd 100644 (file)
@@ -44,7 +44,7 @@ void free_copy_opt(copy_opt_t *co);
 int co_get_costs_loop_depth(ir_node *root, ir_node* arg, int pos);
 
 /**
- * All costs equal 1. Using this will reduce the number of copies.
+ * All costs equal 1. Using this will reduce the _number_ of copies.
  * @return Must be >= 0 in all cases.
  */
 int co_get_costs_all_one(ir_node *root, ir_node* arg, int pos);
index f16eca8..28fb8dd 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright:   (c) Universitaet Karlsruhe
  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
  *
- * Header for copy optimization problem. Analysis and set up of the problem.
+ * Internal header for copy optimization problem.
  */
 
 #ifndef _BECOPYOPT_T_H
@@ -25,7 +25,7 @@ struct _copy_opt_t {
        const arch_register_class_t *cls;
        const arch_env_t *aenv;
        ir_graph *irg;
-       char *name;                                             /**< ProgName__IrgName__RegClass */
+       char *name;                                             /**< ProgName__IrgName__RegClassName */
 
        struct list_head units;                 /**< all units to optimize in specific order */
        cost_fct_t get_costs;                   /**< function ptr used to get costs for copies */
@@ -40,7 +40,7 @@ typedef struct _unit_t {
        copy_opt_t *co;                         /**< the copy_opt this unit belongs to */
        int node_count;                         /**< size of the nodes array */
        ir_node **nodes;                        /**< [0] is the root-node, others are non interfering args of it. */
-       int *costs;                                     /**< costs[i] are arising, if nodes[i] has a different color */
+       int *costs;                                     /**< costs[i] are incurred, if nodes[i] has a different color */
        int inevitable_costs;           /**< sum of costs of all args interfering with root */
        int all_nodes_costs;            /**< sum of all costs[i] */
        int min_nodes_costs;            /**< a lower bound for the costs in costs[], determined by a max indep. set */