+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, 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, 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);
+ }
+ }
+ }
+ }
+}