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