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