+static void path_cstr_for_classes_walker(ir_node *irn, void *env) {
+ problem_instance_t *pi = env;
+ be_chordal_env_t *cenv;
+ int i, o, max;
+ ir_node *m, **cls;
+ pset *class = get_phi_class(irn);
+ if (!class || pset_find_ptr(pi->done, class))
+ return;
+
+ pset_insert_ptr(pi->done, class);
+
+ /* pset to array */
+ max = pset_count(class);
+ cls = alloca(max * sizeof(*cls));
+ for(i=0, m = pset_first(class); m; i++, m = pset_next(class)) {
+ DBG((dbg, LEVEL_1, " class member: %+F\n", m));
+ cls[i] = m;
+ }
+
+ cenv = pi->co->chordal_env;
+ for(i=0; i<max; ++i) {
+ ir_node **path = alloca(max * sizeof(*path));
+ pset *remain = pset_new_ptr(8);
+ pset_insert_pset_ptr(remain, class);
+
+ /* add cls[i] to path and remove it from remainder */
+ path[0] = cls[i];
+ pset_remove_ptr(remain, cls[i]);
+
+ for(o=i+1; o<max; ++o)
+ if (nodes_interfere(cenv, cls[i], cls[o]))
+ check_ecc_and_add_cut(pi, path, 1, remain, cls[o]);
+
+ /* insert back into remainder */
+ pset_insert_ptr(remain, cls[i]);
+ }
+}
+
+
+/**
+ * Matrix P: Path contraints.
+ * If 2 nodes interfere and there is a path of equal-color-edges
+ * connecting them, then at least one of those equal-color-edges
+ * will break and cause some costs.
+ */
+static void pi_add_path_cstr_for_classes(problem_instance_t *pi) {
+ DBG((dbg, LEVEL_2, "Adding path constraints for phi classes...\n"));
+ pi->cst_counter = 0;
+ pi->done = pset_new_ptr_default();
+ irg_walk_graph(get_irg(pi->co), path_cstr_for_classes_walker, NULL, pi);
+ del_pset(pi->done);
+}
+#endif
+
+#ifdef PRECOLOR_MAX_CLIQUE
+struct pre_col {
+ problem_instance_t *pi;
+ pset **clique;
+};
+
+#define has_reg_class(pi,irn) \
+ (arch_get_irn_reg_class(pi->co->chordal_env->session_env->main_env->arch_env, \
+ irn, -1) == pi->co->chordal_env->cls)
+
+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
+