*
*/
-#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);
+}
#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))
/*
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
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);
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
}
}
}
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);
}
}
-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;
}
#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.
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);
pi_add_path_cstr(pi);
#endif
pi_add_clique_path_cstr(pi);
-#ifdef PRECOLOR_MAX_CLIQUE
- pi_add_constr_preColoring(pi);
-#endif
-
- return 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.
}
}
+
/**
* 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
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;
+}
*
*/
+#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