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