fixed the fix of the fix (that was fix)
[libfirm] / ir / be / becopyheur4.c
1 /*
2  * Copyright (C) 1995-2007 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       Simple copy minimization heuristics.
23  * @author      Christian Wuerdig
24  * @date        27.04.2007
25  * @version     $Id$
26  *
27  * This is the C implementation of the mst algorithm
28  * originally written in Java by Sebastian Hack.
29  * (also known as "heur3" :)
30  * Performs simple copy minimization.
31  */
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif /* HAVE_CONFIG_H */
35
36 #include <float.h>
37
38 #include "array.h"
39 #include "irnode_t.h"
40 #include "bitset.h"
41 #include "raw_bitset.h"
42 #include "irphase_t.h"
43 #include "pqueue.h"
44 #include "xmalloc.h"
45 #include "pdeq.h"
46 #include "pset.h"
47 #include "irprintf.h"
48 #include "irbitset.h"
49 #include "error.h"
50
51 #include "bearch.h"
52 #include "beifg.h"
53 #include "be_t.h"
54 #include "becopyopt_t.h"
55 #include "bemodule.h"
56
57 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
58
59 #define COL_COST_INFEASIBLE       DBL_MAX
60 #define AFF_NEIGHBOUR_FIX_BENEFIT 128.0
61 #define NEIGHBOUR_CONSTR_COSTS    64.0
62
63 #define DBG_AFF_CHUNK(env, level, chunk) DEBUG_ONLY(do { if (firm_dbg_get_mask(dbg) & (level)) dbg_aff_chunk((env), (chunk)); } while(0))
64 #define DBG_COL_COST(env, level, cost)   DEBUG_ONLY(do { if (firm_dbg_get_mask(dbg) & (level)) dbg_col_cost((env), (cost)); } while(0))
65
66 static int last_chunk_id = 0;
67
68 typedef struct _col_cost_t {
69         int    col;
70         double cost;
71 } col_cost_t;
72
73 /**
74  * An affinity chunk.
75  */
76 typedef struct _aff_chunk_t {
77         ir_node  **n;                   /**< An ARR_F containing all nodes of the chunk. */
78         bitset_t *nodes;                /**< A bitset containing all nodes inside this chunk. */
79         bitset_t *interfere;            /**< A bitset containing all interfering neighbours of the nodes in this chunk. */
80         int      weight;                /**< Weight of this chunk */
81         unsigned weight_consistent : 1; /**< Set if the weight is consistent. */
82         unsigned deleted           : 1; /**< Set if the was deleted. */
83         int      id;                    /**< For debugging: An id of this chunk. */
84 } aff_chunk_t;
85
86 /**
87  * An affinity edge.
88  */
89 typedef struct _aff_edge_t {
90         ir_node *src;                   /**< Source node. */
91         ir_node *tgt;                   /**< Target node. */
92         double  weight;                 /**< The weight of this edge. */
93 } aff_edge_t;
94
95 /* main coalescing environment */
96 typedef struct _co_mst_env_t {
97         int              n_regs;         /**< number of regs in class */
98         int              k;              /**< number of non-ignore registers in class */
99         bitset_t         *ignore_regs;   /**< set containing all global ignore registers */
100         ir_phase         ph;             /**< phase object holding data for nodes */
101         pqueue           *chunks;        /**< priority queue for chunks */
102         pset             *chunkset;      /**< set holding all chunks */
103         be_ifg_t         *ifg;           /**< the interference graph */
104         const arch_env_t *aenv;          /**< the arch environment */
105         copy_opt_t       *co;            /**< the copy opt object */
106 } co_mst_env_t;
107
108 /* stores coalescing related information for a node */
109 typedef struct _co_mst_irn_t {
110         ir_node     *irn;              /**< the irn this information belongs to */
111         aff_chunk_t *chunk;            /**< the chunk this irn belongs to */
112         bitset_t    *adm_colors;       /**< set of admissible colors for this irn */
113         ir_node     **int_neighs;      /**< array of all interfering neighbours (cached for speed reasons) */
114         int         n_neighs;          /**< length of the interfering neighbours array. */
115         int         int_aff_neigh;     /**< number of interfering affinity neighbours */
116         int         col;               /**< color currently assigned */
117         int         init_col;          /**< the initial color */
118         int         tmp_col;           /**< a temporary assigned color */
119         unsigned    fixed     : 1;     /**< the color is fixed */
120         unsigned    tmp_fixed : 1;     /**< the color is temporary fixed */
121 } co_mst_irn_t;
122
123 #define get_co_mst_irn(mst_env, irn) (phase_get_or_set_irn_data(&(mst_env)->ph, (irn)))
124
125 typedef int decide_func_t(const co_mst_irn_t *node, int col);
126
127 #ifdef DEBUG_libfirm
128
129 /**
130  * Write a chunk to stderr for debugging.
131  */
132 static void dbg_aff_chunk(const co_mst_env_t *env, const aff_chunk_t *c) {
133         int idx;
134         if (c->weight_consistent)
135                 ir_fprintf(stderr, " $%d ", c->weight);
136         ir_fprintf(stderr, "{");
137         bitset_foreach(c->nodes, idx) {
138                 ir_node *n = get_idx_irn(env->co->irg, idx);
139                 ir_fprintf(stderr, " %+F,", n);
140         }
141         ir_fprintf(stderr, "}");
142 }
143
144 /**
145  * Dump all admissible colors to stderr.
146  */
147 static void dbg_admissible_colors(const co_mst_env_t *env, const co_mst_irn_t *node) {
148         int idx;
149         if (bitset_popcnt(node->adm_colors) < 1)
150                 fprintf(stderr, "no admissible colors?!?");
151         else {
152                 bitset_foreach(node->adm_colors, idx)
153                         fprintf(stderr, " %d", idx);
154         }
155 }
156
157 /**
158  * Dump color-cost pairs to stderr.
159  */
160 static void dbg_col_cost(const co_mst_env_t *env, const col_cost_t *cost) {
161         int i;
162         for (i = 0; i < env->n_regs; ++i) {
163                 if (cost[i].cost == COL_COST_INFEASIBLE)
164                         fprintf(stderr, " (%d, INF)", cost[i].col);
165                 else
166                         fprintf(stderr, " (%d, %.1f)", cost[i].col, cost[i].cost);
167         }
168 }
169
170 #endif /* DEBUG_libfirm */
171
172 static INLINE int get_mst_irn_col(const co_mst_irn_t *node) {
173         return node->tmp_fixed ? node->tmp_col : node->col;
174 }
175
176 /**
177  * @return 1 if node @p node has color @p col, 0 otherwise.
178  */
179 static int decider_has_color(const co_mst_irn_t *node, int col) {
180         return get_mst_irn_col(node) == col;
181 }
182
183 /**
184  * @return 1 if node @p node has not color @p col, 0 otherwise.
185  */
186 static int decider_hasnot_color(const co_mst_irn_t *node, int col) {
187         return get_mst_irn_col(node) != col;
188 }
189
190 /**
191  * Always returns true.
192  */
193 static int decider_always_yes(const co_mst_irn_t *node, int col) {
194         return 1;
195 }
196
197 /** compares two affinity edges by its weight */
198 static int cmp_aff_edge(const void *a, const void *b) {
199         const aff_edge_t *e1 = a;
200         const aff_edge_t *e2 = b;
201
202         if (e2->weight == e1->weight) {
203                 if (e2->src->node_idx == e1->src->node_idx)
204                         return QSORT_CMP(e2->tgt->node_idx, e1->tgt->node_idx);
205                 else
206                         return QSORT_CMP(e2->src->node_idx, e1->src->node_idx);
207         }
208         /* sort in descending order */
209         return QSORT_CMP(e2->weight, e1->weight);
210 }
211
212 /** compares to color-cost pairs */
213 static int cmp_col_cost(const void *a, const void *b) {
214         const col_cost_t *c1 = a;
215         const col_cost_t *c2 = b;
216
217         return c1->cost < c2->cost ? -1 : 1;
218 }
219
220 /**
221  * Creates a new affinity chunk
222  */
223 static INLINE aff_chunk_t *new_aff_chunk(co_mst_env_t *env) {
224         aff_chunk_t *c = xmalloc(sizeof(*c));
225         c->weight            = -1;
226         c->weight_consistent = 0;
227         c->n                 = NEW_ARR_F(ir_node *, 0);
228         c->nodes             = bitset_irg_malloc(env->co->irg);
229         c->interfere         = bitset_irg_malloc(env->co->irg);
230         c->id                = last_chunk_id++;
231         pset_insert(env->chunkset, c, c->id);
232         return c;
233 }
234
235 /**
236  * Frees all memory allocated by an affinity chunk.
237  */
238 static INLINE void delete_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) {
239         pset_remove(env->chunkset, c, c->id);
240         bitset_free(c->nodes);
241         bitset_free(c->interfere);
242         DEL_ARR_F(c->n);
243         c->deleted = 1;
244         free(c);
245 }
246
247 /**
248  * Adds a node to an affinity chunk
249  */
250 static INLINE void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node) {
251         int i;
252
253         if (bitset_is_set(c->nodes, get_irn_idx(node->irn)))
254                 return;
255
256         c->weight_consistent = 0;
257         node->chunk          = c;
258         bitset_set(c->nodes, get_irn_idx(node->irn));
259
260         ARR_APP1(ir_node *, c->n, node->irn);
261
262         for (i = node->n_neighs - 1; i >= 0; --i) {
263                 ir_node *neigh = node->int_neighs[i];
264                 bitset_set(c->interfere, get_irn_idx(neigh));
265         }
266 }
267
268 /**
269  * In case there is no phase information for irn, initialize it.
270  */
271 static void *co_mst_irn_init(ir_phase *ph, ir_node *irn, void *old) {
272         co_mst_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0]));
273         co_mst_env_t *env = ph->priv;
274
275         if (res != old) {
276                 const arch_register_req_t *req;
277                 void     *nodes_it = be_ifg_nodes_iter_alloca(env->ifg);
278                 ir_node  *neigh;
279                 unsigned len;
280
281                 res->irn           = irn;
282                 res->chunk         = NULL;
283                 res->fixed         = 0;
284                 res->tmp_fixed     = 0;
285                 res->tmp_col       = -1;
286                 res->int_neighs    = NULL;
287                 res->int_aff_neigh = 0;
288                 res->col           = arch_register_get_index(arch_get_irn_register(env->aenv, irn));
289                 res->init_col      = res->col;
290
291                 DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
292
293                 /* set admissible registers */
294                 res->adm_colors = bitset_obstack_alloc(phase_obst(ph), env->n_regs);
295
296                 /* Exclude colors not assignable to the irn */
297                 req = arch_get_register_req(env->aenv, irn, -1);
298                 if (arch_register_req_is(req, limited))
299                         rbitset_copy_to_bitset(req->limited, res->adm_colors);
300                 else
301                         bitset_set_all(res->adm_colors);
302
303                 /* exclude global ignore registers as well */
304                 bitset_andnot(res->adm_colors, env->ignore_regs);
305
306                 /* set the number of interfering affinity neighbours to -1, they are calculated later */
307                 res->int_aff_neigh = -1;
308
309                 /* build list of interfering neighbours */
310                 len = 0;
311                 be_ifg_foreach_neighbour(env->ifg, nodes_it, irn, neigh) {
312                         if (! arch_irn_is(env->aenv, neigh, ignore)) {
313                                 obstack_ptr_grow(phase_obst(ph), neigh);
314                                 ++len;
315                         }
316                 }
317                 res->int_neighs = obstack_finish(phase_obst(ph));
318                 res->n_neighs   = len;
319         }
320         return res;
321 }
322
323 /**
324  * Check if affinity chunk @p chunk interferes with node @p irn.
325  */
326 static INLINE int aff_chunk_interferes(co_mst_env_t *env, const aff_chunk_t *chunk, ir_node *irn) {
327         return bitset_is_set(chunk->interfere, get_irn_idx(irn));
328 }
329
330 /**
331  * Check if there are interference edges from c1 to c2.
332  * @param env   The global co_mst environment
333  * @param c1    A chunk
334  * @param c2    Another chunk
335  * @return 1 if there are interferences between nodes of c1 and c2, 0 otherwise.
336  */
337 static INLINE int aff_chunks_interfere(co_mst_env_t *env, const aff_chunk_t *c1, const aff_chunk_t *c2) {
338         bitset_t *tmp;
339
340         if (c1 == c2)
341                 return 0;
342
343         /* check if there is a node in c2 having an interfering neighbor in c1 */
344         tmp = bitset_alloca(get_irg_last_idx(env->co->irg));
345         tmp = bitset_copy(tmp, c1->interfere);
346         tmp = bitset_and(tmp, c2->nodes);
347
348         return bitset_popcnt(tmp) > 0;
349 }
350
351 /**
352  * Returns the affinity chunk of @p irn or creates a new
353  * one with @p irn as element if there is none assigned.
354  */
355 static INLINE aff_chunk_t *get_aff_chunk(co_mst_env_t *env, ir_node *irn) {
356         co_mst_irn_t *node = get_co_mst_irn(env, irn);
357         return node->chunk;
358 }
359
360 /**
361  * Let chunk(src) absorb the nodes of chunk(tgt) (only possible when there
362  * are no interference edges from chunk(src) to chunk(tgt)).
363  * @return 1 if successful, 0 if not possible
364  */
365 static int aff_chunk_absorb(co_mst_env_t *env, ir_node *src, ir_node *tgt) {
366         aff_chunk_t *c1 = get_aff_chunk(env, src);
367         aff_chunk_t *c2 = get_aff_chunk(env, tgt);
368
369         DEBUG_ONLY(
370                 DB((dbg, LEVEL_4, "Attempt to let c1 (id %d): ", c1 ? c1->id : -1));
371                 if (c1) {
372                         DBG_AFF_CHUNK(env, LEVEL_4, c1);
373                 } else {
374                         DB((dbg, LEVEL_4, "{%+F}", src));
375                 }
376                 DB((dbg, LEVEL_4, "\n\tabsorb c2 (id %d): ", c2 ? c2->id : -1));
377                 if (c2) {
378                         DBG_AFF_CHUNK(env, LEVEL_4, c2);
379                 } else {
380                         DB((dbg, LEVEL_4, "{%+F}", tgt));
381                 }
382                 DB((dbg, LEVEL_4, "\n"));
383         )
384
385         if (c1 == NULL) {
386                 if (c2 == NULL) {
387                         /* no chunk exists */
388                         co_mst_irn_t *mirn = get_co_mst_irn(env, src);
389                         int i;
390
391                         for (i = mirn->n_neighs - 1; i >= 0; --i) {
392                                 if (mirn->int_neighs[i] == tgt)
393                                         break;
394                         }
395                         if (i < 0) {
396                                 /* create one containing both nodes */
397                                 c1 = new_aff_chunk(env);
398                                 aff_chunk_add_node(c1, get_co_mst_irn(env, src));
399                                 aff_chunk_add_node(c1, get_co_mst_irn(env, tgt));
400                                 goto absorbed;
401                         }
402                 } else {
403                         /* c2 already exists */
404                         if (! aff_chunk_interferes(env, c2, src)) {
405                                 aff_chunk_add_node(c2, get_co_mst_irn(env, src));
406                                 goto absorbed;
407                         }
408                 }
409         } else if (c2 == NULL) {
410                 /* c1 already exists */
411                 if (! aff_chunk_interferes(env, c1, tgt)) {
412                         aff_chunk_add_node(c1, get_co_mst_irn(env, tgt));
413                         goto absorbed;
414                 }
415         } else if (c1 != c2 && ! aff_chunks_interfere(env, c1, c2)) {
416                 int idx, len;
417
418                 for (idx = 0, len = ARR_LEN(c2->n); idx < len; ++idx) {
419                         ir_node      *n  = c2->n[idx];
420                         co_mst_irn_t *mn = get_co_mst_irn(env, n);
421
422                         mn->chunk = c1;
423
424                         if (! bitset_is_set(c1->nodes, get_irn_idx(n)))
425                                 ARR_APP1(ir_node *, c1->n, n);
426                 }
427
428                 bitset_or(c1->nodes, c2->nodes);
429                 bitset_or(c1->interfere, c2->interfere);
430                 c1->weight_consistent = 0;
431
432                 delete_aff_chunk(env, c2);
433                 goto absorbed;
434         }
435         DB((dbg, LEVEL_4, " ... c1 interferes with c2, skipped\n"));
436         return 0;
437
438 absorbed:
439         DB((dbg, LEVEL_4, " ... absorbed\n"));
440         return 1;
441 }
442
443 /**
444  * Assures that the weight of the given chunk is consistent.
445  */
446 static void aff_chunk_assure_weight(const co_mst_env_t *env, aff_chunk_t *c) {
447         if (! c->weight_consistent) {
448                 int w = 0;
449                 int idx, len;
450
451                 for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
452                         ir_node               *n  = c->n[idx];
453                         const affinity_node_t *an = get_affinity_info(env->co, n);
454
455                         if (an != NULL) {
456                                 neighb_t *neigh;
457                                 co_gs_foreach_neighb(an, neigh) {
458                                         const ir_node *m    = neigh->irn;
459                                         const int     m_idx = get_irn_idx(m);
460
461                                         /* skip ignore nodes */
462                                         if (arch_irn_is(env->aenv, m, ignore))
463                                                 continue;
464
465                                         w += bitset_is_set(c->nodes, m_idx) ? neigh->costs : 0;
466                                 }
467                         }
468                 }
469
470                 c->weight            = w;
471                 c->weight_consistent = 1;
472         }
473 }
474
475 /**
476  * Count the number of interfering affinity neighbours
477  */
478 static int count_interfering_aff_neighs(co_mst_env_t *env, const affinity_node_t *an) {
479         const neighb_t     *neigh;
480         ir_node            *irn  = an->irn;
481         const co_mst_irn_t *node = get_co_mst_irn(env, irn);
482         int                res   = 0;
483
484         co_gs_foreach_neighb(an, neigh) {
485                 const ir_node *n = neigh->irn;
486                 int           i;
487
488                 /* skip ignore nodes */
489                 if (arch_irn_is(env->aenv, n, ignore))
490                         continue;
491
492                 /* check if the affinity neighbour interfere */
493                 for (i = 0; i < node->n_neighs; ++i) {
494                         if (node->int_neighs[i] == n) {
495                                 ++res;
496                                 break;
497                         }
498                 }
499         }
500         return res;
501 }
502
503
504 /**
505  * Build chunks of nodes connected by affinity edges.
506  * We start at the heaviest affinity edge.
507  * The chunks of the two edge-defining nodes will be
508  * merged if there are no interference edges from one
509  * chunk to the other.
510  */
511 static void build_affinity_chunks(co_mst_env_t *env) {
512         void        *nodes_it = be_ifg_nodes_iter_alloca(env->ifg);
513         aff_edge_t  *edges    = NEW_ARR_F(aff_edge_t, 0);
514         ir_node     *n;
515         int         i, len;
516         aff_chunk_t *curr_chunk;
517
518         /* at first we create the affinity edge objects */
519         be_ifg_foreach_node(env->ifg, nodes_it, n) {
520                 int             n_idx = get_irn_idx(n);
521                 co_mst_irn_t    *n1;
522                 affinity_node_t *an;
523
524                 /* skip ignore nodes */
525                 if (arch_irn_is(env->aenv, n, ignore))
526                         continue;
527
528                 n1 = get_co_mst_irn(env, n);
529                 an = get_affinity_info(env->co, n);
530
531                 if (an != NULL) {
532                         neighb_t *neigh;
533
534                         if (n1->int_aff_neigh < 0)
535                                 n1->int_aff_neigh = count_interfering_aff_neighs(env, an);
536
537                         /* build the affinity edges */
538                         co_gs_foreach_neighb(an, neigh) {
539                                 ir_node *m    = neigh->irn;
540                                 int     m_idx = get_irn_idx(m);
541
542                                 /* record the edge in only one direction */
543                                 if (n_idx < m_idx) {
544                                         co_mst_irn_t *n2;
545                                         aff_edge_t   edge;
546
547                                         /* skip ignore nodes */
548                                         if (arch_irn_is(env->aenv, m, ignore))
549                                                 continue;
550
551                                         edge.src = n;
552                                         edge.tgt = m;
553
554                                         n2 = get_co_mst_irn(env, m);
555                                         if (n2->int_aff_neigh < 0) {
556                                                 affinity_node_t *am = get_affinity_info(env->co, m);
557                                                 n2->int_aff_neigh = count_interfering_aff_neighs(env, am);
558                                         }
559                                         edge.weight = (double)neigh->costs / (double)(1 + n1->int_aff_neigh + n2->int_aff_neigh);
560                                         ARR_APP1(aff_edge_t, edges, edge);
561                                 }
562                         }
563                 }
564         }
565
566         /* now: sort edges and build the affinity chunks */
567         len = ARR_LEN(edges);
568         qsort(edges, len, sizeof(edges[0]), cmp_aff_edge);
569         for (i = 0; i < len; ++i) {
570                 DBG((dbg, LEVEL_1, "edge (%u,%u) %f\n", edges[i].src->node_idx, edges[i].tgt->node_idx, edges[i].weight));
571
572                 (void)aff_chunk_absorb(env, edges[i].src, edges[i].tgt);
573         }
574
575         /* now insert all chunks into a priority queue */
576         foreach_pset(env->chunkset, curr_chunk) {
577                 aff_chunk_assure_weight(env, curr_chunk);
578
579                 DBG((dbg, LEVEL_1, "entry #%d", curr_chunk->id));
580                 DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
581                 DBG((dbg, LEVEL_1, "\n"));
582
583                 pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
584         }
585         foreach_phase_irn(&env->ph, n) {
586                 co_mst_irn_t *mirn = get_co_mst_irn(env, n);
587
588                 if (mirn->chunk == NULL) {
589                         /* no chunk is allocated so far, do it now */
590                         aff_chunk_t *curr_chunk = new_aff_chunk(env);
591                         aff_chunk_add_node(curr_chunk, mirn);
592
593                         aff_chunk_assure_weight(env, curr_chunk);
594
595                         DBG((dbg, LEVEL_1, "entry #%d", curr_chunk->id));
596                         DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
597                         DBG((dbg, LEVEL_1, "\n"));
598
599                         pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
600                 }
601         }
602
603         DEL_ARR_F(edges);
604 }
605
606 /**
607  * Greedy collect affinity neighbours into thew new chunk @p chunk starting at node @p node.
608  */
609 static void expand_chunk_from(co_mst_env_t *env, co_mst_irn_t *node, bitset_t *visited,
610         aff_chunk_t *chunk, aff_chunk_t *orig_chunk, decide_func_t *decider, int col)
611 {
612         waitq *nodes = new_waitq();
613
614         DBG((dbg, LEVEL_1, "\n\tExpanding new chunk (#%d) from %+F, color %d:", chunk->id, node->irn, col));
615
616         /* init queue and chunk */
617         waitq_put(nodes, node);
618         bitset_set(visited, get_irn_idx(node->irn));
619         aff_chunk_add_node(chunk, node);
620         DB((dbg, LEVEL_1, " %+F", node->irn));
621
622         /* as long as there are nodes in the queue */
623         while (! waitq_empty(nodes)) {
624                 co_mst_irn_t    *n  = waitq_get(nodes);
625                 affinity_node_t *an = get_affinity_info(env->co, n->irn);
626
627                 /* check all affinity neighbors */
628                 if (an != NULL) {
629                         neighb_t *neigh;
630                         co_gs_foreach_neighb(an, neigh) {
631                                 ir_node      *m    = neigh->irn;
632                                 int          m_idx = get_irn_idx(m);
633                                 co_mst_irn_t *n2;
634
635                                 /* skip ignore nodes */
636                                 if (arch_irn_is(env->aenv, m, ignore))
637                                         continue;
638
639                                 n2 = get_co_mst_irn(env, m);
640
641                                 if (! bitset_is_set(visited, m_idx)       &&
642                                         decider(n2, col)                      &&
643                                         ! n2->fixed                           &&
644                                         ! aff_chunk_interferes(env, chunk, m) &&
645                                         bitset_is_set(orig_chunk->nodes, m_idx))
646                                 {
647                                         /*
648                                                 following conditions are met:
649                                                 - neighbour is not visited
650                                                 - neighbour likes the color
651                                                 - neighbour has not yet a fixed color
652                                                 - the new chunk doesn't interfere with the neighbour
653                                                 - neighbour belongs or belonged once to the original chunk
654                                         */
655                                         bitset_set(visited, m_idx);
656                                         aff_chunk_add_node(chunk, n2);
657                                         DB((dbg, LEVEL_1, " %+F", n2->irn));
658                                         /* enqueue for further search */
659                                         waitq_put(nodes, n2);
660                                 }
661                         }
662                 }
663         }
664
665         DB((dbg, LEVEL_1, "\n"));
666
667         del_waitq(nodes);
668 }
669
670 /**
671  * Fragment the given chunk into chunks having given color and not having given color.
672  */
673 static aff_chunk_t *fragment_chunk(co_mst_env_t *env, int col, aff_chunk_t *c, waitq *tmp) {
674         bitset_t    *visited = bitset_irg_malloc(env->co->irg);
675         int         idx, len;
676         aff_chunk_t *best = NULL;
677
678         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
679                 ir_node       *irn;
680                 co_mst_irn_t  *node;
681                 aff_chunk_t   *tmp_chunk;
682                 decide_func_t *decider;
683                 int           check_for_best;
684
685                 irn = c->n[idx];
686                 if (bitset_is_set(visited, get_irn_idx(irn)))
687                         continue;
688
689                 node = get_co_mst_irn(env, irn);
690
691                 if (get_mst_irn_col(node) == col) {
692                         decider        = decider_has_color;
693                         check_for_best = 1;
694                         DBG((dbg, LEVEL_4, "\tcolor %d wanted", col));
695                 }
696                 else {
697                         decider        = decider_hasnot_color;
698                         check_for_best = 0;
699                         DBG((dbg, LEVEL_4, "\tcolor %d forbidden", col));
700                 }
701
702                 /* create a new chunk starting at current node */
703                 tmp_chunk = new_aff_chunk(env);
704                 waitq_put(tmp, tmp_chunk);
705                 expand_chunk_from(env, node, visited, tmp_chunk, c, decider, col);
706                 assert(bitset_popcnt(tmp_chunk->nodes) > 0 && "No nodes added to chunk");
707
708                 /* remember the local best */
709                 aff_chunk_assure_weight(env, tmp_chunk);
710                 if (check_for_best && (! best || best->weight < tmp_chunk->weight))
711                         best = tmp_chunk;
712         }
713
714         assert(best && "No chunk found?");
715         bitset_free(visited);
716         return best;
717 }
718
719 /**
720  * Initializes an array of color-cost pairs.
721  * Sets forbidden colors to costs COL_COST_INFEASIBLE and all others to @p c.
722  */
723 static INLINE void col_cost_init(co_mst_env_t *env, col_cost_t *cost, double c) {
724         int i;
725
726         for (i = 0; i < env->n_regs; ++i) {
727                 cost[i].col = i;
728                 if (bitset_is_set(env->ignore_regs, i))
729                         cost[i].cost = COL_COST_INFEASIBLE;
730                 else
731                         cost[i].cost = c;
732         }
733 }
734
735 /**
736  * Initializes an array of color-cost pairs.
737  * Sets all colors except color @p col to COL_COST_INFEASIBLE and @p col to 0.0
738  */
739 static INLINE void col_cost_init_single(co_mst_env_t *env, col_cost_t *cost, int col) {
740         assert(! bitset_is_set(env->ignore_regs, col) && "Attempt to use forbidden color.");
741         col_cost_init(env, cost, COL_COST_INFEASIBLE);
742         cost[col].col = 0;
743         cost[0].col   = col;
744         cost[0].cost  = 0.0;
745 }
746
747 /**
748  * Resets the temporary fixed color of all nodes within wait queue @p nodes.
749  * ATTENTION: the queue is empty after calling this function!
750  */
751 static INLINE void reject_coloring(waitq *nodes) {
752         DB((dbg, LEVEL_4, "\treject coloring for"));
753         while (! waitq_empty(nodes)) {
754                 co_mst_irn_t *n = waitq_get(nodes);
755                 DB((dbg, LEVEL_4, " %+F", n->irn));
756                 n->tmp_fixed = 0;
757         }
758         DB((dbg, LEVEL_4, "\n"));
759 }
760
761 /**
762  * Determines the costs for each color if it would be assigned to node @p node.
763  */
764 static void determine_color_costs(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs) {
765         affinity_node_t *an = get_affinity_info(env->co, node->irn);
766         neighb_t        *aff_neigh;
767         int             idx, i;
768
769         col_cost_init(env, costs, 0.0);
770
771         /* calculate (negative) costs for affinity neighbours */
772         if (an != NULL) {
773                 co_gs_foreach_neighb(an, aff_neigh) {
774                         ir_node      *m = aff_neigh->irn;
775                         co_mst_irn_t *neigh;
776                         double       c;
777
778                         /* skip ignore nodes */
779                         if (arch_irn_is(env->aenv, m, ignore))
780                                 continue;
781
782                         neigh = get_co_mst_irn(env, m);
783                         c     = (double)aff_neigh->costs;
784
785                         /* calculate costs for fixed affinity neighbours */
786                         if (neigh->tmp_fixed || neigh->fixed) {
787                                 int col = get_mst_irn_col(neigh);
788                                 costs[col].cost -= c * AFF_NEIGHBOUR_FIX_BENEFIT;
789                         }
790                 }
791         }
792
793         /* calculate (positive) costs for interfering neighbours */
794         for (i = 0; i < node->n_neighs; ++i) {
795                 co_mst_irn_t *neigh;
796                 int          col, col_cnt;
797                 ir_node      *int_neigh;
798
799                 int_neigh = node->int_neighs[i];
800
801                 /* skip ignore nodes */
802                 if (arch_irn_is(env->aenv, int_neigh, ignore))
803                         continue;
804
805                 neigh   = get_co_mst_irn(env, int_neigh);
806                 col     = get_mst_irn_col(neigh);
807                 col_cnt = bitset_popcnt(neigh->adm_colors);
808
809                 if (neigh->tmp_fixed || neigh->fixed) {
810                         /* colors of fixed interfering neighbours are infeasible */
811                         costs[col].cost = COL_COST_INFEASIBLE;
812                 }
813                 else if (col_cnt < env->k) {
814                         /* calculate costs for constrained interfering neighbours */
815                         double ratio = 1.0 - ((double)col_cnt / (double)env->k);
816
817                         bitset_foreach_clear(neigh->adm_colors, idx) {
818                                 /* check only explicitly forbidden colors (skip global forbidden ones) */
819                                 if (! bitset_is_set(env->ignore_regs, idx)) {
820                                         costs[col].cost += ratio * NEIGHBOUR_CONSTR_COSTS;
821                                 }
822                         }
823                 }
824         }
825
826         /* set all not admissible colors to COL_COST_INFEASIBLE */
827         bitset_foreach_clear(node->adm_colors, idx)
828                 costs[idx].cost = COL_COST_INFEASIBLE;
829 }
830
831 /* need forward declaration due to recursive call */
832 static int recolor_nodes(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs, waitq *changed_ones);
833
834 /**
835  * Tries to change node to a color but @p explude_col.
836  * @return 1 if succeeded, 0 otherwise.
837  */
838 static int change_node_color_excluded(co_mst_env_t *env, co_mst_irn_t *node, int exclude_col, waitq *changed_ones) {
839         int col = get_mst_irn_col(node);
840         int res = 0;
841
842         /* neighbours has already a different color -> good, temporary fix it */
843         if (col != exclude_col) {
844                 node->tmp_fixed = 1;
845                 node->tmp_col   = col;
846                 waitq_put(changed_ones, node);
847                 return 1;
848         }
849
850         /* The node has the color it should not have _and_ has not been visited yet. */
851         if (! (node->tmp_fixed || node->fixed)) {
852                 col_cost_t *costs = alloca(env->n_regs * sizeof(costs[0]));
853
854                 /* Get the costs for giving the node a specific color. */
855                 determine_color_costs(env, node, costs);
856
857                 /* Since the node must not have the not_col, set the costs for that color to "infinity" */
858                 costs[exclude_col].cost = COL_COST_INFEASIBLE;
859
860                 /* sort the colors according costs, cheapest first. */
861                 qsort(costs, env->n_regs, sizeof(costs[0]), cmp_col_cost);
862
863                 /* Try recoloring the node using the color list. */
864                 res = recolor_nodes(env, node, costs, changed_ones);
865         }
866
867         return res;
868 }
869
870 /**
871  * Tries to bring node @p node to cheapest color and color all interfering neighbours with other colors.
872  * ATTENTION: Expect @p costs already sorted by increasing costs.
873  * @return 1 if coloring could be applied, 0 otherwise.
874  */
875 static int recolor_nodes(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs, waitq *changed_ones) {
876         int   i;
877         waitq *local_changed = new_waitq();
878         waitq *tmp           = new_waitq();
879
880         DBG((dbg, LEVEL_1, "\tRecoloring %+F with color-costs", node->irn));
881         DBG_COL_COST(env, LEVEL_1, costs);
882         DB((dbg, LEVEL_1, "\n"));
883
884         for (i = 0; i < env->n_regs; ++i) {
885                 int tgt_col  = costs[i].col;
886                 int neigh_ok = 1;
887                 int j;
888
889                 /* If the costs for that color (and all successive) are infinite, bail out we won't make it anyway. */
890                 if (costs[i].cost == COL_COST_INFEASIBLE) {
891                         node->tmp_fixed = 0;
892                         del_waitq(local_changed);
893                         del_waitq(tmp);
894                         return 0;
895                 }
896
897                 /* Set the new color of the node and mark the node as temporarily fixed. */
898                 assert(! node->tmp_fixed && "Node must not have been temporary fixed.");
899                 node->tmp_fixed = 1;
900                 node->tmp_col   = tgt_col;
901                 DBG((dbg, LEVEL_4, "\tTemporary setting %+F to color %d\n", node->irn, tgt_col));
902
903                 assert(waitq_empty(local_changed) && "Node queue should be empty here.");
904                 waitq_put(local_changed, node);
905
906                 /* try to color all interfering neighbours with current color forbidden */
907                 for (j = 0; j < node->n_neighs; ++j) {
908                         co_mst_irn_t *nn;
909                         ir_node      *neigh;
910
911                         neigh = node->int_neighs[j];
912
913                         /* skip ignore nodes */
914                         if (arch_irn_is(env->aenv, neigh, ignore))
915                                 continue;
916
917                         nn = get_co_mst_irn(env, neigh);
918                         DB((dbg, LEVEL_4, "\tHandling neighbour %+F, at position %d (fixed: %d, tmp_fixed: %d, tmp_col: %d, col: %d)\n",
919                                 neigh, j, nn->fixed, nn->tmp_fixed, nn->tmp_col, nn->col));
920
921                         /*
922                                 Try to change the color of the neighbor and record all nodes which
923                                 get changed in the tmp list. Add this list to the "changed" list for
924                                 that color. If we did not succeed to change the color of the neighbor,
925                                 we bail out and try the next color.
926                         */
927                         if (get_mst_irn_col(nn) == tgt_col) {
928                                 /* try to color neighbour with tgt_col forbidden */
929                                 neigh_ok = change_node_color_excluded(env, nn, tgt_col, tmp);
930
931                                 /* join lists of changed nodes */
932                                 while (! waitq_empty(tmp))
933                                         waitq_put(local_changed, waitq_get(tmp));
934
935                                 if (! neigh_ok)
936                                         break;
937                         }
938                 }
939
940                 /*
941                         We managed to assign the target color to all neighbors, so from the perspective
942                         of the current node, every thing was ok and we can return safely.
943                 */
944                 if (neigh_ok) {
945                         /* append the local_changed ones to global ones */
946                         while (! waitq_empty(local_changed))
947                                 waitq_put(changed_ones, waitq_get(local_changed));
948                         del_waitq(local_changed);
949                         del_waitq(tmp);
950                         return 1;
951                 }
952                 else {
953                         /* coloring of neighbours failed, so we try next color */
954                         reject_coloring(local_changed);
955                 }
956         }
957
958         del_waitq(local_changed);
959         del_waitq(tmp);
960         return 0;
961 }
962
963 /**
964  * Tries to bring node @p node and all it's neighbours to color @p tgt_col.
965  * @return 1 if color @p col could be applied, 0 otherwise
966  */
967 static int change_node_color(co_mst_env_t *env, co_mst_irn_t *node, int tgt_col, waitq *changed_ones) {
968         int col = get_mst_irn_col(node);
969
970         /* if node already has the target color -> good, temporary fix it */
971         if (col == tgt_col) {
972                 DBG((dbg, LEVEL_4, "\t\tCNC: %+F has already color %d, fix temporary\n", node->irn, tgt_col));
973                 if (! node->tmp_fixed) {
974                         node->tmp_fixed = 1;
975                         node->tmp_col   = tgt_col;
976                         waitq_put(changed_ones, node);
977                 }
978                 return 1;
979         }
980
981         /*
982                 Node has not yet a fixed color and target color is admissible
983                 -> try to recolor node and it's affinity neighbours
984         */
985         if (! (node->fixed || node->tmp_fixed) && bitset_is_set(node->adm_colors, tgt_col)) {
986                 col_cost_t *costs = alloca(env->n_regs * sizeof(costs[0]));
987                 int        res;
988
989                 col_cost_init_single(env, costs, tgt_col);
990
991                 DBG((dbg, LEVEL_4, "\t\tCNC: Attempt to recolor %+F ===>>\n", node->irn));
992                 res = recolor_nodes(env, node, costs, changed_ones);
993                 DBG((dbg, LEVEL_4, "\t\tCNC: <<=== Recoloring of %+F %s\n", node->irn, res ? "succeeded" : "failed"));
994
995                 return res;
996         }
997
998         DEBUG_ONLY(
999                 if (firm_dbg_get_mask(dbg) & LEVEL_4) {
1000                         if (node->fixed || node->tmp_fixed)
1001                                 DB((dbg, LEVEL_4, "\t\tCNC: %+F has already fixed color %d\n", node->irn, col));
1002                         else {
1003                                 DB((dbg, LEVEL_4, "\t\tCNC: color %d not admissible for %+F (", tgt_col, node->irn));
1004                                 dbg_admissible_colors(env, node);
1005                                 DB((dbg, LEVEL_4, ")\n"));
1006                         }
1007                 }
1008         )
1009
1010         return 0;
1011 }
1012
1013 /**
1014  * Tries to color an affinity chunk (or at least a part of it).
1015  * Inserts uncolored parts of the chunk as a new chunk into the priority queue.
1016  */
1017 static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) {
1018         aff_chunk_t *best_chunk   = NULL;
1019         int         best_color    = -1;
1020         waitq       *changed_ones = new_waitq();
1021         waitq       *tmp_chunks   = new_waitq();
1022         waitq       *best_starts  = NULL;
1023         bitset_t    *visited;
1024         int         col, idx, len;
1025
1026         DB((dbg, LEVEL_2, "fragmentizing chunk #%d", c->id));
1027         DBG_AFF_CHUNK(env, LEVEL_2, c);
1028         DB((dbg, LEVEL_2, "\n"));
1029
1030
1031         /* check which color is the "best" for the given chunk */
1032         for (col = 0; col < env->n_regs; ++col) {
1033                 int         one_good     = 0;
1034                 waitq       *good_starts = new_waitq();
1035                 aff_chunk_t *local_best;
1036
1037                 /* skip ignore colors */
1038                 if (bitset_is_set(env->ignore_regs, col))
1039                         continue;
1040
1041                 DB((dbg, LEVEL_3, "\ttrying color %d\n", col));
1042
1043                 /* try to bring all nodes of given chunk to the current color. */
1044                 for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1045                         ir_node      *irn  = c->n[idx];
1046                         co_mst_irn_t *node = get_co_mst_irn(env, irn);
1047                         int          good  = 0;
1048
1049                         assert(! node->fixed && "Node must not have a fixed color.");
1050                         DB((dbg, LEVEL_4, "\t\tBringing %+F from color %d to color %d ...\n", irn, node->col, col));
1051
1052                         /*
1053                                 The order of the colored nodes is important, so we record the successfully
1054                                 colored ones in the order they appeared.
1055                         */
1056                         good = change_node_color(env, node, col, changed_ones);
1057                         if (good)
1058                                 waitq_put(good_starts, node);
1059                         one_good |= good;
1060
1061                         DB((dbg, LEVEL_4, "\t\t... %+F attempt from %d to %d %s\n", irn, node->col, col, one_good ? "succeeded" : "failed"));
1062                 }
1063
1064                 /* try next color when failed */
1065                 if (! one_good)
1066                         continue;
1067
1068                 /* fragment the chunk according to the coloring */
1069                 local_best = fragment_chunk(env, col, c, tmp_chunks);
1070
1071                 /* search the best of the good list
1072                    and make it the new best if it is better than the current */
1073                 if (local_best) {
1074                         aff_chunk_assure_weight(env, local_best);
1075
1076                         DB((dbg, LEVEL_4, "\t\tlocal best chunk (id %d) for color %d: ", local_best->id, col));
1077                         DBG_AFF_CHUNK(env, LEVEL_4, local_best);
1078
1079                         if (! best_chunk || best_chunk->weight < local_best->weight) {
1080                                 best_chunk = local_best;
1081                                 best_color = col;
1082                                 if (best_starts)
1083                                         del_waitq(best_starts);
1084                                 best_starts = good_starts;
1085                                 DB((dbg, LEVEL_4, "\n\t\t... setting global best chunk (id %d), color %d\n", best_chunk->id, best_color));
1086                         } else {
1087                                 DB((dbg, LEVEL_4, "\n\t\t... omitting, global best is better\n"));
1088                                 del_waitq(good_starts);
1089                         }
1090                 }
1091                 else {
1092                         del_waitq(good_starts);
1093                 }
1094
1095                 /* reject the coloring and bring the coloring to the initial state */
1096                 reject_coloring(changed_ones);
1097         }
1098
1099         /* free all intermediate created chunks except best one */
1100         while (! waitq_empty(tmp_chunks)) {
1101                 aff_chunk_t *tmp = waitq_get(tmp_chunks);
1102                 if (tmp != best_chunk)
1103                         delete_aff_chunk(env, tmp);
1104         }
1105         del_waitq(tmp_chunks);
1106
1107         /* return if coloring failed */
1108         if (! best_chunk) {
1109                 del_waitq(changed_ones);
1110                 if (best_starts)
1111                         del_waitq(best_starts);
1112                 return;
1113         }
1114
1115         DB((dbg, LEVEL_2, "\tbest chunk #%d ", best_chunk->id));
1116         DBG_AFF_CHUNK(env, LEVEL_2, best_chunk);
1117         DB((dbg, LEVEL_2, "using color %d\n", best_color));
1118
1119         /* get the best fragment from the best list and color it */
1120         while (! waitq_empty(best_starts)) {
1121                 co_mst_irn_t *node = waitq_get(best_starts);
1122                 int          res;
1123
1124                 if (! bitset_is_set(best_chunk->nodes, get_irn_idx(node->irn)))
1125                         continue;
1126
1127                 res = change_node_color(env, node, best_color, changed_ones);
1128                 if (! res)
1129                         panic("Color manifesting failed for %+F, color %d in chunk %d\n", node->irn, best_color, best_chunk->id);
1130                 node->fixed = 1;
1131                 node->chunk = best_chunk;
1132         }
1133         /* we colored the successful start nodes, now color the rest of the chunk */
1134         for (idx = 0, len = ARR_LEN(best_chunk->n); idx < len; ++idx) {
1135                 ir_node      *irn  = best_chunk->n[idx];
1136                 co_mst_irn_t *node = get_co_mst_irn(env, irn);
1137                 int          res;
1138
1139                 res = change_node_color(env, node, best_color, changed_ones);
1140                 if (! res)
1141                         panic("Color manifesting failed for %+F, color %d in chunk %d\n", irn, best_color, best_chunk->id);
1142                 DB((dbg, LEVEL_4, "\tManifesting color %d for %+F, chunk #%d\n", best_color, irn, best_chunk->id));
1143                 node->fixed = 1;
1144                 node->chunk = best_chunk;
1145         }
1146
1147         /* materialize colors on changed nodes */
1148         while (! waitq_empty(changed_ones)) {
1149                 co_mst_irn_t *n = waitq_get(changed_ones);
1150                 n->tmp_fixed = 0;
1151                 n->col       = n->tmp_col;
1152         }
1153
1154         /* remove the nodes in best chunk from original chunk */
1155         bitset_andnot(c->nodes, best_chunk->nodes);
1156         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1157                 ir_node *irn = c->n[idx];
1158
1159                 if (bitset_is_set(best_chunk->nodes, get_irn_idx(irn))) {
1160                         int last = ARR_LEN(c->n) - 1;
1161
1162                         c->n[idx] = c->n[last];
1163                         ARR_SHRINKLEN(c->n, last);
1164                         len--;
1165                 }
1166         }
1167
1168         /* we have to get the nodes back into the original chunk because they are scattered over temporary chunks */
1169         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1170                 ir_node      *n  = c->n[idx];
1171                 co_mst_irn_t *nn = get_co_mst_irn(env, n);
1172                 nn->chunk = c;
1173         }
1174
1175         /* fragment the remaining chunk */
1176         visited = bitset_irg_malloc(env->co->irg);
1177         bitset_or(visited, best_chunk->nodes);
1178         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1179                 ir_node *irn = c->n[idx];
1180                 if (! bitset_is_set(visited, get_irn_idx(irn))) {
1181                         aff_chunk_t  *new_chunk = new_aff_chunk(env);
1182                         co_mst_irn_t *node      = get_co_mst_irn(env, irn);
1183
1184                         expand_chunk_from(env, node, visited, new_chunk, c, decider_always_yes, 0);
1185                         aff_chunk_assure_weight(env, new_chunk);
1186                         pqueue_put(env->chunks, new_chunk, new_chunk->weight);
1187                 }
1188         }
1189
1190         /* clear obsolete chunks and free some memory */
1191         delete_aff_chunk(env, best_chunk);
1192         bitset_free(visited);
1193         del_waitq(changed_ones);
1194         if (best_starts)
1195                 del_waitq(best_starts);
1196 }
1197
1198 /**
1199  * Main driver for mst safe coalescing algorithm.
1200  */
1201 int co_solve_heuristic_mst(copy_opt_t *co) {
1202         unsigned     n_regs       = co->cls->n_regs;
1203         bitset_t     *ignore_regs = bitset_alloca(n_regs);
1204         unsigned     k;
1205         ir_node      *irn;
1206         co_mst_env_t mst_env;
1207
1208         /* init phase */
1209         phase_init(&mst_env.ph, "co_mst", co->irg, PHASE_DEFAULT_GROWTH, co_mst_irn_init, &mst_env);
1210
1211         k = be_put_ignore_regs(co->cenv->birg, co->cls, ignore_regs);
1212         k = n_regs - k;
1213
1214         mst_env.n_regs      = n_regs;
1215         mst_env.k           = k;
1216         mst_env.chunks      = new_pqueue();
1217         mst_env.co          = co;
1218         mst_env.ignore_regs = ignore_regs;
1219         mst_env.ifg         = co->cenv->ifg;
1220         mst_env.aenv        = co->aenv;
1221         mst_env.chunkset    = pset_new_ptr(512);
1222
1223         DBG((dbg, LEVEL_1, "==== Coloring %+F, class %s ====\n", co->irg, co->cls->name));
1224
1225         /* build affinity chunks */
1226         build_affinity_chunks(&mst_env);
1227
1228         /* color chunks as long as there are some */
1229         while (! pqueue_empty(mst_env.chunks)) {
1230                 aff_chunk_t *chunk = pqueue_get(mst_env.chunks);
1231
1232                 color_aff_chunk(&mst_env, chunk);
1233                 DB((dbg, LEVEL_4, "<<<====== Coloring chunk (%d) done\n", chunk->id));
1234                 delete_aff_chunk(&mst_env, chunk);
1235         }
1236
1237         /* apply coloring */
1238         foreach_phase_irn(&mst_env.ph, irn) {
1239                 co_mst_irn_t *mirn = get_co_mst_irn(&mst_env, irn);
1240                 const arch_register_t *reg;
1241
1242                 if (arch_irn_is(mst_env.aenv, irn, ignore))
1243                         continue;
1244
1245                 assert(mirn->fixed && "Node should have fixed color");
1246
1247                 /* skip nodes where color hasn't changed */
1248                 if (mirn->init_col == mirn->col)
1249                         continue;
1250
1251                 reg = arch_register_for_index(co->cls, mirn->col);
1252                 arch_set_irn_register(co->aenv, irn, reg);
1253                 DB((dbg, LEVEL_1, "%+F set color from %d to %d\n", irn, mirn->init_col, mirn->col));
1254         }
1255
1256         /* free allocated memory */
1257         del_pqueue(mst_env.chunks);
1258         phase_free(&mst_env.ph);
1259         del_pset(mst_env.chunkset);
1260
1261         return 0;
1262 }
1263
1264 void be_init_copyheur4(void) {
1265         FIRM_DBG_REGISTER(dbg, "firm.be.co.heur4");
1266 }
1267
1268 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copyheur4);