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