Changed many things in copy opt. 1st part of refactoring.
[libfirm] / ir / be / becopyilp1.c
1 /**
2  * Author:      Daniel Grund
3  * Date:                17.05.2005
4  * Copyright:   (c) Universitaet Karlsruhe
5  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
6  * CVS-ID:      $Id$
7  *
8  * ILP formalization using:
9  *  - 2 classes of vars: Nodes- and optimality variables.
10  *  - Clique constraints
11  *  - Path constraints
12  *  - Clique path constraints
13  */
14
15 #include "becopyilp_t.h"
16 #include "benumb_t.h"
17 #include "belive_t.h"
18 #include "irdom_t.h"
19 #include "irgwalk.h"
20
21 #define PATH_CONSTRAINTS_FOR_CLASSES
22 #undef PRECOLOR_MAX_CLIQUE
23 #undef NO_NULL_COLORS
24 #undef NO_NULL_COLORS_EXTRA_CSTS
25 #undef NO_NULL_COLORS_WITH_COSTS
26 #if (defined(NO_NULL_COLORS_EXTRA_CSTS) || defined(NO_NULL_COLORS_WITH_COSTS)) && !defined(NO_NULL_COLORS)
27 #error Chose your weapon!
28 #endif
29
30 #undef DUMP_MPS
31 static firm_dbg_module_t *dbg = NULL;
32 #define SLOTS_LIVING 32
33
34
35
36 typedef struct _simpl_t {
37         struct list_head chain;
38         ir_node *irn;
39 } simpl_t;
40
41 typedef struct _problem_instance_t {
42         const copy_opt_t *co;                   /** the copy_opt problem */
43         /* problem size reduction removing simple nodes */
44         struct list_head simplicials;   /**< holds all simpl_t's in right order to color*/
45         pset *removed;                                  /**< holds all removed simplicial irns */
46         /* lp problem */
47         lpp_t *curr_lp;                                 /**< points to the problem currently used */
48         lpp_t *dilp;                                    /**< problem formulation directly as milp */
49 #ifdef NO_NULL_COLORS_EXTRA_CSTS
50         int first_nnc_cst_idx;                  /**< the first index of a constraint belonging to no-null-colors stuff*/
51 #endif
52         int first_nnc_var_idx;                  /**< the first index of a constraint belonging to no-null-colors stuff*/
53
54         int cst_counter, first_x_var, last_x_var;
55         char buf[32];
56         int all_simplicial;
57         pset *done;
58 } problem_instance_t;
59
60 #define is_removed(irn) pset_find_ptr(pi->removed, irn)
61
62 #define is_color_possible(irn,color) arch_reg_is_allocatable(pi->co->aenv, irn, -1, arch_register_for_index(pi->co->cls, color))
63
64 /*
65  * Some stuff for variable name handling.
66  */
67 #define mangle_cst(buf, prefix, nr) \
68                         snprintf((buf), sizeof(buf), "%c%d", (prefix), (nr))
69
70 #define mangle_var1(buf, prefix, color) \
71                         snprintf((buf), sizeof(buf), "%c%d", (prefix), (color))
72
73 #define mangle_var2(buf, prefix, node_nr, color) \
74                         snprintf((buf), sizeof(buf), "%c%d_%d", (prefix), (node_nr), (color))
75
76 #define mangle_var3(buf, prefix, n1, n2, col) \
77                         snprintf((buf), sizeof(buf), "%c%d_%d_%d", (prefix), (n1), (n2), (col))
78
79 #define mangle_var_irn(buf, prefix, irn, color) \
80                         mangle_var2((buf), (prefix), get_irn_graph_nr(irn), (color))
81
82 #define split_var(var, nnr, col) \
83                         sscanf(var, "x%d_%d", (nnr), (col))
84
85
86 /**
87  * Checks if a node is simplicial in the graph
88  * heeding the already removed nodes.
89  */
90 static INLINE int pi_is_simplicial(problem_instance_t *pi, const ir_node *ifn) {
91         int i, o, size = 0;
92         ir_node **all, *curr;
93         be_ifg_t *ifg = pi->co->cenv->ifg;
94         void *iter = be_ifg_neighbours_iter_alloca(ifg);
95
96         all = alloca(be_ifg_degree(ifg, ifn) * sizeof(*all));
97
98         /* get all non-removed neighbors */
99         be_ifg_foreach_neighbour(ifg, iter, ifn, curr)
100                 if (!is_removed(curr))
101                         all[size++] = curr;
102
103         /* check if these form a clique */
104         for (i=0; i<size; ++i)
105                 for (o=i+1; o<size; ++o)
106                         if (!be_ifg_connected(ifg, all[i], all[o]))
107                                 return 0;
108
109         /* all edges exist so this is a clique */
110         return 1;
111 }
112
113 static int irn_cmp(const void *a, const void *b, size_t n)
114 {
115         return a != b;
116 }
117
118 /**
119  * Iterative finds and 'removes' from the graph all nodes which are
120  * simplicial AND not member of a equal-color-wish
121  */
122 static void pi_find_simplicials(problem_instance_t *pi) {
123         ir_node *irn;
124         int redo = 1;
125         int n_nodes = 0;
126         const be_ifg_t *ifg = pi->co->cenv->ifg;
127         void *iter = be_ifg_neighbours_iter_alloca(ifg);
128
129         DBG((dbg, LEVEL_2, "Find simlicials...\n"));
130
131         while (redo) {
132                 arch_register_req_t req;
133                 redo = 0;
134                 be_ifg_foreach_node(ifg, iter, irn) {
135                         if (!is_removed(irn) && !co_is_optimizable(pi->co->aenv, irn, &req) && !co_is_optimizable_arg(pi->co, irn)) {
136                         if (pi_is_simplicial(pi, irn)) {
137                                         simpl_t *s = xmalloc(sizeof(*s));
138                                         s->irn = irn;
139                                         list_add(&s->chain, &pi->simplicials);
140                                         pset_insert_ptr(pi->removed, irn);
141                                         redo = 1;
142                                         DBG((dbg, LEVEL_2, " Removed %+F\n", irn));
143                         }
144                         }
145                 }
146         }
147
148         /* TODO: Count inside the last look */
149         be_ifg_foreach_node(ifg, iter, irn) {
150                 n_nodes++;
151         }
152
153         if (n_nodes == pset_count(pi->removed))
154                 pi->all_simplicial = 1;
155 }
156
157 #ifdef NO_NULL_COLORS
158 static void pi_add_constr_no_null_colors(problem_instance_t *pi) {
159         int cst_counter=0, col, var_idx, cst_idx;
160         int n_colors = pi->co->chordal_env->cls->n_regs;
161         char buf[40];
162
163         for (col = 0; col < n_colors; ++col) {
164                 mangle_var1(buf, 'u', col);
165 #ifdef NO_NULL_COLORS_WITH_COSTS
166                 var_idx = lpp_add_var(pi->curr_lp, buf, lpp_binary, 1.0 / (double) (1 << (col+1)) );
167 #else
168                 var_idx = lpp_add_var(pi->curr_lp, buf, lpp_binary, 1.0 / (2.0 * n_colors) );
169 #endif
170                 if (!pi->first_nnc_var_idx)
171                         pi->first_nnc_var_idx = var_idx;
172         }
173
174 #ifdef NO_NULL_COLORS_EXTRA_CSTS
175         for (col = 0; col < n_colors; ++col) {
176                 mangle_cst(buf, 'U', cst_counter++);
177                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, 0);
178                 if (!pi->first_nnc_cst_idx)
179                         pi->first_nnc_cst_idx = cst_idx;
180                 lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+col, -1);
181         }
182 #endif
183
184 #ifndef NO_NULL_COLORS_WITH_COSTS
185         for (col = 0; col < n_colors - 1; ++col) {
186                 mangle_cst(buf, 'U', cst_counter++);
187                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, 0);
188                 lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+col  ,  1);
189                 lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+col+1, -1);
190         }
191 #endif
192
193 }
194 #endif
195
196 /**
197  * Add coloring-force conditions
198  * Matrix A: knapsack constraint for each node
199  */
200 static void pi_add_constr_A(problem_instance_t *pi) {
201         pmap_entry *pme;
202
203         DBG((dbg, LEVEL_2, "Add A constraints...\n"));
204         /* iterate over all blocks */
205         pmap_foreach(pi->co->cenv->border_heads, pme) {
206                 struct list_head *head = pme->value;
207                 border_t *curr;
208                 bitset_t *pos_regs = bitset_alloca(pi->co->cenv->cls->n_regs);
209
210                 list_for_each_entry_reverse(border_t, curr, head, list)
211                         if (curr->is_def && curr->is_real && !is_removed(curr->irn)) {
212                                 int cst_idx, nnr, col;
213
214                                 nnr = get_irn_graph_nr(curr->irn);
215                                 mangle_cst(pi->buf, 'A', nnr);
216                                 cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_equal, 1);
217
218                                 /* iterate over all possible colors in order */
219                                 bitset_clear_all(pos_regs);
220                                 arch_get_allocatable_regs(pi->co->aenv, curr->irn, -1, pos_regs);
221                                 bitset_foreach(pos_regs, col) {
222                                         int var_idx;
223                                         mangle_var2(pi->buf, 'x', nnr, col);
224                                         var_idx = lpp_add_var(pi->curr_lp, pi->buf, lpp_binary, 0);
225                                         if (!pi->first_x_var)
226                                                 pi->first_x_var = var_idx;
227                                         pi->last_x_var = var_idx;
228                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
229 #ifdef NO_NULL_COLORS_EXTRA_CSTS
230                                         lpp_set_factor_fast(pi->curr_lp, pi->first_nnc_cst_idx+col, var_idx, 1);
231 #endif
232                                 }
233                         }
234         }
235 }
236
237 /**
238  * Checks if all nodes in @p living are live in in block @p block.
239  * @return 1 if all are live in
240  *         0 else
241  */
242 static INLINE int all_live_in(ir_node *block, pset *living) {
243         ir_node *n;
244         for (n = pset_first(living); n; n = pset_next(living))
245                 if (!is_live_in(block, n)) {
246                         pset_break(living);
247                         return 0;
248                 }
249         return 1;
250 }
251
252 /**
253  * Finds cliques in the interference graph, considering only nodes
254  * for which the color @p color is possible. Finds only 'maximal-cliques',
255  * viz cliques which are not contained in another one.
256  * Matrix B: interference constraints using cliques
257  */
258 static void pi_add_constr_B(problem_instance_t *pi, int color) {
259         enum phase_t {growing, shrinking} phase = growing;
260         border_t *b;
261         pmap_entry *pme;
262         pset *living = pset_new_ptr(SLOTS_LIVING);
263
264         DBG((dbg, LEVEL_2, "Add B constraints (col = %d)...\n", color));
265         /* iterate over all blocks */
266         pmap_foreach(pi->co->cenv->border_heads, pme) {
267                 ir_node *block = pme->key;
268                 struct list_head *head = pme->value;
269
270                 list_for_each_entry_reverse(border_t, b, head, list) {
271                         const ir_node *irn = b->irn;
272                         if (is_removed(irn) || !is_color_possible(irn, color))
273                                 continue;
274
275                         if (b->is_def) {
276                                 DBG((dbg, LEVEL_2, "Def %n\n", irn));
277                                 pset_insert_ptr(living, irn);
278                                 phase = growing;
279                         } else { /* is_use */
280                                 DBG((dbg, LEVEL_2, "Use %n\n", irn));
281
282                                 /* before shrinking the set, store the current 'maximum' clique;
283                                  * do NOT if clique is a single node
284                                  * do NOT if all values are live_in (in this case they were contained in a live-out clique elsewhere) */
285                                 if (phase == growing && pset_count(living) >= 2 && !all_live_in(block, living)) {
286                                         int cst_idx;
287                                         ir_node *n;
288                                         mangle_cst(pi->buf, 'B', pi->cst_counter);
289 #ifdef NO_NULL_COLORS
290                                         cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_less, 0);
291 #else
292                                         cst_idx = lpp_add_cst(pi->curr_lp, pi->buf, lpp_less, 1);
293 #endif
294                                         for (n = pset_first(living); n; n = pset_next(living)) {
295                                                 int var_idx;
296                                                 mangle_var_irn(pi->buf, 'x', n, color);
297                                                 var_idx = lpp_get_var_idx(pi->curr_lp, pi->buf);
298                                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
299                                         }
300 #ifdef NO_NULL_COLORS
301                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, pi->first_nnc_var_idx+color, -1.0);
302 #endif
303                                         pi->cst_counter++;
304                                 }
305                                 pset_remove_ptr(living, irn);
306                                 phase = shrinking;
307                         }
308                 }
309         }
310         assert(0 == pset_count(living));
311         del_pset(living);
312 }
313
314 /**
315  * Generates constraints which interrelate x with y variables.
316  * x1 and x2 have the different colors ==> y_12 = 1
317  */
318 static void pi_add_constr_E(problem_instance_t *pi) {
319         unit_t *curr;
320         bitset_t *root_regs, *arg_regs, *work_regs;
321         int cst_counter = 0;
322         unsigned nregs = pi->co->cenv->cls->n_regs;
323         root_regs = bitset_alloca(nregs);
324         arg_regs = bitset_alloca(nregs);
325         work_regs = bitset_alloca(nregs);
326
327         DBG((dbg, LEVEL_2, "Add E constraints...\n"));
328         /* for all roots of optimization units */
329         list_for_each_entry(unit_t, curr, &pi->co->units, units) {
330                 ir_node *root, *arg;
331                 int rootnr, argnr, color;
332                 int y_idx, i;
333                 char buf[32];
334
335                 root = curr->nodes[0];
336                 rootnr = get_irn_graph_nr(root);
337                 bitset_clear_all(root_regs);
338                 arch_get_allocatable_regs(pi->co->aenv, root, -1, root_regs);
339
340                 /* for all arguments of root */
341                 for (i = 1; i < curr->node_count; ++i) {
342                         arg = curr->nodes[i];
343                         argnr = get_irn_graph_nr(arg);
344                         bitset_clear_all(arg_regs);
345                         arch_get_allocatable_regs(pi->co->aenv, arg, -1, arg_regs);
346
347                         /* Introduce new variable and set factor in objective function */
348                         mangle_var2(buf, 'y', rootnr, argnr);
349                         y_idx = lpp_add_var(pi->curr_lp, buf, lpp_binary, curr->costs[i]);
350
351                         /* set starting value */
352                         lpp_set_start_value(pi->curr_lp, y_idx, (get_irn_col(pi->co, root) != get_irn_col(pi->co, arg)));
353
354                         /* For all colors root and arg have in common, add 2 constraints to E */
355                         bitset_copy(work_regs, root_regs);
356                         bitset_and(work_regs, arg_regs);
357                         bitset_foreach(work_regs, color) {
358                                 int root_idx, arg_idx, cst_idx;
359                                 mangle_var2(buf, 'x', rootnr, color);
360                                 root_idx = lpp_get_var_idx(pi->curr_lp, buf);
361                                 mangle_var2(buf, 'x', argnr, color);
362                                 arg_idx = lpp_get_var_idx(pi->curr_lp, buf);
363
364                                 /* add root-arg-y <= 0 */
365                                 mangle_cst(buf, 'E', cst_counter++);
366                                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_less, 0);
367                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, root_idx, 1);
368                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, arg_idx, -1);
369                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1);
370
371                                 /* add arg-root-y <= 0 */
372                                 mangle_cst(buf, 'E', cst_counter++);
373                                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_less, 0);
374                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, root_idx, -1);
375                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, arg_idx, 1);
376                                 lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1);
377                         }
378                         /* For all colors root and arg have "disjunct", add 1 constraints to E.
379                          * If root gets a color the arg is not possible to get then they will
380                          * definetly get different colors. So y has to be 1.
381                          * Vice versa for arg.
382                          */
383                         bitset_copy(work_regs, root_regs);
384                         bitset_xor(work_regs, arg_regs);
385                         bitset_foreach(work_regs, color) {
386                                 int root_idx, arg_idx, cst_idx;
387                                 mangle_var2(buf, 'x', rootnr, color);
388                                 root_idx = lpp_get_var_idx(pi->curr_lp, buf);
389                                 mangle_var2(buf, 'x', argnr, color);
390                                 arg_idx = lpp_get_var_idx(pi->curr_lp, buf);
391
392                                 mangle_cst(buf, 'E', cst_counter++);
393                                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_less, 0);
394                                 if (bitset_is_set(root_regs, color)) {
395                                         /* add root-y <= 0 */
396                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, root_idx, 1);
397                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1);
398                                 } else {
399                                         assert(bitset_is_set(arg_regs, color) && "bitset_xor is buggy");
400                                         /* add arg-y <= 0 */
401                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, arg_idx, 1);
402                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, -1);
403                                 }
404                         }
405                 }
406         }
407 }
408
409 static INLINE int get_costs(problem_instance_t *pi, ir_node *phi, ir_node *irn) {
410         int i;
411         unit_t *curr;
412         /* search optimization unit for phi */
413         list_for_each_entry(unit_t, curr, &pi->co->units, units)
414                 if (curr->nodes[0] == phi) {
415                         for (i=1; i<curr->node_count; ++i)
416                                 if (curr->nodes[i] == irn)
417                                         return curr->costs[i];
418                         assert(0 && "irn must occur in this ou");
419                 }
420         assert(0 && "phi must be found in a ou");
421         return 0;
422 }
423
424 static void clique_path_walker(ir_node *block, void *env) {
425         problem_instance_t *pi = env;
426         int count, arity, row, col, other_row, *costs;
427         ir_node **phis, *phi, *irn, **phi_matrix;
428         pset *done;
429         bitset_t *candidates;
430
431         /* Count all phi nodes of this block */
432         for (count=0, irn = sched_first(block); is_Phi(irn); irn = sched_next(irn))
433                 count++;
434
435         /* We at least 2 phi nodes for this class of inequalities */
436         if (count < 2)
437                 return;
438
439         /* Build the \Phi-Matrix */
440         arity = get_irn_arity(sched_first(block));
441         phis = alloca(count * sizeof(*phis));
442         costs = alloca(count * sizeof(costs));
443         phi_matrix = alloca(count*arity * sizeof(*phi_matrix));
444         candidates = bitset_alloca(count);
445
446         phi = sched_first(block);
447         for (row=0; row<count; ++row) {
448                 phis[row] = phi;
449                 for (col=0; col<arity; ++col) {
450                         ir_node *arg = get_irn_n(phi, col);
451                         /* Sort out all arguments interfering with its phi */
452                         if (nodes_interfere(pi->co->cenv, phi, arg)) {
453                                 phi_matrix[row*arity + col] =  NULL;
454                         } else
455                                 phi_matrix[row*arity + col] =  arg;
456                 }
457                 phi = sched_next(phi);
458         }
459
460         /* Now find the interesting patterns in the matrix:
461          * All nodes which are used at least twice in a column. */
462         /* columnwise ... */
463         for (col=0; col<arity; ++col) {
464                 done = pset_new_ptr_default();
465                 for (row=0; row<count; ++row) {
466                         irn = phi_matrix[row*arity + col];
467                         /*
468                          * is this an interfering arg (NULL)
469                          * or has the irn already been processed in this col?
470                          */
471                         if (!irn || pset_find_ptr(done, irn))
472                                 continue;
473                         else
474                                 pset_insert_ptr(done, irn);
475
476                         /* insert irn in candidates */
477                         bitset_clear_all(candidates);
478                         bitset_set(candidates, row);
479                         /* search the irn in the rows below */
480                         for (other_row = row+1; other_row<count; ++other_row)
481                                 if (irn == phi_matrix[other_row*arity + col]) {
482                                         /* found the irn in the same col in another row */
483                                         bitset_set(candidates, other_row);
484                                 }
485
486                         /* now we know all occurences of irn in this col */
487                         if (bitset_popcnt(candidates) < 2)
488                                 continue;
489
490                         /* generate an unequation finally.
491                          * phis are indexed in the bitset,
492                          * shared argument is irn
493                          * rhs is phi_count - 1 */
494                         {
495                                 char buf[32];
496                                 ir_node *root;
497                                 int pos, irnnr, rootnr, cst_idx, y_idx, cst_counter = 0;
498                                 int minimal_unequal_count = bitset_popcnt(candidates)-1;
499
500                                 irnnr = get_irn_graph_nr(irn);
501                                 mangle_cst(buf, 'M', cst_counter++);
502                                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, minimal_unequal_count);
503
504                                 /* for all phis */
505                                 bitset_foreach(candidates, pos) {
506                                         root = phis[pos];
507                                         rootnr = get_irn_graph_nr(root);
508                                         mangle_var2(buf, 'y', rootnr, irnnr);
509                                         y_idx = lpp_get_var_idx(pi->curr_lp, buf);
510                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, 1);
511                                 }
512                         }
513                 }
514                 del_pset(done); /* clear set for next row */
515         } /*next col*/
516 }
517
518 /**
519  * Matrix M: Multi-Arg-Use. Interrelates different \phi-functions
520  * in the same block, iff they use the same arg at the same pos.
521  * Only one of the phis can get the arg.
522  */
523 static void pi_add_clique_path_cstr(problem_instance_t *pi) {
524         DBG((dbg, LEVEL_2, "Adding clique path constraints...\n"));
525         dom_tree_walk_irg(pi->co->irg, clique_path_walker, NULL, pi);
526 }
527
528 #ifndef PATH_CONSTRAINTS_FOR_CLASSES
529 /**
530  * Matrix P: Path contraints.
531  * If 2 nodes interfere and there is a path of equal-color-edges
532  * connecting them, then at least one of those equal-color-edges
533  * will break and cause some costs.
534  */
535 static void pi_add_path_cstr(problem_instance_t *pi) {
536         unit_t *curr;
537         int cst_counter = 0;
538         DBG((dbg, LEVEL_2, "Adding path constraints...\n"));
539
540         /* for all optimization units (only phis) */
541         list_for_each_entry(unit_t, curr, &pi->co->units, units) {
542                 int i, o, rootnr;
543
544                 if (curr->min_nodes_costs == 0)
545                         continue;
546
547                 rootnr = get_irn_graph_nr(curr->nodes[0]);
548                 /* check all argument pairs for interference */
549                 for (i=1; i<curr->node_count; ++i) {
550                         const ir_node *arg1 = curr->nodes[i];
551                         int arg1nr = get_irn_graph_nr(arg1);
552                         for (o=i+1; o<curr->node_count; ++o) {
553                                 const ir_node *arg2 = curr->nodes[o];
554                                 int arg2nr = get_irn_graph_nr(arg2);
555                                 if (nodes_interfere(pi->co->cenv, arg1, arg2)) {
556                                         int cst_idx, y_idx;
557                                         char buf[32];
558
559                                         mangle_cst(buf, 'P', cst_counter++);
560                                         cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, 1);
561
562                                         mangle_var2(buf, 'y', rootnr, arg1nr);
563                                         y_idx = lpp_get_var_idx(pi->curr_lp, buf);
564                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, 1);
565
566                                         mangle_var2(buf, 'y', rootnr, arg2nr);
567                                         y_idx = lpp_get_var_idx(pi->curr_lp, buf);
568                                         lpp_set_factor_fast(pi->curr_lp, cst_idx, y_idx, 1);
569                                 }
570                         }
571                 }
572         }
573 }
574 #endif
575
576 #ifdef PATH_CONSTRAINTS_FOR_CLASSES
577 static INLINE int get_y_var_idx(problem_instance_t *pi, int nnr1, int nnr2) {
578         int res;
579         char buf[30];
580
581         mangle_var2(buf, 'y', nnr1, nnr2);
582         if ((res = lpp_get_var_idx(pi->curr_lp, buf)) != -1)
583                 return res;
584
585         mangle_var2(buf, 'y', nnr2, nnr1);
586         if ((res = lpp_get_var_idx(pi->curr_lp, buf)) != -1)
587                 return res;
588
589         assert(0 && "One of them must work");
590   return -1;
591 }
592
593 static void check_ecc_and_add_cut(problem_instance_t *pi, ir_node **path, int length, pset *remain, ir_node *tgt) {
594         if (path[length-1] == tgt) { /* we found a path */
595                 int cst_idx, var_idx, i, nnr1, nnr2;
596                 char buf[30];
597
598                 /* add cut to ilp */
599                 mangle_cst(buf, 'Q', pi->cst_counter++);
600                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_greater, 1);
601
602                 /* add all vars along the path */
603                 nnr2 = get_irn_graph_nr(path[0]);
604                 for (i=1; i<length; ++i) {
605                         nnr1 = nnr2;
606                         nnr2 = get_irn_graph_nr(path[i]);
607                         var_idx = get_y_var_idx(pi, nnr1, nnr2);
608                         lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
609                 }
610         } else { /* try to extend the path */
611                 be_chordal_env_t *cenv = pi->co->cenv;
612                 const ir_edge_t *edge;
613                 ir_node *end = path[length-1];
614                 ir_node **next = alloca(pset_count(remain) * sizeof(*next));
615                 int i, o, max, next_pos = 0;
616                 pset *done = pset_new_ptr_default();
617
618                 /* find all potential next nodes on path */
619                 /*  args of phis */
620                 if (is_Phi(end))
621                         for(i=0, max=get_irn_arity(end); i<max; ++i) {
622                                 ir_node *arg = get_irn_n(end, i);
623                                 if (!pset_find_ptr(done, arg) && pset_find_ptr(remain, arg)) {
624                                         next[next_pos++] = arg;
625                                         pset_insert_ptr(done, arg);
626                                 }
627                         }
628                 /*  outs of phis and other nodes */
629                 foreach_out_edge(end, edge) {
630                         ir_node *user = edge->src;
631                         if (is_Phi(user) && !pset_find_ptr(done, user) && pset_find_ptr(remain, user)) {
632                                 next[next_pos++] = user;
633                                 pset_insert_ptr(done, user);
634                         }
635                 }
636                 del_pset(done);
637
638
639                 /* delete all potential nodes with interferences to other nodes in the path */
640                 for (i=0; i<next_pos; ++i) {
641                         ir_node *nn = next[i];
642
643                         /* if next is the tgt, it may interfere with path[0],
644                          * so skip the first check */
645                         o = (nn == tgt && length > 1) ? 1 : 0;
646
647                         for(; o<length; ++o)
648                                 if (nodes_interfere(cenv, nn, path[o])) {
649                                         next[i] = NULL;
650                                         break;
651                                 }
652                 }
653                 /* now we have all possible nodes in next; impossibles are NULL */
654
655                 /* try to finish path with all possible nodes */
656                 for (i=0; i<next_pos; ++i) {
657                         if (!next[i]) /* this was an impossible node */
658                                 continue;
659
660                         path[length] = next[i];
661                         pset_remove_ptr(remain, next[i]);
662                         check_ecc_and_add_cut(pi, path, length+1, remain, tgt);
663                         pset_insert_ptr(remain, next[i]);
664                 }
665         }
666 }
667
668 static void path_cstr_for_classes_walker(ir_node *irn, void *env) {
669         problem_instance_t *pi = env;
670         be_chordal_env_t *cenv;
671         int i, o, max;
672         ir_node *m, **cls;
673         pset *class = get_phi_class(irn);
674         if (!class || pset_find_ptr(pi->done, class))
675                 return;
676
677         pset_insert_ptr(pi->done, class);
678
679         /* pset to array */
680         max = pset_count(class);
681         cls = alloca(max * sizeof(*cls));
682         for(i=0, m = pset_first(class); m; i++, m = pset_next(class)) {
683                 DBG((dbg, LEVEL_1, " class member: %+F\n", m));
684                 cls[i] = m;
685         }
686
687         cenv = pi->co->cenv;
688         for(i=0; i<max; ++i) {
689                 ir_node **path = alloca(max * sizeof(*path));
690                 pset *remain = pset_new_ptr(8);
691                 pset_insert_pset_ptr(remain, class);
692
693                 /* add cls[i] to path and remove it from remainder */
694                 path[0] = cls[i];
695                 pset_remove_ptr(remain, cls[i]);
696
697                 for(o=i+1; o<max; ++o)
698                         if (nodes_interfere(cenv, cls[i], cls[o]))
699                                 check_ecc_and_add_cut(pi, path, 1, remain, cls[o]);
700
701                 /* insert back into remainder */
702                 pset_insert_ptr(remain, cls[i]);
703         }
704 }
705
706
707 /**
708  * Matrix P: Path contraints.
709  * If 2 nodes interfere and there is a path of equal-color-edges
710  * connecting them, then at least one of those equal-color-edges
711  * will break and cause some costs.
712  */
713 static void pi_add_path_cstr_for_classes(problem_instance_t *pi) {
714         DBG((dbg, LEVEL_2, "Adding path constraints for phi classes...\n"));
715         pi->cst_counter = 0;
716         pi->done = pset_new_ptr_default();
717         irg_walk_graph(pi->co->irg, path_cstr_for_classes_walker, NULL, pi);
718         del_pset(pi->done);
719 }
720 #endif
721
722 #ifdef PRECOLOR_MAX_CLIQUE
723 struct pre_col {
724         problem_instance_t *pi;
725         pset **clique;
726 };
727
728 static void preColoringWalker(ir_node *bl, void *env) {
729         struct pre_col *e = env;
730         pset **clique = e->clique;
731         pset *max_clique = clique ? *clique : NULL;
732         int max = max_clique ? pset_count(max_clique) : 0;
733         problem_instance_t *pi = e->pi;
734
735         int i, n;
736         pset *live       = pset_new_ptr_default();
737         ir_node *irn;
738         irn_live_t *li;
739
740         /* as always, bring the live end nodes to life here */
741         live_foreach(bl, li) {
742           if(live_is_end(li) && has_reg_class(pi, li->irn)) {
743             pset_insert_ptr(live, irn);
744           }
745         }
746
747         sched_foreach_reverse(bl, irn) {
748                 int pres = pset_count(live);
749
750                 if(pres > max) {
751                         max = pres;
752                         if(max_clique)
753                                 del_pset(max_clique);
754
755                         max_clique = pset_new_ptr_default();
756                         pset_insert_pset_ptr(max_clique, live);
757                 }
758
759
760
761                 if(has_reg_class(pi, irn))
762                         pset_remove_ptr(live, irn);
763
764                 for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
765                         ir_node *op = get_irn_n(irn, i);
766                         if(has_reg_class(pi, op) && !is_Phi(irn))
767                                 pset_insert_ptr(live, op);
768                 }
769         }
770
771   del_pset(live);
772   *clique = max_clique;
773 }
774
775 static void pi_add_constr_preColoring(problem_instance_t *pi) {
776         ir_node *irn;
777         int cst_counter, color;
778         struct pre_col pre_col;
779
780         pre_col.clique = NULL;
781         pre_col.pi = pi;
782
783         dom_tree_walk_irg(get_irg(pi->co), preColoringWalker, NULL, &pre_col);
784
785         color = 0;
786         for (irn = pset_first(*pre_col.clique); irn; irn = pset_next(*pre_col.clique)) {
787                 int cst_idx, var_idx, nnr = get_irn_graph_nr(irn);
788                 char buf[100];
789
790                 mangle_cst(buf, 'K', cst_counter++);
791                 cst_idx = lpp_add_cst(pi->curr_lp, buf, lpp_equal, 1);
792
793                 mangle_var2(buf, 'x', nnr, color++);
794                 var_idx = lpp_get_var_idx(pi->curr_lp, buf);
795                 lpp_set_factor_fast(pi->curr_lp, cst_idx, var_idx, 1);
796         }
797 }
798 #endif
799
800 /**
801  * Generate the initial problem matrices and vectors.
802  */
803 static problem_instance_t *new_pi(const copy_opt_t *co) {
804         problem_instance_t *pi;
805         int col;
806
807         DBG((dbg, LEVEL_2, "Generating new instance...\n"));
808         pi = xcalloc(1, sizeof(*pi));
809         pi->co = co;
810         pi->removed = pset_new_ptr_default();
811         INIT_LIST_HEAD(&pi->simplicials);
812         pi->dilp     = new_lpp(co->name, lpp_minimize);
813
814         /* problem size reduction */
815         pi_find_simplicials(pi);
816         if (pi->all_simplicial)
817                 return pi;
818
819         /* built objective and constraints */
820         pi->curr_lp = pi->dilp;
821 #ifdef NO_NULL_COLORS
822         pi_add_constr_no_null_colors(pi);
823 #endif
824         pi_add_constr_A(pi);
825         for (col = 0; col < pi->co->cls->n_regs; ++col)
826                 pi_add_constr_B(pi, col);
827         pi_add_constr_E(pi);
828
829 #ifdef PATH_CONSTRAINTS_FOR_CLASSES
830         pi_add_path_cstr_for_classes(pi);
831 #else
832         pi_add_path_cstr(pi);
833 #endif
834         pi_add_clique_path_cstr(pi);
835 #ifdef PRECOLOR_MAX_CLIQUE
836         pi_add_constr_preColoring(pi);
837 #endif
838
839         return pi;
840 }
841
842 /**
843  * Clean the problem instance
844  */
845 static void free_pi(problem_instance_t *pi) {
846         simpl_t *simpl, *tmp;
847
848         DBG((dbg, LEVEL_2, "Free instance...\n"));
849         free_lpp(pi->dilp);
850         list_for_each_entry_safe(simpl_t, simpl, tmp, &pi->simplicials, chain)
851                 free(simpl);
852         del_pset(pi->removed);
853         free(pi);
854 }
855
856 /**
857  * Set starting values for the mip problem according
858  * to the current coloring of the graph.
859  */
860 static void pi_set_start_sol(problem_instance_t *pi) {
861         int i;
862         char var_name[64];
863         DBG((dbg, LEVEL_2, "Set start solution...\n"));
864         for (i=pi->first_x_var; i<=pi->last_x_var; ++i) {
865                 int nnr, col;
866                 double val;
867                 /* get variable name */
868                 lpp_get_var_name(pi->curr_lp, i, var_name, sizeof(var_name));
869                 /* split into components */
870                 if (split_var(var_name, &nnr, &col) == 2) {
871                         assert(get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->irg, nnr)) != -1);
872                         val = (get_irn_col(pi->co, get_irn_for_graph_nr(pi->co->irg, nnr)) == col) ? 1 : 0;
873                         lpp_set_start_value(pi->curr_lp, i, val);
874                 } else {
875                         fprintf(stderr, "Variable name is: %s\n", var_name);
876                         assert(0 && "x vars always look like this 'x123_45'");
877                 }
878         }
879 }
880
881 /**
882  * Invoke a solver
883  */
884 static void pi_solve_ilp(problem_instance_t *pi) {
885   double lower_bound;
886
887         pi_set_start_sol(pi);
888         lower_bound = co_get_lower_bound(pi->co) - co_get_inevit_copy_costs(pi->co);
889         lpp_set_bound(pi->curr_lp, lower_bound);
890         lpp_solve_net(pi->curr_lp, LPP_HOST, LPP_SOLVER);
891 //      lpp_solve_cplex(pi->curr_lp);
892         DBG((dbg, LEVEL_1, "Solution time: %.2f\n", pi->curr_lp->sol_time));
893 }
894
895 /**
896  * Set the color of all simplicial nodes removed form
897  * the graph before transforming it to an ilp.
898  */
899 static void pi_set_simplicials(problem_instance_t *pi) {
900         simpl_t *simpl, *tmp;
901         be_ifg_t *ifg        = pi->co->cenv->ifg;
902         bitset_t *used_cols  = bitset_alloca(arch_register_class_n_regs(pi->co->cls));
903         void *iter           = be_ifg_neighbours_iter_alloca(ifg);
904
905         DBG((dbg, LEVEL_2, "Set simplicials...\n"));
906         /* color the simplicial nodes in right order */
907         list_for_each_entry_safe(simpl_t, simpl, tmp, &pi->simplicials, chain) {
908                 int free_col;
909                 ir_node *other, *irn;
910
911                 /* get free color by inspecting all neighbors */
912                 irn = simpl->irn;
913                 bitset_clear_all(used_cols);
914
915                 be_ifg_foreach_neighbour(ifg, iter, irn, other) {
916                         if (!is_removed(other)) /* only inspect nodes which are in graph right now */
917                                 bitset_set(used_cols, get_irn_col(pi->co, other));
918                 }
919
920                 /* now all bits not set are possible colors */
921                 free_col = bitset_next_clear(used_cols, 0);
922                 assert(free_col != -1 && "No free color found. This can not be.");
923                 set_irn_col(pi->co, irn, free_col);
924                 pset_remove_ptr(pi->removed, irn); /* irn is back in graph again */
925         }
926 }
927
928 /**
929  * Sets the colors of irns according to the values of variables
930  * provided by the solution of the solver.
931  */
932 static int pi_apply_solution(problem_instance_t *pi) {
933         int res = 1, i;
934         double *sol;
935         lpp_sol_state_t state;
936         DBG((dbg, LEVEL_2, "Applying solution...\n"));
937
938 #ifdef DO_STAT
939         copystat_add_ilp_time((int)(1000.0*lpp_get_sol_time(pi->curr_lp)));  //now we have ms
940         copystat_add_ilp_vars(lpp_get_var_count(pi->curr_lp));
941         copystat_add_ilp_csts(lpp_get_cst_count(pi->curr_lp));
942         copystat_add_ilp_iter(lpp_get_iter_cnt(pi->curr_lp));
943 #endif
944
945         sol = xmalloc((pi->last_x_var - pi->first_x_var + 1) * sizeof(*sol));
946         state = lpp_get_solution(pi->curr_lp, sol, pi->first_x_var, pi->last_x_var);
947         if (state != lpp_optimal) {
948                 printf("WARNING %s: Solution state is not 'optimal': %d\n", pi->co->name, state);
949                 assert(state >= lpp_feasible && "The solution should at least be feasible!");
950                 res = 0;
951         }
952         for (i=0; i<pi->last_x_var - pi->first_x_var + 1; ++i) {
953                 int nnr, col;
954                 char var_name[64];
955
956                 if (sol[i] > 1-EPSILON) { /* split varibale name into components */
957                         lpp_get_var_name(pi->curr_lp, pi->first_x_var+i, var_name, sizeof(var_name));
958                         if (split_var(var_name, &nnr, &col) == 2) {
959                                 DBG((dbg, LEVEL_2, "Irn %n  Idx %d  Var %s  Val %f\n", get_irn_for_graph_nr(pi->co->irg, nnr), i, var_name, sol[i]));
960                                 DBG((dbg, LEVEL_2, "x%d = %d\n", nnr, col));
961                                 set_irn_col(pi->co, get_irn_for_graph_nr(pi->co->irg, nnr), col);
962                         } else
963                                 assert(0 && "This should be a x-var");
964                 }
965         }
966         return res;
967 }
968
969 int co_solve_ilp1(copy_opt_t *co, double time_limit) {
970         int res = 1;
971         problem_instance_t *pi;
972
973         dbg = firm_dbg_register("ir.be.copyoptilp");
974
975         pi = new_pi(co);
976         if (!pi->all_simplicial) {
977 #ifdef DUMP_MPS
978                 char buf[512];
979                 snprintf(buf, sizeof(buf), "%s.mps", co->name);
980                 lpp_dump(pi->curr_lp, buf);
981 #endif
982                 lpp_set_time_limit(pi->curr_lp, time_limit);
983                 pi_solve_ilp(pi);
984                 res = pi_apply_solution(pi);
985                 pi_set_simplicials(pi);
986         }
987         free_pi(pi);
988         return res;
989 }