Factored copy minimzation out
[libfirm] / ir / be / becopyheur2.c
1
2 /**
3  * More experiments on coalescing.
4  * @author Sebastian Hack
5  * @date   14.04.2006
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #ifdef WITH_LIBCORE
13 #include <libcore/lc_opts.h>
14 #include <libcore/lc_opts_enum.h>
15 #endif /* WITH_LIBCORE */
16
17 #include <stdlib.h>
18 #include <limits.h>
19
20 #include "list.h"
21 #include "pdeq.h"
22 #include "bitset.h"
23
24 #include "debug.h"
25 #include "bitfiddle.h"
26
27 #include "irphase_t.h"
28 #include "irgraph_t.h"
29 #include "irnode_t.h"
30 #include "irprintf.h"
31 #include "irtools.h"
32
33 #include "beabi.h"
34 #include "benode_t.h"
35 #include "becopyopt.h"
36 #include "becopyopt_t.h"
37 #include "bechordal_t.h"
38
39 #define DUMP_BEFORE 1
40 #define DUMP_AFTER  2
41 #define DUMP_CLOUD  4
42 #define DUMP_ALL    2 * DUMP_CLOUD - 1
43
44 static int    dump_flags      = 0;
45 static int    subtree_iter    = 4;
46 static int    max_depth       = 20;
47 static double constr_factor   = 0.9;
48
49 /* Options using libcore */
50 #ifdef WITH_LIBCORE
51
52 static const lc_opt_enum_mask_items_t dump_items[] = {
53         { "before",  DUMP_BEFORE },
54         { "after",   DUMP_AFTER  },
55         { "cloud",   DUMP_CLOUD  },
56         { "all",     DUMP_ALL    },
57         { NULL,      0 }
58 };
59
60 static lc_opt_enum_mask_var_t dump_var = {
61         &dump_flags, dump_items
62 };
63
64 static const lc_opt_table_entry_t options[] = {
65         LC_OPT_ENT_ENUM_MASK("dump", "dump ifg before, after or after each cloud",             &dump_var),
66         LC_OPT_ENT_INT      ("iter", "iterations for subtree nodes (standard: 3)",             &subtree_iter),
67         LC_OPT_ENT_DBL      ("cf",   "factor of constraint importance (between 0.0 and 1.0)",  &constr_factor),
68         LC_OPT_ENT_INT      ("max",  "maximum recursion depth (default 20)",                   &max_depth),
69         { NULL }
70 };
71
72 void be_co2_register_options(lc_opt_entry_t *grp)
73 {
74         lc_opt_entry_t *co2_grp = lc_opt_get_grp(grp, "co2");
75         lc_opt_add_table(co2_grp, options);
76 }
77 #endif
78
79 /*
80   ____  _             _
81  / ___|| |_ __ _ _ __| |_
82  \___ \| __/ _` | '__| __|
83   ___) | || (_| | |  | |_
84  |____/ \__\__,_|_|   \__|
85
86 */
87
88 #define INFEASIBLE(cost) ((cost) == INT_MAX)
89
90 static be_ifg_dump_dot_cb_t ifg_dot_cb;
91
92 typedef unsigned col_t;
93
94 typedef struct _co2_irn_t       co2_irn_t;
95 typedef struct _co2_cloud_t     co2_cloud_t;
96 typedef struct _co2_cloud_irn_t co2_cloud_irn_t;
97
98 typedef struct {
99         col_t col;
100         int costs;
101 } col_cost_pair_t;
102
103 typedef struct {
104         phase_t     ph;
105         copy_opt_t *co;
106         bitset_t   *ignore_regs;
107         co2_irn_t  *touched;
108         int         visited;
109         int         n_regs;
110         struct list_head cloud_head;
111         DEBUG_ONLY(firm_dbg_module_t *dbg;)
112 } co2_t;
113
114 struct _co2_irn_t {
115         ir_node         *irn;
116         affinity_node_t *aff;
117         co2_irn_t       *touched_next;
118         col_t            tmp_col;
119         col_t            orig_col;
120         int                              last_color_change;
121         bitset_t        *adm_cache;
122         unsigned         fixed          : 1;
123         unsigned         tmp_fixed      : 1;
124         unsigned         is_constrained : 1;
125         struct list_head changed_list;
126 };
127
128 struct _co2_cloud_irn_t {
129         struct _co2_irn_t  inh;
130         co2_cloud_t       *cloud;
131         int                visited;
132         int                index;
133         co2_cloud_irn_t   *mst_parent;
134         int                mst_costs;
135         int                mst_n_childs;
136         co2_cloud_irn_t  **mst_childs;
137         int               *col_costs;
138         int                costs;
139         int               *fronts;
140         int               *color_badness;
141         col_cost_pair_t   *tmp_coloring;
142         struct list_head   cloud_list;
143         struct list_head   mst_list;
144 };
145
146 struct _co2_cloud_t {
147         co2_t            *env;
148         struct obstack    obst;
149         int               costs;
150         int               mst_costs;
151         int               inevit;
152         int               best_costs;
153         int               n_memb;
154         int               n_constr;
155         int               max_degree;
156         int                           ticks;
157         double            freedom;
158         co2_cloud_irn_t  *master;
159         co2_cloud_irn_t  *mst_root;
160         co2_cloud_irn_t **seq;
161         struct list_head  members_head;
162         struct list_head  list;
163 };
164
165 typedef struct {
166         co2_cloud_irn_t *src, *tgt;
167         int costs;
168 } edge_t;
169
170 #define FRONT_BASE(ci,col)  ((ci)->fronts + col * (ci)->mst_n_childs)
171
172 #define get_co2_irn(co2, irn)         ((co2_irn_t *)       phase_get_or_set_irn_data(&co2->ph, irn))
173 #define get_co2_cloud_irn(co2, irn)   ((co2_cloud_irn_t *) phase_get_or_set_irn_data(&co2->ph, irn))
174
175 static void *co2_irn_init(phase_t *ph, ir_node *irn, void *data)
176 {
177         co2_t *env         = (co2_t *) ph;
178         affinity_node_t *a = get_affinity_info(env->co, irn);
179         size_t size        = a ? sizeof(co2_cloud_irn_t) : sizeof(co2_irn_t);
180         co2_irn_t *ci      = data ? data : phase_alloc(ph, size);
181
182         memset(ci, 0, size);
183         INIT_LIST_HEAD(&ci->changed_list);
184         ci->touched_next = env->touched;
185         ci->orig_col     = get_irn_col(env->co, irn);
186         env->touched     = ci;
187         ci->irn          = irn;
188         ci->aff          = a;
189
190         if(a) {
191                 co2_cloud_irn_t *cci = (co2_cloud_irn_t *) ci;
192                 INIT_LIST_HEAD(&cci->cloud_list);
193                 cci->mst_parent   = cci;
194         }
195
196         return ci;
197 }
198
199 #define CLOUD_WEIGHT(c) ((1 - constr_factor) * (c)->costs + constr_factor * (c)->freedom)
200
201 static int cmp_clouds_gt(const void *a, const void *b)
202 {
203         const co2_cloud_t **p = a;
204         const co2_cloud_t **q = b;
205         double c = CLOUD_WEIGHT(*p);
206         double d = CLOUD_WEIGHT(*q);
207         return QSORT_CMP(d, c);
208 }
209
210 /**
211  * An order on color/costs pairs.
212  * If the costs are equal, we use the color as a kind of normalization.
213  */
214 static int col_cost_pair_lt(const void *a, const void *b)
215 {
216         const col_cost_pair_t *p = a;
217         const col_cost_pair_t *q = b;
218         int c = p->costs;
219         int d = q->costs;
220         return QSORT_CMP(c, d);
221 }
222
223 int cmp_edges(const void *a, const void *b)
224 {
225         const edge_t *p = a;
226         const edge_t *q = b;
227         return QSORT_CMP(q->costs, p->costs);
228 }
229
230 static col_t get_col(co2_t *env, ir_node *irn)
231 {
232         co2_irn_t *ci = get_co2_irn(env, irn);
233         return ci->tmp_fixed ? ci->tmp_col : ci->orig_col;
234 }
235
236 static INLINE int color_is_fix(co2_t *env, ir_node *irn)
237 {
238         co2_irn_t *ci = get_co2_irn(env, irn);
239         return ci->fixed || ci->tmp_fixed;
240 }
241
242 static INLINE bitset_t *get_adm(co2_t *env, co2_irn_t *ci)
243 {
244         if(!ci->adm_cache) {
245                 arch_register_req_t req;
246                 ci->adm_cache = bitset_obstack_alloc(phase_obst(&env->ph), env->n_regs);
247                 arch_get_register_req(env->co->aenv, &req, ci->irn, BE_OUT_POS(0));
248                 if(arch_register_req_is(&req, limited)) {
249                         req.limited(req.limited_env, ci->adm_cache);
250                         ci->is_constrained = 1;
251                 }
252                 else {
253                         bitset_copy(ci->adm_cache, env->ignore_regs);
254                         bitset_flip_all(ci->adm_cache);
255                 }
256         }
257
258         return ci->adm_cache;
259 }
260
261 static INLINE bitset_t *admissible_colors(co2_t *env, co2_irn_t *ci, bitset_t *bs)
262 {
263         bitset_copy(bs, get_adm(env, ci));
264         return bs;
265 }
266
267 static INLINE int is_color_admissible(co2_t *env, co2_irn_t *ci, col_t col)
268 {
269         bitset_t *bs = get_adm(env, ci);
270         return bitset_is_set(bs, col);
271 }
272
273 static INLINE int is_constrained(co2_t *env, co2_irn_t *ci)
274 {
275         if(!ci->adm_cache)
276                 get_adm(env, ci);
277         return ci->is_constrained;
278 }
279
280 static void incur_constraint_costs(co2_t *env, ir_node *irn, col_cost_pair_t *col_costs, int costs)
281 {
282         bitset_t *aux = bitset_alloca(env->co->cls->n_regs);
283         arch_register_req_t req;
284
285         arch_get_register_req(env->co->aenv, &req, irn, BE_OUT_POS(0));
286
287         if(arch_register_req_is(&req, limited)) {
288                 bitset_pos_t elm;
289                 int n_constr;
290
291                 req.limited(req.limited_env, aux);
292                 n_constr = bitset_popcnt(aux);
293                 bitset_foreach(aux, elm) {
294                         col_costs[elm].costs  = add_saturated(col_costs[elm].costs, costs / n_constr);
295                 }
296         }
297 }
298
299 /**
300  * Determine costs which shall indicate how cheap/expensive it is to try
301  * to assign a node some color.
302  * The costs are computed for all colors. INT_MAX means that it is impossible
303  * to give the node that specific color.
304  *
305  * @param env       The co2 this pointer.
306  * @param irn       The node.
307  * @param col_costs An array of colors x costs where the costs are written to.
308  */
309 static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *col_costs)
310 {
311         ir_node *irn       = ci->irn;
312         be_ifg_t *ifg      = env->co->cenv->ifg;
313         int n_regs         = env->co->cls->n_regs;
314         bitset_t *forb     = bitset_alloca(n_regs);
315         affinity_node_t *a = ci->aff;
316
317         bitset_pos_t elm;
318         ir_node *pos;
319         void *it;
320         int i;
321
322         /* Put all forbidden colors into the aux bitset. */
323         admissible_colors(env, ci, forb);
324         bitset_flip_all(forb);
325
326         for(i = 0; i < n_regs; ++i) {
327                 col_costs[i].col   = i;
328                 col_costs[i].costs = 0;
329         }
330
331         if(a) {
332                 neighb_t *n;
333
334                 co_gs_foreach_neighb(a, n) {
335                         if(color_is_fix(env, n->irn)) {
336                                 col_t col = get_col(env, n->irn);
337                                 col_costs[col].costs = add_saturated(col_costs[col].costs, -n->costs * 128);
338                         }
339
340                         incur_constraint_costs(env, n->irn, col_costs, -n->costs);
341                 }
342         }
343
344         it = be_ifg_neighbours_iter_alloca(ifg);
345         be_ifg_foreach_neighbour(ifg, it, irn, pos) {
346                 col_t col = get_col(env, pos);
347                 if(color_is_fix(env, pos)) {
348                         col_costs[col].costs  = INT_MAX;
349                 }
350                 else {
351                         incur_constraint_costs(env, pos, col_costs, INT_MAX);
352                         col_costs[col].costs = add_saturated(col_costs[col].costs, 8 * be_ifg_degree(ifg, pos));
353                 }
354         }
355         be_ifg_neighbours_break(ifg, it);
356
357         /* Set the costs to infinity for each color which is not allowed at this node. */
358         bitset_foreach(forb, elm) {
359                 col_costs[elm].costs  = INT_MAX;
360         }
361
362 }
363
364 static void single_color_cost(co2_t *env, co2_irn_t *ci, col_t col, col_cost_pair_t *seq)
365 {
366         int n_regs = env->co->cls->n_regs;
367         int i;
368
369         for(i = 0; i < n_regs; ++i) {
370                 seq[i].col   = i;
371                 seq[i].costs = INT_MAX;
372         }
373
374         assert(is_color_admissible(env, ci, col));
375         seq[col].col = 0;
376         seq[0].col   = col;
377         seq[0].costs = 0;
378 }
379
380 static void reject_coloring(struct list_head *h)
381 {
382         co2_irn_t *pos;
383
384         list_for_each_entry(co2_irn_t, pos, h, changed_list)
385                 pos->tmp_fixed = 0;
386 }
387
388 static void materialize_coloring(struct list_head *h)
389 {
390         co2_irn_t *pos;
391
392         list_for_each_entry(co2_irn_t, pos, h, changed_list) {
393                 pos->orig_col  = pos->tmp_col;
394                 pos->tmp_fixed = 0;
395         }
396 }
397
398 static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth);
399
400 static int recolor(co2_t *env, ir_node *irn, col_cost_pair_t *col_list, struct list_head *parent_changed, int depth)
401 {
402         int n_regs         = env->co->cls->n_regs;
403         be_ifg_t *ifg      = env->co->cenv->ifg;
404         co2_irn_t *ci      = get_co2_irn(env, irn);
405         int res            = 0;
406
407         int i;
408
409         if(depth >= max_depth)
410           return 0;
411
412         for(i = 0; i < n_regs; ++i) {
413                 col_t tgt_col  = col_list[i].col;
414                 unsigned costs = col_list[i].costs;
415                 int neigh_ok   = 1;
416
417                 struct list_head changed;
418                 ir_node *n;
419                 void *it;
420
421                 DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying color %d(%d) on %+F\n", depth, tgt_col, costs, irn));
422
423                 /* If the costs for that color (and all successive) are infinite, bail out we won't make it anyway. */
424                 if(INFEASIBLE(costs)) {
425                         DB((env->dbg, LEVEL_4, "\t\t%2{firm:indent}color %d infeasible\n", depth, tgt_col));
426                         ci->tmp_fixed = 0;
427                         return 0;
428                 }
429
430                 /* Set the new color of the node and mark the node as temporarily fixed. */
431                 ci->tmp_col     = tgt_col;
432                 ci->tmp_fixed   = 1;
433
434                 /*
435                 If that color has costs > 0, there's at least one neighbor having that color,
436                 so we will try to change the neighbors' colors, too.
437                 */
438                 INIT_LIST_HEAD(&changed);
439                 list_add(&ci->changed_list, &changed);
440
441                 it = be_ifg_neighbours_iter_alloca(ifg);
442                 be_ifg_foreach_neighbour(ifg, it, irn, n) {
443
444                         /* try to re-color the neighbor if it has the target color. */
445                         if(get_col(env, n) == tgt_col) {
446                                 struct list_head tmp;
447
448                                 /*
449                                 Try to change the color of the neighbor and record all nodes which
450                                 get changed in the tmp list. Add this list to the "changed" list for
451                                 that color. If we did not succeed to change the color of the neighbor,
452                                 we bail out and try the next color.
453                                 */
454                                 INIT_LIST_HEAD(&tmp);
455                                 neigh_ok = change_color_not(env, n, tgt_col, &tmp, depth + 1);
456                                 list_splice(&tmp, &changed);
457                                 if(!neigh_ok)
458                                         break;
459                         }
460                 }
461                 be_ifg_neighbours_break(ifg, it);
462
463                 /*
464                 We managed to assign the target color to all neighbors, so from the perspective
465                 of the current node, every thing was ok and we can return safely.
466                 */
467                 if(neigh_ok) {
468                         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}color %d(%d) was ok\n", depth, tgt_col, costs));
469                         list_splice(&changed, parent_changed);
470                         res = 1;
471                         break;
472                 }
473
474                 /*
475                 If not, that color did not succeed and we unfix all nodes we touched
476                 by traversing the changed list and setting tmp_fixed to 0 for these nodes.
477                 */
478                 else
479                         reject_coloring(&changed);
480         }
481
482         return res;
483 }
484
485 static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth)
486 {
487         co2_irn_t *ci = get_co2_irn(env, irn);
488         int res       = 0;
489         col_t col     = get_col(env, irn);
490
491         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}clearing %+F(%d) of color %d\n", depth, irn, col, not_col));
492
493         /* the node does not have to forbidden color. That's fine, mark it as visited and return. */
494         if(col != not_col) {
495                 if(!ci->tmp_fixed) {
496                         ci->tmp_col     = col;
497                         ci->tmp_fixed   = 1;
498                 }
499
500                 list_add(&ci->changed_list, parent_changed);
501                 return 1;
502         }
503
504         /* The node has the color it should not have _and_ has not been visited yet. */
505         if(!color_is_fix(env, irn)) {
506                 int n_regs            = env->co->cls->n_regs;
507                 col_cost_pair_t *csts = alloca(n_regs * sizeof(csts[0]));
508
509                 /* Get the costs for giving the node a specific color. */
510                 determine_color_costs(env, ci, csts);
511
512                 /* Since the node must not have the not_col, set the costs for that color to "infinity" */
513                 csts[not_col].costs = INT_MAX;
514
515                 /* sort the colors according costs, cheapest first. */
516                 qsort(csts, n_regs, sizeof(csts[0]), col_cost_pair_lt);
517
518                 /* Try recoloring the node using the color list. */
519                 res = recolor(env, irn, csts, parent_changed, depth);
520         }
521
522         /* If we came here, everything went ok. */
523         return res;
524 }
525
526 static int change_color_single(co2_t *env, ir_node *irn, col_t tgt_col, struct list_head *parent_changed, int depth)
527 {
528         co2_irn_t *ci = get_co2_irn(env, irn);
529         col_t col     = get_col(env, irn);
530         int res       = 0;
531
532         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying to set %+F(%d) to color %d\n", depth, irn, col, tgt_col));
533
534         /* the node has the wanted color. That's fine, mark it as visited and return. */
535         if(col == tgt_col) {
536                 if(!ci->tmp_fixed) {
537                         ci->tmp_col     = col;
538                         ci->tmp_fixed   = 1;
539                         list_add(&ci->changed_list, parent_changed);
540                 }
541
542                 res = 1;
543                 goto end;
544         }
545
546         if(!color_is_fix(env, irn) && is_color_admissible(env, ci, tgt_col)) {
547                 int n_regs           = env->co->cls->n_regs;
548                 col_cost_pair_t *seq = alloca(n_regs * sizeof(seq[0]));
549
550                 /* Get the costs for giving the node a specific color. */
551                 single_color_cost(env, ci, tgt_col, seq);
552
553                 /* Try recoloring the node using the color list. */
554                 res = recolor(env, irn, seq, parent_changed, depth);
555
556         }
557
558 end:
559         DB((env->dbg, LEVEL_3, "\t\t%2{firm:indent}color %d %s for %+F\n", depth, tgt_col, res ? "was ok" : "failed", irn));
560         return res;
561 }
562
563 /**
564  * Examine the costs of the current coloring concerning a MST subtree.
565  * @param ci  The subtree root.
566  * @param col The color of @p ci.
567  * @return    The best coloring for that subtree under the assumption that @p ci has color @p col.
568  */
569 static int examine_subtree_coloring(co2_cloud_irn_t *ci, col_t col)
570 {
571         int *front = FRONT_BASE(ci, col);
572         int cost   = 0;
573         int i;
574
575         for(i = 0; i < ci->mst_n_childs; ++i) {
576                 co2_cloud_irn_t *chld = ci->mst_childs[i];
577                 col_t chld_col        = front[i];
578
579                 cost += examine_subtree_coloring(chld, chld_col);
580                 cost += col != chld_col ? chld->mst_costs : 0;
581         }
582
583         return cost;
584 }
585
586 /**
587  * Determine color badnesses of a node.
588  * Badness means that it is unlikely that the node in question can
589  * obtain a color. The higher the badness, the more unlikely it is that
590  * the node can be assigned that color.
591  * @param ci      The node.
592  * @param badness An integer array as long as there are registers.
593  * @note          The array <code>badness</code> is not cleared.
594  */
595 static void node_color_badness(co2_cloud_irn_t *ci, int *badness)
596 {
597         co2_t *env     = ci->cloud->env;
598         co2_irn_t *ir  = &ci->inh;
599         int n_regs     = env->n_regs;
600         be_ifg_t *ifg  = env->co->cenv->ifg;
601         bitset_t *bs   = bitset_alloca(n_regs);
602
603         bitset_pos_t elm;
604         ir_node *irn;
605         void *it;
606
607         admissible_colors(env, &ci->inh, bs);
608         bitset_flip_all(bs);
609         bitset_foreach(bs, elm)
610                 badness[elm] = ci->costs;
611
612         /* Use constrained/fixed interfering neighbors to influence the color badness */
613         it = be_ifg_neighbours_iter_alloca(ifg);
614         be_ifg_foreach_neighbour(ifg, it, ir->irn, irn) {
615                 co2_irn_t *ni = get_co2_irn(env, irn);
616
617                 admissible_colors(env, ni, bs);
618                 if(bitset_popcnt(bs) == 1) {
619                         bitset_pos_t c = bitset_next_set(bs, 0);
620                         badness[c] += ci->costs;
621                 }
622
623                 else if(ni->fixed) {
624                         col_t c = get_col(env, ni->irn);
625                         badness[c] += ci->costs;
626                 }
627         }
628         be_ifg_neighbours_break(ifg, it);
629 }
630
631 /**
632  * Determine the badness of a MST subtree.
633  * The badness is written into the <code>color_badness</code> array of each node and accumulated in the parents.
634  * @see node_color_badness() for a definition of badness.
635  * @param ci    The root of the subtree.
636  * @param depth Depth for debugging purposes.
637  */
638 static void determine_color_badness(co2_cloud_irn_t *ci, int depth)
639 {
640         co2_t *env     = ci->cloud->env;
641         int i, j;
642
643         node_color_badness(ci, ci->color_badness);
644
645         /* Collect the color badness for the whole subtree */
646         for(i = 0; i < ci->mst_n_childs; ++i) {
647                 co2_cloud_irn_t *child = ci->mst_childs[i];
648                 determine_color_badness(child, depth + 1);
649
650                 for(j = 0; j < env->n_regs; ++j)
651                         ci->color_badness[j] += child->color_badness[j];
652         }
653
654         for(j = 0; j < env->n_regs; ++j)
655                 DBG((env->dbg, LEVEL_2, "%2{firm:indent}%+F col %d badness %d\n", depth, ci->inh.irn, j, ci->color_badness[j]));
656 }
657
658 /**
659  * Unfix all nodes in a MST subtree.
660  */
661 static void unfix_subtree(co2_cloud_irn_t *ci)
662 {
663         int i;
664
665         ci->inh.fixed = 0;
666         for(i = 0; i < ci->mst_n_childs; ++i)
667                 unfix_subtree(ci->mst_childs[i]);
668 }
669
670 static int coalesce_top_down(co2_cloud_irn_t *ci, int child_nr, int depth)
671 {
672         co2_t *env           = ci->cloud->env;
673         col_cost_pair_t *seq = alloca(env->n_regs * sizeof(seq[0]));
674         int is_root          = ci->mst_parent == ci;
675         col_t parent_col     = is_root ? -1 : get_col(env, ci->mst_parent->inh.irn);
676         int min_badness      = INT_MAX;
677         int best_col_costs   = INT_MAX;
678         int best_col         = -1;
679         int n_regs           = env->n_regs;
680         int n_iter           = is_root ? MIN(n_regs, subtree_iter) : 1;
681
682         struct list_head changed;
683         int ok, i, j;
684
685         for(i = 0; i < n_regs; ++i) {
686                 int badness = ci->color_badness[i];
687
688                 seq[i].col   = i;
689                 seq[i].costs = is_color_admissible(env, &ci->inh, i) ? badness : INT_MAX;
690
691                 min_badness = MIN(min_badness, badness);
692         }
693
694         /* If we are not the root and the parent's color is allowed for this node give it top prio. */
695         if(!is_root && is_color_admissible(env, &ci->inh, parent_col))
696                 seq[parent_col].costs = min_badness - 1;
697
698         /* Sort the colors. The will be processed in that ordering. */
699         qsort(seq, env->n_regs, sizeof(seq[0]), col_cost_pair_lt);
700
701         DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}starting top-down coalesce for %+F\n", depth, ci->inh.irn));
702         INIT_LIST_HEAD(&changed);
703         for(i = 0; i < (best_col < 0 ? n_regs : n_iter); ++i) {
704                 col_t col    = seq[i].col;
705                 int add_cost = !is_root && col != parent_col ? ci->mst_costs : 0;
706
707                 int subtree_costs, sum_costs;
708
709                 DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}%+F trying color %d\n", depth, ci->inh.irn, col));
710
711                 unfix_subtree(ci);
712                 INIT_LIST_HEAD(&changed);
713                 ok = change_color_single(env, ci->inh.irn, col, &changed, depth);
714                 if(ok) {
715                         materialize_coloring(&changed);
716                         ci->inh.fixed = 1;
717                 }
718
719                 else
720                         continue;
721
722                 for(j = 0; j < ci->mst_n_childs; ++j) {
723                         co2_cloud_irn_t *child = ci->mst_childs[j];
724                         ok = coalesce_top_down(child, j, depth + 1) >= 0;
725                         if(ok)
726                                 child->inh.fixed = 1;
727                         else
728                                 break;
729                 }
730
731                 /* If the subtree could not be colored, we have to try another color. */
732                 if(!ok)
733                         continue;
734
735                 subtree_costs      = examine_subtree_coloring(ci, col);
736                 sum_costs          = subtree_costs + add_cost;
737                 DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}-> %+F costing %d + %d is ok.\n", depth, ci->inh.irn, subtree_costs, add_cost));
738
739                 if(sum_costs < best_col_costs) {
740                         best_col           = col;
741                         best_col_costs     = sum_costs;
742                         ci->col_costs[col] = subtree_costs;
743                 }
744
745                 if(sum_costs == 0)
746                         break;
747         }
748
749         if(!is_root) {
750                 int *front = FRONT_BASE(ci->mst_parent, parent_col);
751                 front[child_nr] = best_col;
752         }
753
754         return best_col;
755 }
756
757 static void populate_cloud(co2_t *env, co2_cloud_t *cloud, affinity_node_t *a, int curr_costs)
758 {
759         be_ifg_t *ifg       = env->co->cenv->ifg;
760         co2_cloud_irn_t *ci = get_co2_cloud_irn(env, a->irn);
761         int costs           = 0;
762         neighb_t *n;
763
764         if(ci->cloud)
765                 return;
766
767         /* mark the node as visited and add it to the cloud. */
768         ci->cloud   = cloud;
769         list_add(&ci->cloud_list, &cloud->members_head);
770
771         DB((env->dbg, LEVEL_2, "\t%+F\n", ci->inh.irn));
772
773         /* determine the nodes costs */
774         co_gs_foreach_neighb(a, n) {
775                 costs += n->costs;
776                 DB((env->dbg, LEVEL_3, "\t\tneigh %+F cost %d\n", n->irn, n->costs));
777                 if(be_ifg_connected(ifg, a->irn, n->irn))
778                         cloud->inevit += n->costs;
779         }
780
781         /* add the node's cost to the total costs of the cloud. */
782         ci->costs          = costs;
783         cloud->costs      += costs;
784         cloud->n_constr   += is_constrained(env, &ci->inh);
785         cloud->freedom    += bitset_popcnt(get_adm(env, &ci->inh));
786         cloud->max_degree  = MAX(cloud->max_degree, ci->inh.aff->degree);
787         cloud->n_memb++;
788
789         /* If this is the heaviest node in the cloud, set it as the cloud's master. */
790         if(costs >= curr_costs) {
791                 curr_costs    = costs;
792                 cloud->master = ci;
793         }
794
795         /* add all the neighbors of the node to the cloud. */
796         co_gs_foreach_neighb(a, n) {
797                 affinity_node_t *an = get_affinity_info(env->co, n->irn);
798                 assert(an);
799                 populate_cloud(env, cloud, an, curr_costs);
800         }
801 }
802
803 static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a)
804 {
805         co2_cloud_t *cloud = phase_alloc(&env->ph, sizeof(cloud[0]));
806         co2_cloud_irn_t *ci;
807         int i;
808
809         DBG((env->dbg, LEVEL_2, "new cloud with %+F\n", a->irn));
810         memset(cloud, 0, sizeof(cloud[0]));
811         INIT_LIST_HEAD(&cloud->members_head);
812         INIT_LIST_HEAD(&cloud->list);
813         list_add(&cloud->list, &env->cloud_head);
814         cloud->best_costs = INT_MAX;
815         cloud->env = env;
816         env->visited++;
817         populate_cloud(env, cloud, a, 0);
818         cloud->freedom = (cloud->n_memb * env->n_regs) / cloud->freedom;
819
820         /* Also allocate space for the node sequence and compute that sequence. */
821         cloud->seq    = phase_alloc(&env->ph, cloud->n_memb * sizeof(cloud->seq[0]));
822
823         i = 0;
824         list_for_each_entry(co2_cloud_irn_t, ci, &cloud->members_head, cloud_list) {
825                 ci->index       = i;
826                 cloud->seq[i++] = ci;
827         }
828         DBG((env->dbg, LEVEL_2, "cloud cost %d, freedom %f\n", cloud->costs, cloud->freedom));
829
830         return cloud;
831 }
832
833 static void apply_coloring(co2_cloud_irn_t *ci, col_t col, int depth)
834 {
835         ir_node *irn = ci->inh.irn;
836         int *front   = FRONT_BASE(ci, col);
837         int i, ok;
838         struct list_head changed;
839
840         INIT_LIST_HEAD(&changed);
841
842         DBG((ci->cloud->env->dbg, LEVEL_2, "%2{firm:indent}setting %+F to %d\n", depth, irn, col));
843         ok = change_color_single(ci->cloud->env, irn, col, &changed, depth);
844         // assert(ok && "Color changing may not fail while committing the coloring");
845         materialize_coloring(&changed);
846
847         for(i = 0; i < ci->mst_n_childs; ++i) {
848                 apply_coloring(ci->mst_childs[i], front[i], depth + 1);
849         }
850 }
851
852 static co2_cloud_irn_t *find_mst_root(co2_cloud_irn_t *ci)
853 {
854         while(ci != ci->mst_parent)
855                 ci = ci->mst_parent;
856         return ci;
857 }
858
859
860 static void process_cloud(co2_cloud_t *cloud)
861 {
862         co2_t *env  = cloud->env;
863         int n_regs  = env->n_regs;
864         int n_edges = 0;
865         int *mst_edges = xmalloc(cloud->n_memb * cloud->n_memb * sizeof(mst_edges[0]));
866         pdeq *q;
867
868         edge_t *edges;
869         int i;
870         int best_col;
871
872         memset(mst_edges, 0, cloud->n_memb * cloud->n_memb * sizeof(mst_edges[0]));
873
874         /* Collect all edges in the cloud on an obstack and sort the increasingly */
875         obstack_init(&cloud->obst);
876         for(i = 0; i < cloud->n_memb; ++i) {
877                 co2_cloud_irn_t *ci = cloud->seq[i];
878                 neighb_t *n;
879
880                 co_gs_foreach_neighb(ci->inh.aff, n) {
881                         co2_cloud_irn_t *ni = get_co2_cloud_irn(cloud->env, n->irn);
882                         if(ci->index < ni->index) {
883                                 edge_t e;
884                                 e.src   = ci;
885                                 e.tgt   = ni;
886                                 e.costs = n->costs;
887                                 obstack_grow(&cloud->obst, &e, sizeof(e));
888                                 n_edges++;
889                         }
890                 }
891         }
892         edges = obstack_finish(&cloud->obst);
893         qsort(edges, n_edges, sizeof(edges[0]), cmp_edges);
894
895         /* Compute the maximum spanning tree using Kruskal/Union-Find */
896         DBG((env->dbg, LEVEL_2, "computing spanning tree of cloud with master %+F\n", cloud->master->inh.irn));
897         for(i = 0; i < n_edges; ++i) {
898                 edge_t *e        = &edges[i];
899                 co2_cloud_irn_t *rs = find_mst_root(e->src);
900                 co2_cloud_irn_t *rt = find_mst_root(e->tgt);
901
902                 /* if the union/find roots are different */
903                 if(rs != rt) {
904                         int si = e->src->index;
905                         int ti = e->tgt->index;
906
907                         /* unify the sets */
908                         rs->mst_parent = rt;
909                         DBG((env->dbg, LEVEL_2, "\tadding edge %+F -- %+F cost %d\n", rs->inh.irn, rt->inh.irn, e->costs));
910
911                         /* this edge is in the MST, so set it in the bitset. */
912                         mst_edges[si * cloud->n_memb + ti] = e->costs;
913                         mst_edges[ti * cloud->n_memb + si] = e->costs;
914                 }
915         }
916         obstack_free(&cloud->obst, edges);
917
918         cloud->master->mst_parent = cloud->master;
919         cloud->mst_root = cloud->master;
920         q = new_pdeq1(cloud->master);
921         while(!pdeq_empty(q)) {
922                 co2_cloud_irn_t *ci = pdeq_getl(q);
923                 int ofs    = ci->index * cloud->n_memb;
924                 int end    = ofs + cloud->n_memb;
925                 int i;
926
927                 ci->mst_n_childs = 0;
928                 for(i = ofs; i < end; ++i) {
929                         if(mst_edges[i] != 0) {
930                                 int other = i - ofs;
931                                 co2_cloud_irn_t *child = cloud->seq[i - ofs];
932
933                                 /* put the child to the worklist */
934                                 pdeq_putr(q, child);
935
936                                 /* make ci the parent of the child and add the child to the children array of the parent */
937                                 child->mst_parent = ci;
938                                 child->mst_costs  = mst_edges[i];
939                                 ci->mst_n_childs++;
940                                 obstack_ptr_grow(&cloud->obst, child);
941
942                                 mst_edges[other * cloud->n_memb + ci->index] = 0;
943                                 mst_edges[i] = 0;
944                         }
945                 }
946
947                 obstack_ptr_grow(&cloud->obst, NULL);
948                 ci->mst_childs = obstack_finish(&cloud->obst);
949         }
950         del_pdeq(q);
951         free(mst_edges);
952
953
954         DBG((env->dbg, LEVEL_3, "mst:\n"));
955         for(i = 0; i < cloud->n_memb; ++i) {
956                 co2_cloud_irn_t *ci = cloud->seq[i];
957                 DBG((env->dbg, LEVEL_3, "\t%+F -> %+F\n", ci->inh.irn, ci->mst_parent->inh.irn));
958         }
959
960         for(i = 0; i < cloud->n_memb; ++i) {
961                 co2_cloud_irn_t *ci = cloud->seq[i];
962                 int n_childs = ci->mst_n_childs;
963                 int j;
964
965                 ci->col_costs       = obstack_alloc(&cloud->obst, n_regs * sizeof(ci->col_costs[0]));
966                 ci->tmp_coloring    = obstack_alloc(&cloud->obst, n_regs * sizeof(ci->tmp_coloring[0]));
967                 ci->fronts          = obstack_alloc(&cloud->obst, n_regs * n_childs * sizeof(ci->fronts[0]));
968                 ci->color_badness   = obstack_alloc(&cloud->obst, n_regs * sizeof(ci->fronts[0]));
969                 memset(ci->color_badness, 0, n_regs * sizeof(ci->color_badness[0]));
970                 memset(ci->col_costs,     0, n_regs * sizeof(ci->col_costs[0]));
971                 memset(ci->tmp_coloring,  0, n_regs * sizeof(ci->tmp_coloring[0]));
972                 memset(ci->fronts,        0, n_regs * n_childs * sizeof(ci->fronts[0]));
973
974                 for(j = 0; j < env->n_regs; j++)
975                         ci->col_costs[j] = INT_MAX;
976
977         }
978
979         determine_color_badness(cloud->mst_root, 0);
980         best_col = coalesce_top_down(cloud->mst_root, -1, 0);
981         unfix_subtree(cloud->mst_root);
982         apply_coloring(cloud->mst_root, best_col, 0);
983
984         /* The coloring should represent the one with the best costs. */
985         //materialize_coloring(&changed);
986         DBG((env->dbg, LEVEL_2, "\tbest coloring for root %+F was %d costing %d\n",
987                 cloud->mst_root->inh.irn, best_col, examine_subtree_coloring(cloud->mst_root, best_col)));
988
989         /* Fix all nodes in the cloud. */
990         for(i = 0; i < cloud->n_memb; ++i)
991                 cloud->seq[i]->inh.fixed = 1;
992
993         /* Free all space used while optimizing this cloud. */
994         obstack_free(&cloud->obst, NULL);
995 }
996
997 static int cloud_costs(co2_cloud_t *cloud)
998 {
999         int i, costs = 0;
1000         neighb_t *n;
1001
1002         for(i = 0; i < cloud->n_memb; ++i) {
1003                 co2_irn_t *ci = (co2_irn_t *) cloud->seq[i];
1004                 col_t col = get_col(cloud->env, ci->irn);
1005                 co_gs_foreach_neighb(ci->aff, n) {
1006                         col_t n_col = get_col(cloud->env, n->irn);
1007                         costs += col != n_col ? n->costs : 0;
1008                 }
1009         }
1010
1011         return costs / 2;
1012 }
1013
1014 static void process(co2_t *env)
1015 {
1016         affinity_node_t *a;
1017         co2_cloud_t *pos;
1018         co2_cloud_t **clouds;
1019         int n_clouds;
1020         int i;
1021         int init_costs  = 0;
1022         int all_costs   = 0;
1023         int final_costs = 0;
1024
1025         n_clouds = 0;
1026         co_gs_foreach_aff_node(env->co, a) {
1027                 co2_cloud_irn_t *ci = get_co2_cloud_irn(env, a->irn);
1028
1029                 if(!ci->cloud) {
1030                         co2_cloud_t *cloud = new_cloud(env, a);
1031                         n_clouds++;
1032                 }
1033         }
1034
1035         i = 0;
1036         clouds = xmalloc(n_clouds * sizeof(clouds[0]));
1037         list_for_each_entry(co2_cloud_t, pos, &env->cloud_head, list)
1038                 clouds[i++] = pos;
1039         qsort(clouds, n_clouds, sizeof(clouds[0]), cmp_clouds_gt);
1040
1041         for(i = 0; i < n_clouds; ++i) {
1042                 init_costs  += cloud_costs(clouds[i]);
1043
1044                 /* Process the cloud. */
1045                 process_cloud(clouds[i]);
1046
1047                 all_costs   += clouds[i]->costs;
1048                 final_costs += cloud_costs(clouds[i]);
1049
1050                 /* Dump the IFG if the user demanded it. */
1051                 if (dump_flags & DUMP_CLOUD) {
1052                         char buf[256];
1053                         FILE *f;
1054
1055                         ir_snprintf(buf, sizeof(buf), "ifg_%F_%s_cloud_%d.dot", env->co->irg, env->co->cls->name, i);
1056                         if(f = fopen(buf, "wt")) {
1057                                 be_ifg_dump_dot(env->co->cenv->ifg, env->co->irg, f, &ifg_dot_cb, env);
1058                                 fclose(f);
1059                         }
1060                 }
1061         }
1062
1063         DB((env->dbg, LEVEL_1, "all costs: %d, init costs: %d, final costs: %d\n", all_costs, init_costs, final_costs));
1064
1065         xfree(clouds);
1066 }
1067
1068 static void writeback_colors(co2_t *env)
1069 {
1070         const arch_env_t *aenv = env->co->aenv;
1071         co2_irn_t *irn;
1072
1073         for(irn = env->touched; irn; irn = irn->touched_next) {
1074                 const arch_register_t *reg = arch_register_for_index(env->co->cls, irn->orig_col);
1075                 arch_set_irn_register(aenv, irn->irn, reg);
1076         }
1077 }
1078
1079
1080 /*
1081   ___ _____ ____   ____   ___ _____   ____                        _
1082  |_ _|  ___/ ___| |  _ \ / _ \_   _| |  _ \ _   _ _ __ ___  _ __ (_)_ __   __ _
1083   | || |_ | |  _  | | | | | | || |   | | | | | | | '_ ` _ \| '_ \| | '_ \ / _` |
1084   | ||  _|| |_| | | |_| | |_| || |   | |_| | |_| | | | | | | |_) | | | | | (_| |
1085  |___|_|   \____| |____/ \___/ |_|   |____/ \__,_|_| |_| |_| .__/|_|_| |_|\__, |
1086                                                            |_|            |___/
1087 */
1088
1089 static const char *get_dot_color_name(int col)
1090 {
1091         static const char *names[] = {
1092                 "blue",
1093                 "red",
1094                 "green",
1095                 "yellow",
1096                 "cyan",
1097                 "magenta",
1098                 "orange",
1099                 "chocolate",
1100                 "beige",
1101                 "navy",
1102                 "darkgreen",
1103                 "darkred",
1104                 "lightPink",
1105                 "chartreuse",
1106                 "lightskyblue",
1107                 "linen",
1108                 "pink",
1109                 "lightslateblue",
1110                 "mintcream",
1111                 "red",
1112                 "darkolivegreen",
1113                 "mediumblue",
1114                 "mistyrose",
1115                 "salmon",
1116                 "darkseagreen",
1117                 "mediumslateblue"
1118                 "moccasin",
1119                 "tomato",
1120                 "forestgreen",
1121                 "darkturquoise",
1122                 "palevioletred"
1123         };
1124
1125         return col < sizeof(names)/sizeof(names[0]) ? names[col] : "white";
1126 }
1127
1128 static const char *get_dot_shape_name(co2_t *env, co2_irn_t *ci)
1129 {
1130         arch_register_req_t req;
1131
1132         arch_get_register_req(env->co->aenv, &req, ci->irn, BE_OUT_POS(0));
1133         if(arch_register_req_is(&req, limited))
1134                 return "diamond";
1135
1136         if(ci->fixed)
1137                 return "rectangle";
1138
1139         if(ci->tmp_fixed)
1140                 return "hexagon";
1141
1142         return "ellipse";
1143 }
1144
1145 static void ifg_dump_graph_attr(FILE *f, void *self)
1146 {
1147         fprintf(f, "overlay=false");
1148 }
1149
1150 static int ifg_is_dump_node(void *self, ir_node *irn)
1151 {
1152         co2_t *env = self;
1153         return !arch_irn_is(env->co->aenv, irn, ignore);
1154 }
1155
1156 static void ifg_dump_node_attr(FILE *f, void *self, ir_node *irn)
1157 {
1158         co2_t *env    = self;
1159         co2_irn_t *ci = get_co2_irn(env, irn);
1160         int peri      = 1;
1161
1162         char buf[128] = "";
1163
1164         if(ci->aff) {
1165                 co2_cloud_irn_t *cci = (void *) ci;
1166                 if (cci->cloud && cci->cloud->mst_root == cci)
1167                         peri = 2;
1168
1169                 if(cci->cloud && cci->cloud->mst_root)
1170                         snprintf(buf, sizeof(buf), "%+F", cci->cloud->mst_root->inh.irn);
1171         }
1172
1173         ir_fprintf(f, "label=\"%+F%s\" style=filled peripheries=%d color=%s shape=%s", irn, buf, peri,
1174                 get_dot_color_name(get_col(env, irn)), get_dot_shape_name(env, ci));
1175 }
1176
1177 static void ifg_dump_at_end(FILE *file, void *self)
1178 {
1179         co2_t *env = self;
1180         affinity_node_t *a;
1181
1182         co_gs_foreach_aff_node(env->co, a) {
1183                 co2_cloud_irn_t *ai = get_co2_cloud_irn(env, a->irn);
1184                 int idx = get_irn_idx(a->irn);
1185                 neighb_t *n;
1186
1187                 if(ai->mst_parent != ai)
1188                         fprintf(file, "\tn%d -- n%d [style=dotted color=blue arrowhead=normal];\n", idx, get_irn_idx(ai->mst_parent->inh.irn));
1189
1190                 co_gs_foreach_neighb(a, n) {
1191                         int nidx = get_irn_idx(n->irn);
1192                         co2_cloud_irn_t *ci = get_co2_cloud_irn(env, n->irn);
1193
1194                         if(idx < nidx) {
1195                                 const char *color = get_col(env, a->irn) == get_col(env, n->irn) ? "black" : "red";
1196                                 const char *arr = "arrowhead=dot arrowtail=dot";
1197
1198                                 if(ci->mst_parent == ai)
1199                                         arr = "arrowtail=normal";
1200                                 else if(ai->mst_parent == ci)
1201                                         arr = "arrowhead=normal";
1202
1203                                 fprintf(file, "\tn%d -- n%d [label=\"%d\" %s style=dashed color=%s weight=0.01];\n", idx, nidx, n->costs, arr, color);
1204                         }
1205                 }
1206         }
1207 }
1208
1209
1210 static be_ifg_dump_dot_cb_t ifg_dot_cb = {
1211         ifg_is_dump_node,
1212         ifg_dump_graph_attr,
1213         ifg_dump_node_attr,
1214         NULL,
1215         NULL,
1216         ifg_dump_at_end
1217 };
1218
1219
1220 int co_solve_heuristic_new(copy_opt_t *co)
1221 {
1222         char buf[256];
1223         co2_t env;
1224         FILE *f;
1225
1226         phase_init(&env.ph, "co2", co->cenv->birg->irg, PHASE_DEFAULT_GROWTH, co2_irn_init);
1227         env.touched     = NULL;
1228         env.visited     = 0;
1229         env.co          = co;
1230         env.n_regs      = co->cls->n_regs;
1231         env.ignore_regs = bitset_alloca(co->cls->n_regs);
1232         arch_put_non_ignore_regs(co->aenv, co->cls, env.ignore_regs);
1233         bitset_flip_all(env.ignore_regs);
1234         be_abi_put_ignore_regs(co->cenv->birg->abi, co->cls, env.ignore_regs);
1235         FIRM_DBG_REGISTER(env.dbg, "firm.be.co2");
1236         INIT_LIST_HEAD(&env.cloud_head);
1237
1238         if(dump_flags & DUMP_BEFORE) {
1239                 ir_snprintf(buf, sizeof(buf), "ifg_%F_%s_before.dot", co->irg, co->cls->name);
1240                 f = fopen(buf, "wt");
1241                 if (f != NULL) {
1242                         be_ifg_dump_dot(co->cenv->ifg, co->irg, f, &ifg_dot_cb, &env);
1243                         fclose(f);
1244                 }
1245         }
1246
1247         process(&env);
1248
1249         if(dump_flags & DUMP_AFTER) {
1250                 ir_snprintf(buf, sizeof(buf), "ifg_%F_%s_after.dot", co->irg, co->cls->name);
1251                 f = fopen(buf, "wt");
1252                 if (f != NULL) {
1253                         be_ifg_dump_dot(co->cenv->ifg, co->irg, f, &ifg_dot_cb, &env);
1254                         fclose(f);
1255                 }
1256         }
1257
1258         writeback_colors(&env);
1259         phase_free(&env.ph);
1260         return 0;
1261 }