- if (!is_removed(irn) && !is_optimizable(get_arch_env(pi->co), irn, &req) && !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
- */
-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->chordal_env->border_heads, pme) {
- struct list_head *head = pme->value;
- border_t *curr;
- 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)) {
- 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(get_arch_env(pi->co), curr->irn, -1, pi->co->chordal_env->cls, 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);
-#ifdef NO_NULL_COLORS_EXTRA_CSTS
- lpp_set_factor_fast(pi->curr_lp, pi->first_nnc_cst_idx+col, var_idx, 1);
-#endif
- }
- }
- }
-}
-
-/**
- * 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->chordal_env->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);
-#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);
- 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->chordal_env->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(get_arch_env(pi->co), root, -1, 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(get_arch_env(pi->co), arg, -1, pi->co->chordal_env->cls, 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 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;
-}