becopyopt: Reduce indirection.
[libfirm] / ir / be / becopyheur2.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief       More experiments on coalescing.
9  * @author      Sebastian Hack
10  * @date        14.04.2006
11  */
12 #include "config.h"
13
14 #include "lc_opts.h"
15 #include "lc_opts_enum.h"
16
17 #include <stdlib.h>
18 #include <limits.h>
19
20 #include "beintlive_t.h"
21 #include "beirg.h"
22 #include "list.h"
23 #include "pdeq.h"
24 #include "bitset.h"
25 #include "raw_bitset.h"
26
27 #include "debug.h"
28 #include "bitfiddle.h"
29
30 #include "irgraph_t.h"
31 #include "irnode_t.h"
32 #include "irprintf.h"
33 #include "util.h"
34 #include "irtools.h"
35 #include "irnodemap.h"
36 #include "be_t.h"
37 #include "bemodule.h"
38 #include "beabi.h"
39 #include "benode.h"
40 #include "becopyopt.h"
41 #include "becopyopt_t.h"
42 #include "bechordal_t.h"
43
44 #define DUMP_BEFORE 1
45 #define DUMP_AFTER  2
46 #define DUMP_CLOUD  4
47 #define DUMP_ALL    2 * DUMP_CLOUD - 1
48
49 static unsigned dump_flags      = 0;
50 static int      subtree_iter    = 4;
51 static int      max_depth       = 20;
52 static double   constr_factor   = 0.9;
53
54 static const lc_opt_enum_mask_items_t dump_items[] = {
55         { "before",  DUMP_BEFORE },
56         { "after",   DUMP_AFTER  },
57         { "cloud",   DUMP_CLOUD  },
58         { "all",     DUMP_ALL    },
59         { NULL,      0 }
60 };
61
62 static lc_opt_enum_mask_var_t dump_var = {
63         &dump_flags, dump_items
64 };
65
66 static const lc_opt_table_entry_t options[] = {
67         LC_OPT_ENT_ENUM_MASK("dump", "dump ifg cloud",                                         &dump_var),
68         LC_OPT_ENT_INT      ("iter", "iterations for subtree nodes",                           &subtree_iter),
69         LC_OPT_ENT_DBL      ("cf",   "factor of constraint importance (between 0.0 and 1.0)",  &constr_factor),
70         LC_OPT_ENT_INT      ("max",  "maximum recursion depth",                                &max_depth),
71         LC_OPT_LAST
72 };
73
74 /*
75   ____  _             _
76  / ___|| |_ __ _ _ __| |_
77  \___ \| __/ _` | '__| __|
78   ___) | || (_| | |  | |_
79  |____/ \__\__,_|_|   \__|
80
81 */
82
83 #define INFEASIBLE(cost) ((cost) == INT_MAX)
84
85 typedef unsigned col_t;
86
87 typedef struct co2_irn_t       co2_irn_t;
88 typedef struct co2_cloud_t     co2_cloud_t;
89 typedef struct co2_cloud_irn_t co2_cloud_irn_t;
90
91 typedef struct {
92         col_t col;
93         int costs;
94 } col_cost_pair_t;
95
96 typedef struct {
97         ir_nodemap     map;
98         struct obstack obst;
99         copy_opt_t *co;
100         bitset_t   *allocatable_regs;
101         co2_irn_t  *touched;
102         int         visited;
103         int         n_regs;
104         struct list_head cloud_head;
105         DEBUG_ONLY(firm_dbg_module_t *dbg;)
106 } co2_t;
107
108 struct co2_irn_t {
109         const ir_node   *irn;
110         affinity_node_t *aff;
111         co2_irn_t       *touched_next;
112         col_t            tmp_col;
113         col_t            orig_col;
114         bitset_t        *adm_cache;
115         unsigned         fixed          : 1;
116         unsigned         tmp_fixed      : 1;
117         struct list_head changed_list;
118 };
119
120 struct co2_cloud_irn_t {
121         struct co2_irn_t   inh;
122         co2_cloud_t       *cloud;
123         int                visited;
124         int                index;
125         co2_cloud_irn_t   *mst_parent;
126         int                mst_costs;
127         int                mst_n_childs;
128         co2_cloud_irn_t  **mst_childs;
129         int               *col_costs;
130         int                costs;
131         int               *fronts;
132         int               *color_badness;
133         col_cost_pair_t   *tmp_coloring;
134         struct list_head   cloud_list;
135         struct list_head   mst_list;
136 };
137
138 struct co2_cloud_t {
139         co2_t            *env;
140         struct obstack    obst;
141         int               costs;
142         int               mst_costs;
143         int               inevit;
144         int               best_costs;
145         int               n_memb;
146         int               ticks;
147         double            freedom;
148         co2_cloud_irn_t  *master;
149         co2_cloud_irn_t  *mst_root;
150         co2_cloud_irn_t **seq;
151         struct list_head  members_head;
152         struct list_head  list;
153 };
154
155 typedef struct {
156         co2_cloud_irn_t *src, *tgt;
157         int costs;
158 } edge_t;
159
160 #define FRONT_BASE(ci,col)  ((ci)->fronts + col * (ci)->mst_n_childs)
161
162 static co2_irn_t *get_co2_irn(co2_t *env, const ir_node *node)
163 {
164         co2_irn_t *ci = ir_nodemap_get(co2_irn_t, &env->map, node);
165         if (ci == NULL) {
166                 ci = OALLOCZ(&env->obst, co2_irn_t);
167
168                 INIT_LIST_HEAD(&ci->changed_list);
169                 ci->touched_next = env->touched;
170                 ci->orig_col     = get_irn_col(node);
171                 env->touched     = ci;
172                 ci->irn          = node;
173                 ci->aff          = NULL;
174
175                 ir_nodemap_insert(&env->map, node, ci);
176         }
177         return ci;
178 }
179
180 static co2_cloud_irn_t *get_co2_cloud_irn(co2_t *env, const ir_node *node)
181 {
182         co2_cloud_irn_t *ci = ir_nodemap_get(co2_cloud_irn_t, &env->map, node);
183         if (ci == NULL) {
184                 ci = OALLOCZ(&env->obst, co2_cloud_irn_t);
185
186                 INIT_LIST_HEAD(&ci->inh.changed_list);
187                 ci->inh.touched_next = env->touched;
188                 ci->inh.orig_col     = get_irn_col(node);
189                 env->touched         = &ci->inh;
190                 ci->inh.irn          = node;
191                 ci->inh.aff          = get_affinity_info(env->co, node);
192
193                 INIT_LIST_HEAD(&ci->cloud_list);
194                 ci->mst_parent = ci;
195
196                 ir_nodemap_insert(&env->map, node, ci);
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 = (const co2_cloud_t*const*)a;
206         const co2_cloud_t * const *q = (const co2_cloud_t*const*)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 = (const col_cost_pair_t*)a;
219         const col_cost_pair_t *q = (const col_cost_pair_t*)b;
220         int c = p->costs;
221         int d = q->costs;
222         return QSORT_CMP(c, d);
223 }
224
225 static int cmp_edges(const void *a, const void *b)
226 {
227         const edge_t *p = (const edge_t*)a;
228         const edge_t *q = (const edge_t*)b;
229         return QSORT_CMP(q->costs, p->costs);
230 }
231
232 static col_t get_col(co2_t *env, const 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, const 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 == NULL) {
247                 const arch_register_req_t *req;
248                 ci->adm_cache = bitset_obstack_alloc(&env->obst, env->n_regs);
249                 req = arch_get_irn_register_req(ci->irn);
250
251                 if (arch_register_req_is(req, limited)) {
252                         int i, n;
253
254                         n = env->n_regs;
255                         for (i = 0; i < n; ++i) {
256                                 if (rbitset_is_set(req->limited, i))
257                                         bitset_set(ci->adm_cache, i);
258                         }
259                 } else {
260                         bitset_copy(ci->adm_cache, env->allocatable_regs);
261                 }
262         }
263
264         return ci->adm_cache;
265 }
266
267 static inline bitset_t *admissible_colors(co2_t *env, co2_irn_t *ci, bitset_t *bs)
268 {
269         bitset_copy(bs, get_adm(env, ci));
270         return bs;
271 }
272
273 static inline int is_color_admissible(co2_t *env, co2_irn_t *ci, col_t col)
274 {
275         bitset_t *bs = get_adm(env, ci);
276         return bitset_is_set(bs, col);
277 }
278
279 static void incur_constraint_costs(co2_t *env, const ir_node *irn, col_cost_pair_t *col_costs, int costs)
280 {
281         const arch_register_req_t *req = arch_get_irn_register_req(irn);
282
283         if (arch_register_req_is(req, limited)) {
284                 unsigned n_regs   = env->co->cls->n_regs;
285                 unsigned n_constr = 0;
286                 unsigned i;
287
288                 n_constr = rbitset_popcount(req->limited, n_regs);
289                 for (i = 0; i < n_regs; ++i) {
290                         if (rbitset_is_set(req->limited, i)) {
291                                 col_costs[i].costs = add_saturated(col_costs[i].costs, costs / n_constr);
292                         }
293                 }
294         }
295 }
296
297 /**
298  * Determine costs which shall indicate how cheap/expensive it is to try
299  * to assign a node some color.
300  * The costs are computed for all colors. INT_MAX means that it is impossible
301  * to give the node that specific color.
302  *
303  * @param env       The co2 this pointer.
304  * @param irn       The node.
305  * @param col_costs An array of colors x costs where the costs are written to.
306  */
307 static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *col_costs)
308 {
309         const ir_node *irn = ci->irn;
310         be_ifg_t *ifg      = env->co->cenv->ifg;
311         int n_regs         = env->co->cls->n_regs;
312         affinity_node_t *a = ci->aff;
313
314         neighbours_iter_t it;
315         int i;
316
317         /* Put all forbidden colors into the aux bitset. */
318         bitset_t *const admissible = bitset_alloca(n_regs);
319         admissible_colors(env, ci, admissible);
320
321         for (i = 0; i < n_regs; ++i) {
322                 col_costs[i].col   = i;
323                 col_costs[i].costs = 0;
324         }
325
326         if (a) {
327                 co_gs_foreach_neighb(a, n) {
328                         if (color_is_fix(env, n->irn)) {
329                                 col_t col = get_col(env, n->irn);
330                                 col_costs[col].costs = add_saturated(col_costs[col].costs, -n->costs * 128);
331                         }
332
333                         incur_constraint_costs(env, n->irn, col_costs, -n->costs);
334                 }
335         }
336
337         be_ifg_foreach_neighbour(ifg, &it, irn, pos) {
338                 col_t col = get_col(env, pos);
339                 if (color_is_fix(env, pos)) {
340                         col_costs[col].costs  = INT_MAX;
341                 }
342                 else {
343                         incur_constraint_costs(env, pos, col_costs, INT_MAX);
344                         col_costs[col].costs = add_saturated(col_costs[col].costs, 8 * be_ifg_degree(ifg, pos));
345                 }
346         }
347         be_ifg_neighbours_break(&it);
348
349         /* Set the costs to infinity for each color which is not allowed at this node. */
350         bitset_foreach_clear(admissible, elm) {
351                 col_costs[elm].costs  = INT_MAX;
352         }
353
354 }
355
356 static void single_color_cost(co2_t *env, co2_irn_t *ci, col_t col, col_cost_pair_t *seq)
357 {
358         int n_regs = env->co->cls->n_regs;
359         int i;
360
361         for (i = 0; i < n_regs; ++i) {
362                 seq[i].col   = i;
363                 seq[i].costs = INT_MAX;
364         }
365
366         (void) ci;
367         assert(is_color_admissible(env, ci, col));
368         seq[col].col = 0;
369         seq[0].col   = col;
370         seq[0].costs = 0;
371 }
372
373 static void reject_coloring(struct list_head *h)
374 {
375         list_for_each_entry(co2_irn_t, pos, h, changed_list)
376                 pos->tmp_fixed = 0;
377 }
378
379 static void materialize_coloring(struct list_head *h)
380 {
381         list_for_each_entry(co2_irn_t, pos, h, changed_list) {
382                 pos->orig_col  = pos->tmp_col;
383                 pos->tmp_fixed = 0;
384         }
385 }
386
387 static int change_color_not(co2_t *env, const ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth);
388
389 static int recolor(co2_t *env, const ir_node *irn, col_cost_pair_t *col_list, struct list_head *parent_changed, int depth)
390 {
391         int n_regs         = env->co->cls->n_regs;
392         be_ifg_t *ifg      = env->co->cenv->ifg;
393         co2_irn_t *ci      = get_co2_irn(env, irn);
394         int res            = 0;
395
396         int i;
397
398         if (depth >= max_depth)
399           return 0;
400
401         for (i = 0; i < n_regs; ++i) {
402                 col_t tgt_col  = col_list[i].col;
403                 unsigned costs = col_list[i].costs;
404                 int neigh_ok   = 1;
405
406                 struct list_head changed;
407                 neighbours_iter_t it;
408
409                 DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying color %d(%d) on %+F\n", depth, tgt_col, costs, irn));
410
411                 /* If the costs for that color (and all successive) are infinite, bail out we won't make it anyway. */
412                 if (INFEASIBLE(costs)) {
413                         DB((env->dbg, LEVEL_4, "\t\t%2{firm:indent}color %d infeasible\n", depth, tgt_col));
414                         ci->tmp_fixed = 0;
415                         return 0;
416                 }
417
418                 /* Set the new color of the node and mark the node as temporarily fixed. */
419                 ci->tmp_col     = tgt_col;
420                 ci->tmp_fixed   = 1;
421
422                 /*
423                 If that color has costs > 0, there's at least one neighbor having that color,
424                 so we will try to change the neighbors' colors, too.
425                 */
426                 INIT_LIST_HEAD(&changed);
427                 list_add(&ci->changed_list, &changed);
428
429                 be_ifg_foreach_neighbour(ifg, &it, irn, n) {
430
431                         /* try to re-color the neighbor if it has the target color. */
432                         if (get_col(env, n) == tgt_col) {
433                                 struct list_head tmp;
434
435                                 /*
436                                 Try to change the color of the neighbor and record all nodes which
437                                 get changed in the tmp list. Add this list to the "changed" list for
438                                 that color. If we did not succeed to change the color of the neighbor,
439                                 we bail out and try the next color.
440                                 */
441                                 INIT_LIST_HEAD(&tmp);
442                                 neigh_ok = change_color_not(env, n, tgt_col, &tmp, depth + 1);
443                                 list_splice(&tmp, &changed);
444                                 if (!neigh_ok)
445                                         break;
446                         }
447                 }
448                 be_ifg_neighbours_break(&it);
449
450                 /*
451                 We managed to assign the target color to all neighbors, so from the perspective
452                 of the current node, every thing was ok and we can return safely.
453                 */
454                 if (neigh_ok) {
455                         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}color %d(%d) was ok\n", depth, tgt_col, costs));
456                         list_splice(&changed, parent_changed);
457                         res = 1;
458                         break;
459                 }
460
461                 /*
462                 If not, that color did not succeed and we unfix all nodes we touched
463                 by traversing the changed list and setting tmp_fixed to 0 for these nodes.
464                 */
465                 else
466                         reject_coloring(&changed);
467         }
468
469         return res;
470 }
471
472 static int change_color_not(co2_t *env, const ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth)
473 {
474         co2_irn_t *ci = get_co2_irn(env, irn);
475         int res       = 0;
476         col_t col     = get_col(env, irn);
477
478         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}clearing %+F(%d) of color %d\n", depth, irn, col, not_col));
479
480         /* the node does not have to forbidden color. That's fine, mark it as visited and return. */
481         if (col != not_col) {
482                 if (!ci->tmp_fixed) {
483                         ci->tmp_col     = col;
484                         ci->tmp_fixed   = 1;
485                 }
486
487                 list_add(&ci->changed_list, parent_changed);
488                 return 1;
489         }
490
491         /* The node has the color it should not have _and_ has not been visited yet. */
492         if (!color_is_fix(env, irn)) {
493                 int n_regs            = env->co->cls->n_regs;
494                 col_cost_pair_t *csts = ALLOCAN(col_cost_pair_t, n_regs);
495
496                 /* Get the costs for giving the node a specific color. */
497                 determine_color_costs(env, ci, csts);
498
499                 /* Since the node must not have the not_col, set the costs for that color to "infinity" */
500                 csts[not_col].costs = INT_MAX;
501
502                 /* sort the colors according costs, cheapest first. */
503                 qsort(csts, n_regs, sizeof(csts[0]), col_cost_pair_lt);
504
505                 /* Try recoloring the node using the color list. */
506                 res = recolor(env, irn, csts, parent_changed, depth);
507         }
508
509         /* If we came here, everything went ok. */
510         return res;
511 }
512
513 static int change_color_single(co2_t *env, const ir_node *irn, col_t tgt_col, struct list_head *parent_changed, int depth)
514 {
515         co2_irn_t *ci = get_co2_irn(env, irn);
516         col_t col     = get_col(env, irn);
517         int res       = 0;
518
519         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying to set %+F(%d) to color %d\n", depth, irn, col, tgt_col));
520
521         /* the node has the wanted color. That's fine, mark it as visited and return. */
522         if (col == tgt_col) {
523                 if (!ci->tmp_fixed) {
524                         ci->tmp_col     = col;
525                         ci->tmp_fixed   = 1;
526                         list_add(&ci->changed_list, parent_changed);
527                 }
528
529                 res = 1;
530                 goto end;
531         }
532
533         if (!color_is_fix(env, irn) && is_color_admissible(env, ci, tgt_col)) {
534                 int n_regs           = env->co->cls->n_regs;
535                 col_cost_pair_t *seq = ALLOCAN(col_cost_pair_t, n_regs);
536
537                 /* Get the costs for giving the node a specific color. */
538                 single_color_cost(env, ci, tgt_col, seq);
539
540                 /* Try recoloring the node using the color list. */
541                 res = recolor(env, irn, seq, parent_changed, depth);
542
543         }
544
545 end:
546         DB((env->dbg, LEVEL_3, "\t\t%2{firm:indent}color %d %s for %+F\n", depth, tgt_col, res ? "was ok" : "failed", irn));
547         return res;
548 }
549
550 /**
551  * Examine the costs of the current coloring concerning a MST subtree.
552  * @param ci  The subtree root.
553  * @param col The color of @p ci.
554  * @return    The best coloring for that subtree under the assumption that @p ci has color @p col.
555  */
556 static int examine_subtree_coloring(co2_cloud_irn_t *ci, col_t col)
557 {
558         int *front = FRONT_BASE(ci, col);
559         int cost   = 0;
560         int i;
561
562         for (i = 0; i < ci->mst_n_childs; ++i) {
563                 co2_cloud_irn_t *chld = ci->mst_childs[i];
564                 col_t chld_col        = front[i];
565
566                 cost += examine_subtree_coloring(chld, chld_col);
567                 cost += col != chld_col ? chld->mst_costs : 0;
568         }
569
570         return cost;
571 }
572
573 /**
574  * Determine color badnesses of a node.
575  * Badness means that it is unlikely that the node in question can
576  * obtain a color. The higher the badness, the more unlikely it is that
577  * the node can be assigned that color.
578  * @param ci      The node.
579  * @param badness An integer array as long as there are registers.
580  * @note          The array <code>badness</code> is not cleared.
581  */
582 static void node_color_badness(co2_cloud_irn_t *ci, int *badness)
583 {
584         co2_t *env     = ci->cloud->env;
585         co2_irn_t *ir  = &ci->inh;
586         int n_regs     = env->n_regs;
587         be_ifg_t *ifg  = env->co->cenv->ifg;
588         bitset_t *bs   = bitset_alloca(n_regs);
589
590         neighbours_iter_t it;
591
592         admissible_colors(env, &ci->inh, bs);
593         bitset_foreach_clear(bs, elm)
594                 badness[elm] = ci->costs;
595
596         /* Use constrained/fixed interfering neighbors to influence the color badness */
597         be_ifg_foreach_neighbour(ifg, &it, ir->irn, irn) {
598                 co2_irn_t *ni = get_co2_irn(env, irn);
599
600                 admissible_colors(env, ni, bs);
601                 if (bitset_popcount(bs) == 1) {
602                         size_t c = bitset_next_set(bs, 0);
603                         badness[c] += ci->costs;
604                 }
605
606                 else if (ni->fixed) {
607                         col_t c = get_col(env, ni->irn);
608                         badness[c] += ci->costs;
609                 }
610         }
611         be_ifg_neighbours_break(&it);
612 }
613
614 /**
615  * Determine the badness of a MST subtree.
616  * The badness is written into the <code>color_badness</code> array of each node and accumulated in the parents.
617  * @see node_color_badness() for a definition of badness.
618  * @param ci    The root of the subtree.
619  * @param depth Depth for debugging purposes.
620  */
621 static void determine_color_badness(co2_cloud_irn_t *ci, int depth)
622 {
623         co2_t *env     = ci->cloud->env;
624         int i, j;
625
626         node_color_badness(ci, ci->color_badness);
627
628         /* Collect the color badness for the whole subtree */
629         for (i = 0; i < ci->mst_n_childs; ++i) {
630                 co2_cloud_irn_t *child = ci->mst_childs[i];
631                 determine_color_badness(child, depth + 1);
632
633                 for (j = 0; j < env->n_regs; ++j)
634                         ci->color_badness[j] += child->color_badness[j];
635         }
636
637         for (j = 0; j < env->n_regs; ++j)
638                 DBG((env->dbg, LEVEL_2, "%2{firm:indent}%+F col %d badness %d\n", depth, ci->inh.irn, j, ci->color_badness[j]));
639 }
640
641 /**
642  * Unfix all nodes in a MST subtree.
643  */
644 static void unfix_subtree(co2_cloud_irn_t *ci)
645 {
646         int i;
647
648         ci->inh.fixed = 0;
649         for (i = 0; i < ci->mst_n_childs; ++i)
650                 unfix_subtree(ci->mst_childs[i]);
651 }
652
653 static int coalesce_top_down(co2_cloud_irn_t *ci, int child_nr, int depth)
654 {
655         co2_t *env           = ci->cloud->env;
656         col_cost_pair_t *seq = ALLOCAN(col_cost_pair_t, env->n_regs);
657         int is_root          = ci->mst_parent == ci;
658         col_t parent_col     = is_root ? (col_t) -1 : get_col(env, ci->mst_parent->inh.irn);
659         int min_badness      = INT_MAX;
660         int best_col_costs   = INT_MAX;
661         int best_col         = -1;
662         int n_regs           = env->n_regs;
663         int n_iter           = is_root ? MIN(n_regs, subtree_iter) : 1;
664
665         struct list_head changed;
666         int ok, i, j;
667
668         for (i = 0; i < n_regs; ++i) {
669                 int badness = ci->color_badness[i];
670
671                 seq[i].col   = i;
672                 seq[i].costs = is_color_admissible(env, &ci->inh, i) ? badness : INT_MAX;
673
674                 min_badness = MIN(min_badness, badness);
675         }
676
677         /* If we are not the root and the parent's color is allowed for this node give it top prio. */
678         if (!is_root && is_color_admissible(env, &ci->inh, parent_col))
679                 seq[parent_col].costs = min_badness - 1;
680
681         /* Sort the colors. The will be processed in that ordering. */
682         qsort(seq, env->n_regs, sizeof(seq[0]), col_cost_pair_lt);
683
684         DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}starting top-down coalesce for %+F\n", depth, ci->inh.irn));
685         INIT_LIST_HEAD(&changed);
686         for (i = 0; i < (best_col < 0 ? n_regs : n_iter); ++i) {
687                 col_t col    = seq[i].col;
688                 int add_cost = !is_root && col != parent_col ? ci->mst_costs : 0;
689
690                 int subtree_costs, sum_costs;
691
692                 DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}%+F trying color %d\n", depth, ci->inh.irn, col));
693
694                 unfix_subtree(ci);
695                 INIT_LIST_HEAD(&changed);
696                 ok = change_color_single(env, ci->inh.irn, col, &changed, depth);
697                 if (ok) {
698                         materialize_coloring(&changed);
699                         ci->inh.fixed = 1;
700                 }
701
702                 else
703                         continue;
704
705                 for (j = 0; j < ci->mst_n_childs; ++j) {
706                         co2_cloud_irn_t *child = ci->mst_childs[j];
707                         ok = coalesce_top_down(child, j, depth + 1) >= 0;
708                         if (ok)
709                                 child->inh.fixed = 1;
710                         else
711                                 break;
712                 }
713
714                 /* If the subtree could not be colored, we have to try another color. */
715                 if (!ok)
716                         continue;
717
718                 subtree_costs      = examine_subtree_coloring(ci, col);
719                 sum_costs          = subtree_costs + add_cost;
720                 DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}-> %+F costing %d + %d is ok.\n", depth, ci->inh.irn, subtree_costs, add_cost));
721
722                 if (sum_costs < best_col_costs) {
723                         best_col           = col;
724                         best_col_costs     = sum_costs;
725                         ci->col_costs[col] = subtree_costs;
726                 }
727
728                 if (sum_costs == 0)
729                         break;
730         }
731
732         if (!is_root) {
733                 int *front = FRONT_BASE(ci->mst_parent, parent_col);
734                 front[child_nr] = best_col;
735         }
736
737         return best_col;
738 }
739
740 static void populate_cloud(co2_t *env, co2_cloud_t *cloud, affinity_node_t *a, int curr_costs)
741 {
742         co2_cloud_irn_t *ci = get_co2_cloud_irn(env, a->irn);
743         int costs           = 0;
744
745         if (ci->cloud)
746                 return;
747
748         /* mark the node as visited and add it to the cloud. */
749         ci->cloud   = cloud;
750         list_add(&ci->cloud_list, &cloud->members_head);
751
752         DB((env->dbg, LEVEL_2, "\t%+F\n", ci->inh.irn));
753
754         /* determine the nodes costs */
755         be_lv_t *const lv = be_get_irg_liveness(env->co->irg);
756         co_gs_foreach_neighb(a, n) {
757                 costs += n->costs;
758                 DB((env->dbg, LEVEL_3, "\t\tneigh %+F cost %d\n", n->irn, n->costs));
759                 if (be_values_interfere(lv, a->irn, n->irn))
760                         cloud->inevit += n->costs;
761         }
762
763         /* add the node's cost to the total costs of the cloud. */
764         ci->costs        = costs;
765         cloud->costs    += costs;
766         cloud->freedom  += bitset_popcount(get_adm(env, &ci->inh));
767         cloud->n_memb   += 1;
768
769         /* If this is the heaviest node in the cloud, set it as the cloud's master. */
770         if (costs >= curr_costs) {
771                 curr_costs    = costs;
772                 cloud->master = ci;
773         }
774
775         /* add all the neighbors of the node to the cloud. */
776         co_gs_foreach_neighb(a, n) {
777                 affinity_node_t *an = get_affinity_info(env->co, n->irn);
778                 assert(an);
779                 populate_cloud(env, cloud, an, curr_costs);
780         }
781 }
782
783 static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a)
784 {
785         co2_cloud_t *cloud = OALLOC(&env->obst, co2_cloud_t);
786         int i;
787
788         DBG((env->dbg, LEVEL_2, "new cloud with %+F\n", a->irn));
789         memset(cloud, 0, sizeof(cloud[0]));
790         INIT_LIST_HEAD(&cloud->members_head);
791         INIT_LIST_HEAD(&cloud->list);
792         list_add(&cloud->list, &env->cloud_head);
793         cloud->best_costs = INT_MAX;
794         cloud->env = env;
795         env->visited++;
796         populate_cloud(env, cloud, a, 0);
797         cloud->freedom = (cloud->n_memb * env->n_regs) / cloud->freedom;
798
799         /* Also allocate space for the node sequence and compute that sequence. */
800         cloud->seq = OALLOCN(&env->obst, co2_cloud_irn_t*, cloud->n_memb);
801
802         i = 0;
803         list_for_each_entry(co2_cloud_irn_t, ci, &cloud->members_head, cloud_list) {
804                 ci->index       = i;
805                 cloud->seq[i++] = ci;
806         }
807         DBG((env->dbg, LEVEL_2, "cloud cost %d, freedom %f\n", cloud->costs, cloud->freedom));
808
809         return cloud;
810 }
811
812 static void apply_coloring(co2_cloud_irn_t *ci, col_t col, int depth)
813 {
814         const ir_node *irn = ci->inh.irn;
815         int *front   = FRONT_BASE(ci, col);
816         int i;
817         struct list_head changed;
818
819         INIT_LIST_HEAD(&changed);
820
821         DBG((ci->cloud->env->dbg, LEVEL_2, "%2{firm:indent}setting %+F to %d\n", depth, irn, col));
822         change_color_single(ci->cloud->env, irn, col, &changed, depth);
823         materialize_coloring(&changed);
824
825         for (i = 0; i < ci->mst_n_childs; ++i) {
826                 apply_coloring(ci->mst_childs[i], front[i], depth + 1);
827         }
828 }
829
830 static co2_cloud_irn_t *find_mst_root(co2_cloud_irn_t *ci)
831 {
832         while (ci != ci->mst_parent)
833                 ci = ci->mst_parent;
834         return ci;
835 }
836
837
838 static void process_cloud(co2_cloud_t *cloud)
839 {
840         co2_t *env  = cloud->env;
841         int n_regs  = env->n_regs;
842         int n_edges = 0;
843         int *mst_edges = XMALLOCNZ(int, cloud->n_memb * cloud->n_memb);
844         pdeq *q;
845
846         edge_t *edges;
847         int i;
848         int best_col;
849
850         /* Collect all edges in the cloud on an obstack and sort the increasingly */
851         obstack_init(&cloud->obst);
852         for (i = 0; i < cloud->n_memb; ++i) {
853                 co2_cloud_irn_t *ci = cloud->seq[i];
854
855                 co_gs_foreach_neighb(ci->inh.aff, n) {
856                         co2_cloud_irn_t *ni = get_co2_cloud_irn(cloud->env, n->irn);
857                         if (ci->index < ni->index) {
858                                 edge_t e;
859                                 e.src   = ci;
860                                 e.tgt   = ni;
861                                 e.costs = n->costs;
862                                 obstack_grow(&cloud->obst, &e, sizeof(e));
863                                 n_edges++;
864                         }
865                 }
866         }
867         edges = (edge_t*)obstack_finish(&cloud->obst);
868         qsort(edges, n_edges, sizeof(edges[0]), cmp_edges);
869
870         /* Compute the maximum spanning tree using Kruskal/Union-Find */
871         DBG((env->dbg, LEVEL_2, "computing spanning tree of cloud with master %+F\n", cloud->master->inh.irn));
872         for (i = 0; i < n_edges; ++i) {
873                 edge_t *e        = &edges[i];
874                 co2_cloud_irn_t *rs = find_mst_root(e->src);
875                 co2_cloud_irn_t *rt = find_mst_root(e->tgt);
876
877                 /* if the union/find roots are different */
878                 if (rs != rt) {
879                         int si = e->src->index;
880                         int ti = e->tgt->index;
881
882                         /* unify the sets */
883                         rs->mst_parent = rt;
884                         DBG((env->dbg, LEVEL_2, "\tadding edge %+F -- %+F cost %d\n", rs->inh.irn, rt->inh.irn, e->costs));
885
886                         /* this edge is in the MST, so set it in the bitset. */
887                         mst_edges[si * cloud->n_memb + ti] = e->costs;
888                         mst_edges[ti * cloud->n_memb + si] = e->costs;
889                 }
890         }
891         obstack_free(&cloud->obst, edges);
892
893         cloud->master->mst_parent = cloud->master;
894         cloud->mst_root = cloud->master;
895         q = new_pdeq1(cloud->master);
896         while (!pdeq_empty(q)) {
897                 co2_cloud_irn_t *ci = (co2_cloud_irn_t*)pdeq_getl(q);
898                 int ofs    = ci->index * cloud->n_memb;
899                 int end    = ofs + cloud->n_memb;
900                 int i;
901
902                 ci->mst_n_childs = 0;
903                 for (i = ofs; i < end; ++i) {
904                         if (mst_edges[i] != 0) {
905                                 int other = i - ofs;
906                                 co2_cloud_irn_t *child = cloud->seq[i - ofs];
907
908                                 /* put the child to the worklist */
909                                 pdeq_putr(q, child);
910
911                                 /* make ci the parent of the child and add the child to the children array of the parent */
912                                 child->mst_parent = ci;
913                                 child->mst_costs  = mst_edges[i];
914                                 ci->mst_n_childs++;
915                                 obstack_ptr_grow(&cloud->obst, child);
916
917                                 mst_edges[other * cloud->n_memb + ci->index] = 0;
918                                 mst_edges[i] = 0;
919                         }
920                 }
921
922                 obstack_ptr_grow(&cloud->obst, NULL);
923                 ci->mst_childs = (co2_cloud_irn_t**)obstack_finish(&cloud->obst);
924         }
925         del_pdeq(q);
926         free(mst_edges);
927
928
929         DBG((env->dbg, LEVEL_3, "mst:\n"));
930         for (i = 0; i < cloud->n_memb; ++i) {
931                 DEBUG_ONLY(co2_cloud_irn_t *ci = cloud->seq[i];)
932                 DBG((env->dbg, LEVEL_3, "\t%+F -> %+F\n", ci->inh.irn, ci->mst_parent->inh.irn));
933         }
934
935         for (i = 0; i < cloud->n_memb; ++i) {
936                 co2_cloud_irn_t *ci = cloud->seq[i];
937                 int n_childs = ci->mst_n_childs;
938                 int j;
939
940                 ci->col_costs       = OALLOCNZ(&cloud->obst, int,             n_regs);
941                 ci->tmp_coloring    = OALLOCNZ(&cloud->obst, col_cost_pair_t, n_regs);
942                 ci->fronts          = OALLOCNZ(&cloud->obst, int,             n_regs * n_childs);
943                 ci->color_badness   = OALLOCNZ(&cloud->obst, int,             n_regs);
944
945                 for (j = 0; j < env->n_regs; j++)
946                         ci->col_costs[j] = INT_MAX;
947         }
948
949         determine_color_badness(cloud->mst_root, 0);
950         best_col = coalesce_top_down(cloud->mst_root, -1, 0);
951         unfix_subtree(cloud->mst_root);
952         apply_coloring(cloud->mst_root, best_col, 0);
953
954         /* The coloring should represent the one with the best costs. */
955         //materialize_coloring(&changed);
956         DBG((env->dbg, LEVEL_2, "\tbest coloring for root %+F was %d costing %d\n",
957                 cloud->mst_root->inh.irn, best_col, examine_subtree_coloring(cloud->mst_root, best_col)));
958
959         /* Fix all nodes in the cloud. */
960         for (i = 0; i < cloud->n_memb; ++i)
961                 cloud->seq[i]->inh.fixed = 1;
962
963         /* Free all space used while optimizing this cloud. */
964         obstack_free(&cloud->obst, NULL);
965 }
966
967 static int cloud_costs(co2_cloud_t *cloud)
968 {
969         int i, costs = 0;
970
971         for (i = 0; i < cloud->n_memb; ++i) {
972                 co2_irn_t *ci = (co2_irn_t *) cloud->seq[i];
973                 col_t col = get_col(cloud->env, ci->irn);
974                 co_gs_foreach_neighb(ci->aff, n) {
975                         col_t n_col = get_col(cloud->env, n->irn);
976                         costs += col != n_col ? n->costs : 0;
977                 }
978         }
979
980         return costs / 2;
981 }
982
983 static void writeback_colors(co2_t *env)
984 {
985         co2_irn_t *irn;
986
987         for (irn = env->touched; irn; irn = irn->touched_next) {
988                 const arch_register_t *reg = arch_register_for_index(env->co->cls, irn->orig_col);
989                 arch_set_irn_register((ir_node*)irn->irn, reg);
990         }
991 }
992
993 static void process(co2_t *env)
994 {
995         co2_cloud_t **clouds;
996         int n_clouds;
997         int i;
998         int init_costs  = 0;
999         int all_costs   = 0;
1000         int final_costs = 0;
1001
1002         n_clouds = 0;
1003         co_gs_foreach_aff_node(env->co, a) {
1004                 co2_cloud_irn_t *ci = get_co2_cloud_irn(env, a->irn);
1005
1006                 if (!ci->cloud) {
1007                         new_cloud(env, a);
1008                         n_clouds++;
1009                 }
1010         }
1011
1012         i = 0;
1013         clouds = XMALLOCN(co2_cloud_t*, n_clouds);
1014         list_for_each_entry(co2_cloud_t, pos, &env->cloud_head, list)
1015                 clouds[i++] = pos;
1016         qsort(clouds, n_clouds, sizeof(clouds[0]), cmp_clouds_gt);
1017
1018         for (i = 0; i < n_clouds; ++i) {
1019                 init_costs  += cloud_costs(clouds[i]);
1020
1021                 /* Process the cloud. */
1022                 process_cloud(clouds[i]);
1023
1024                 all_costs   += clouds[i]->costs;
1025                 final_costs += cloud_costs(clouds[i]);
1026         }
1027
1028         DB((env->dbg, LEVEL_1, "all costs: %d, init costs: %d, final costs: %d\n", all_costs, init_costs, final_costs));
1029
1030         xfree(clouds);
1031 }
1032
1033 static int co_solve_heuristic_new(copy_opt_t *co)
1034 {
1035         co2_t env;
1036
1037         ir_nodemap_init(&env.map, co->irg);
1038         obstack_init(&env.obst);
1039         env.touched     = NULL;
1040         env.visited     = 0;
1041         env.co          = co;
1042         env.n_regs      = co->cls->n_regs;
1043         env.allocatable_regs = bitset_alloca(co->cls->n_regs);
1044         be_put_allocatable_regs(co->irg, co->cls, env.allocatable_regs);
1045         FIRM_DBG_REGISTER(env.dbg, "firm.be.co2");
1046         INIT_LIST_HEAD(&env.cloud_head);
1047
1048         process(&env);
1049
1050         writeback_colors(&env);
1051         obstack_free(&env.obst, NULL);
1052         ir_nodemap_destroy(&env.map);
1053         return 0;
1054 }
1055
1056 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copyheur2)
1057 void be_init_copyheur2(void)
1058 {
1059         lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
1060         lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
1061         lc_opt_entry_t *chordal_grp = lc_opt_get_grp(ra_grp, "chordal");
1062         lc_opt_entry_t *co2_grp = lc_opt_get_grp(chordal_grp, "co2");
1063
1064         static co_algo_info copyheur = {
1065                 co_solve_heuristic_new, 0
1066         };
1067
1068         lc_opt_add_table(co2_grp, options);
1069         be_register_copyopt("heur2", &copyheur);
1070 }