d068c5afa7dcdd9c4d3ab67d639e85d86ad7c0bf
[libfirm] / ir / be / becopyheur4.c
1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       Simple copy minimization heuristics.
23  * @author      Christian Wuerdig
24  * @date        27.04.2007
25  *
26  * This is the C implementation of the mst algorithm
27  * originally written in Java by Sebastian Hack.
28  * (also known as "heur3" :)
29  * Performs simple copy minimization.
30  */
31 #include "config.h"
32
33 #define DISABLE_STATEV
34
35 #include <float.h>
36
37 #include "array.h"
38 #include "irnode_t.h"
39 #include "bitset.h"
40 #include "raw_bitset.h"
41 #include "irnodemap.h"
42 #include "pqueue.h"
43 #include "xmalloc.h"
44 #include "pdeq.h"
45 #include "irprintf.h"
46 #include "util.h"
47 #include "irtools.h"
48 #include "error.h"
49 #include "list.h"
50 #include "statev_t.h"
51
52 #include "bearch.h"
53 #include "beifg.h"
54 #include "be_t.h"
55 #include "becopyopt_t.h"
56 #include "bemodule.h"
57
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
64 #ifdef DEBUG_libfirm
65
66 #define DBG_AFF_CHUNK(env, level, chunk) do { if (firm_dbg_get_mask(dbg) & (level)) dbg_aff_chunk((env), (chunk)); } while (0)
67 #define DBG_COL_COST(env, level, cost)   do { if (firm_dbg_get_mask(dbg) & (level)) dbg_col_cost((env), (cost)); } while (0)
68
69 static firm_dbg_module_t *dbg = NULL;
70
71 #else
72
73 #define DBG_AFF_CHUNK(env, level, chunk)
74 #define DBG_COL_COST(env, level, cost)
75
76 #endif
77
78 typedef float real_t;
79 #define REAL(C)   (C ## f)
80
81 static unsigned last_chunk_id   = 0;
82 static int recolor_limit        = 7;
83 static double dislike_influence = REAL(0.1);
84
85 typedef struct col_cost_t {
86         int     col;
87         real_t  cost;
88 } col_cost_t;
89
90 /**
91  * An affinity chunk.
92  */
93 typedef struct aff_chunk_t {
94         const ir_node  **n;                     /**< An ARR_F containing all nodes of the chunk. */
95         const ir_node  **interfere;             /**< An ARR_F containing all inference. */
96         int              weight;                /**< Weight of this chunk */
97         unsigned         weight_consistent : 1; /**< Set if the weight is consistent. */
98         unsigned         deleted           : 1; /**< For debugging: Set if the was deleted. */
99         unsigned         id;                    /**< An id of this chunk. */
100         unsigned         visited;
101         list_head        list;
102         col_cost_t       color_affinity[1];
103 } aff_chunk_t;
104
105 /**
106  * An affinity edge.
107  */
108 typedef struct aff_edge_t {
109         const ir_node *src;                   /**< Source node. */
110         const ir_node *tgt;                   /**< Target node. */
111         int           weight;                 /**< The weight of this edge. */
112 } aff_edge_t;
113
114 /* main coalescing environment */
115 typedef struct co_mst_env_t {
116         int              n_regs;         /**< number of regs in class */
117         bitset_t         *allocatable_regs; /**< set containing all global ignore registers */
118         ir_nodemap        map;           /**< phase object holding data for nodes */
119         struct obstack    obst;
120         pqueue_t         *chunks;        /**< priority queue for chunks */
121         list_head         chunklist;     /**< list holding all chunks */
122         be_ifg_t         *ifg;           /**< the interference graph */
123         copy_opt_t       *co;            /**< the copy opt object */
124         unsigned         chunk_visited;
125         col_cost_t      **single_cols;
126 } co_mst_env_t;
127
128 /* stores coalescing related information for a node */
129 typedef struct co_mst_irn_t {
130         const ir_node    *irn;              /**< the irn this information belongs to */
131         aff_chunk_t      *chunk;            /**< the chunk this irn belongs to */
132         bitset_t         *adm_colors;       /**< set of admissible colors for this irn */
133         ir_node          **int_neighs;      /**< array of all interfering neighbours (cached for speed reasons) */
134         int              n_neighs;          /**< length of the interfering neighbours array. */
135         int              int_aff_neigh;     /**< number of interfering affinity neighbours */
136         int              col;               /**< color currently assigned */
137         int              init_col;          /**< the initial color */
138         int              tmp_col;           /**< a temporary assigned color */
139         unsigned         fixed     : 1;     /**< the color is fixed */
140         struct list_head list;              /**< Queue for coloring undo. */
141         real_t           constr_factor;
142 } co_mst_irn_t;
143
144 /**
145  * In case there is no phase information for irn, initialize it.
146  */
147 static co_mst_irn_t *co_mst_irn_init(co_mst_env_t *env, const ir_node *irn)
148 {
149         co_mst_irn_t *res = OALLOC(&env->obst, co_mst_irn_t);
150
151         const arch_register_req_t *req;
152         neighbours_iter_t nodes_it;
153         ir_node  *neigh;
154         unsigned len;
155
156         res->irn           = irn;
157         res->chunk         = NULL;
158         res->fixed         = 0;
159         res->tmp_col       = -1;
160         res->int_neighs    = NULL;
161         res->int_aff_neigh = 0;
162         res->col           = arch_get_irn_register(irn)->index;
163         res->init_col      = res->col;
164         INIT_LIST_HEAD(&res->list);
165
166         DB((dbg, LEVEL_4, "Creating phase info for %+F\n", irn));
167
168         /* set admissible registers */
169         res->adm_colors = bitset_obstack_alloc(&env->obst, env->n_regs);
170
171         /* Exclude colors not assignable to the irn */
172         req = arch_get_irn_register_req(irn);
173         if (arch_register_req_is(req, limited)) {
174                 rbitset_copy_to_bitset(req->limited, res->adm_colors);
175                 /* exclude global ignore registers as well */
176                 bitset_and(res->adm_colors, env->allocatable_regs);
177         } else {
178                 bitset_copy(res->adm_colors, env->allocatable_regs);
179         }
180
181         /* compute the constraint factor */
182         res->constr_factor = (real_t) (1 + env->n_regs - bitset_popcount(res->adm_colors)) / env->n_regs;
183
184         /* set the number of interfering affinity neighbours to -1, they are calculated later */
185         res->int_aff_neigh = -1;
186
187         /* build list of interfering neighbours */
188         len = 0;
189         be_ifg_foreach_neighbour(env->ifg, &nodes_it, irn, neigh) {
190                 if (!arch_irn_is_ignore(neigh)) {
191                         obstack_ptr_grow(&env->obst, neigh);
192                         ++len;
193                 }
194         }
195         res->int_neighs = (ir_node**)obstack_finish(&env->obst);
196         res->n_neighs   = len;
197         return res;
198 }
199
200 static co_mst_irn_t *get_co_mst_irn(co_mst_env_t *env, const ir_node *node)
201 {
202         co_mst_irn_t *res = ir_nodemap_get(co_mst_irn_t, &env->map, node);
203         if (res == NULL) {
204                 res = co_mst_irn_init(env, node);
205                 ir_nodemap_insert(&env->map, node, res);
206         }
207         return res;
208 }
209
210 typedef int decide_func_t(const co_mst_irn_t *node, int col);
211
212 #ifdef DEBUG_libfirm
213
214 /**
215  * Write a chunk to stderr for debugging.
216  */
217 static void dbg_aff_chunk(const co_mst_env_t *env, const aff_chunk_t *c)
218 {
219         int i, l;
220         (void) env;
221         if (c->weight_consistent)
222                 ir_fprintf(stderr, " $%d ", c->weight);
223         ir_fprintf(stderr, "{");
224         for (i = 0, l = ARR_LEN(c->n); i < l; ++i) {
225                 const ir_node *n = c->n[i];
226                 ir_fprintf(stderr, " %+F,", n);
227         }
228         ir_fprintf(stderr, "}");
229 }
230
231 /**
232  * Dump all admissible colors to stderr.
233  */
234 static void dbg_admissible_colors(const co_mst_env_t *env, const co_mst_irn_t *node)
235 {
236         (void) env;
237
238         if (bitset_popcount(node->adm_colors) < 1)
239                 fprintf(stderr, "no admissible colors?!?");
240         else {
241                 bitset_foreach(node->adm_colors, idx) {
242                         ir_fprintf(stderr, " %zu", idx);
243                 }
244         }
245 }
246
247 /**
248  * Dump color-cost pairs to stderr.
249  */
250 static void dbg_col_cost(const co_mst_env_t *env, const col_cost_t *cost)
251 {
252         int i;
253         for (i = 0; i < env->n_regs; ++i)
254                 fprintf(stderr, " (%d, %.4f)", cost[i].col, cost[i].cost);
255 }
256
257 #endif /* DEBUG_libfirm */
258
259 static inline int get_mst_irn_col(const co_mst_irn_t *node)
260 {
261         return node->tmp_col >= 0 ? node->tmp_col : node->col;
262 }
263
264 /**
265  * @return 1 if node @p node has color @p col, 0 otherwise.
266  */
267 static int decider_has_color(const co_mst_irn_t *node, int col)
268 {
269         return get_mst_irn_col(node) == col;
270 }
271
272 /**
273  * @return 1 if node @p node has not color @p col, 0 otherwise.
274  */
275 static int decider_hasnot_color(const co_mst_irn_t *node, int col)
276 {
277         return get_mst_irn_col(node) != col;
278 }
279
280 /**
281  * Always returns true.
282  */
283 static int decider_always_yes(const co_mst_irn_t *node, int col)
284 {
285         (void) node;
286         (void) col;
287         return 1;
288 }
289
290 /** compares two affinity edges by its weight */
291 static int cmp_aff_edge(const void *a, const void *b)
292 {
293         const aff_edge_t *e1 = (const aff_edge_t*)a;
294         const aff_edge_t *e2 = (const aff_edge_t*)b;
295
296         if (e2->weight == e1->weight) {
297                 if (e2->src->node_idx == e1->src->node_idx)
298                         return QSORT_CMP(e2->tgt->node_idx, e1->tgt->node_idx);
299                 else
300                         return QSORT_CMP(e2->src->node_idx, e1->src->node_idx);
301         }
302         /* sort in descending order */
303         return QSORT_CMP(e2->weight, e1->weight);
304 }
305
306 /** compares to color-cost pairs */
307 static __attribute__((unused)) int cmp_col_cost_lt(const void *a, const void *b)
308 {
309         const col_cost_t *c1 = (const col_cost_t*)a;
310         const col_cost_t *c2 = (const col_cost_t*)b;
311         real_t diff = c1->cost - c2->cost;
312
313         if (diff < 0)
314                 return 1;
315         if (diff > 0)
316                 return -1;
317
318         return QSORT_CMP(c1->col, c2->col);
319 }
320
321 static int cmp_col_cost_gt(const void *a, const void *b)
322 {
323         const col_cost_t *c1 = (const col_cost_t*)a;
324         const col_cost_t *c2 = (const col_cost_t*)b;
325         real_t diff = c2->cost - c1->cost;
326
327         if (diff > 0)
328                 return 1;
329         if (diff < 0)
330                 return -1;
331
332         return QSORT_CMP(c1->col, c2->col);
333 }
334
335 /**
336  * Creates a new affinity chunk
337  */
338 static inline aff_chunk_t *new_aff_chunk(co_mst_env_t *env)
339 {
340         aff_chunk_t *c = XMALLOCF(aff_chunk_t, color_affinity, env->n_regs);
341         c->n                 = NEW_ARR_F(const ir_node *, 0);
342         c->interfere         = NEW_ARR_F(const ir_node *, 0);
343         c->weight            = -1;
344         c->weight_consistent = 0;
345         c->deleted           = 0;
346         c->id                = ++last_chunk_id;
347         c->visited           = 0;
348         list_add(&c->list, &env->chunklist);
349         return c;
350 }
351
352 /**
353  * Frees all memory allocated by an affinity chunk.
354  */
355 static inline void delete_aff_chunk(aff_chunk_t *c)
356 {
357         list_del(&c->list);
358         DEL_ARR_F(c->interfere);
359         DEL_ARR_F(c->n);
360         c->deleted = 1;
361         free(c);
362 }
363
364 /**
365  * binary search of sorted nodes.
366  *
367  * @return the position where n is found in the array arr or ~pos
368  * if the nodes is not here.
369  */
370 static inline int nodes_bsearch(const ir_node **arr, const ir_node *n)
371 {
372         int hi = ARR_LEN(arr);
373         int lo = 0;
374
375         while (lo < hi) {
376                 int md = lo + ((hi - lo) >> 1);
377
378                 if (arr[md] == n)
379                         return md;
380                 if (arr[md] < n)
381                         lo = md + 1;
382                 else
383                         hi = md;
384         }
385
386         return ~lo;
387 }
388
389 /** Check if a node n can be found inside arr. */
390 static int node_contains(const ir_node **arr, const ir_node *n)
391 {
392         int i = nodes_bsearch(arr, n);
393         return i >= 0;
394 }
395
396 /**
397  * Insert a node into the sorted nodes list.
398  *
399  * @return 1 if the node was inserted, 0 else
400  */
401 static int nodes_insert(const ir_node ***arr, const ir_node *irn)
402 {
403         int idx = nodes_bsearch(*arr, irn);
404
405         if (idx < 0) {
406                 int i, n = ARR_LEN(*arr);
407                 const ir_node **l;
408
409                 ARR_APP1(const ir_node *, *arr, irn);
410
411                 /* move it */
412                 idx = ~idx;
413                 l = *arr;
414                 for (i = n - 1; i >= idx; --i)
415                         l[i + 1] = l[i];
416                 l[idx] = irn;
417                 return 1;
418         }
419         return 0;
420 }
421
422 /**
423  * Adds a node to an affinity chunk
424  */
425 static inline void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node)
426 {
427         int i;
428
429         if (! nodes_insert(&c->n, node->irn))
430                 return;
431
432         c->weight_consistent = 0;
433         node->chunk          = c;
434
435         for (i = node->n_neighs - 1; i >= 0; --i) {
436                 ir_node *neigh = node->int_neighs[i];
437                 nodes_insert(&c->interfere, neigh);
438         }
439 }
440
441 /**
442  * Check if affinity chunk @p chunk interferes with node @p irn.
443  */
444 static inline int aff_chunk_interferes(const aff_chunk_t *chunk, const ir_node *irn)
445 {
446         return node_contains(chunk->interfere, irn);
447 }
448
449 /**
450  * Check if there are interference edges from c1 to c2.
451  * @param c1    A chunk
452  * @param c2    Another chunk
453  * @return 1 if there are interferences between nodes of c1 and c2, 0 otherwise.
454  */
455 static inline int aff_chunks_interfere(const aff_chunk_t *c1, const aff_chunk_t *c2)
456 {
457         int i;
458
459         if (c1 == c2)
460                 return 0;
461
462         /* check if there is a node in c2 having an interfering neighbor in c1 */
463         for (i = ARR_LEN(c2->n) - 1; i >= 0; --i) {
464                 const ir_node *irn = c2->n[i];
465
466                 if (node_contains(c1->interfere, irn))
467                         return 1;
468         }
469         return 0;
470 }
471
472 /**
473  * Returns the affinity chunk of @p irn or creates a new
474  * one with @p irn as element if there is none assigned.
475  */
476 static inline aff_chunk_t *get_aff_chunk(co_mst_env_t *env, const ir_node *irn)
477 {
478         co_mst_irn_t *node = get_co_mst_irn(env, irn);
479         return node->chunk;
480 }
481
482 /**
483  * Let chunk(src) absorb the nodes of chunk(tgt) (only possible when there
484  * are no interference edges from chunk(src) to chunk(tgt)).
485  * @return 1 if successful, 0 if not possible
486  */
487 static int aff_chunk_absorb(co_mst_env_t *env, const ir_node *src, const ir_node *tgt)
488 {
489         aff_chunk_t *c1 = get_aff_chunk(env, src);
490         aff_chunk_t *c2 = get_aff_chunk(env, tgt);
491
492 #ifdef DEBUG_libfirm
493                 DB((dbg, LEVEL_4, "Attempt to let c1 (id %u): ", c1 ? c1->id : 0));
494                 if (c1) {
495                         DBG_AFF_CHUNK(env, LEVEL_4, c1);
496                 } else {
497                         DB((dbg, LEVEL_4, "{%+F}", src));
498                 }
499                 DB((dbg, LEVEL_4, "\n\tabsorb c2 (id %u): ", c2 ? c2->id : 0));
500                 if (c2) {
501                         DBG_AFF_CHUNK(env, LEVEL_4, c2);
502                 } else {
503                         DB((dbg, LEVEL_4, "{%+F}", tgt));
504                 }
505                 DB((dbg, LEVEL_4, "\n"));
506 #endif
507
508         if (c1 == NULL) {
509                 if (c2 == NULL) {
510                         /* no chunk exists */
511                         co_mst_irn_t *mirn = get_co_mst_irn(env, src);
512                         int i;
513
514                         for (i = mirn->n_neighs - 1; i >= 0; --i) {
515                                 if (mirn->int_neighs[i] == tgt)
516                                         break;
517                         }
518                         if (i < 0) {
519                                 /* create one containing both nodes */
520                                 c1 = new_aff_chunk(env);
521                                 aff_chunk_add_node(c1, get_co_mst_irn(env, src));
522                                 aff_chunk_add_node(c1, get_co_mst_irn(env, tgt));
523                                 goto absorbed;
524                         }
525                 } else {
526                         /* c2 already exists */
527                         if (! aff_chunk_interferes(c2, src)) {
528                                 aff_chunk_add_node(c2, get_co_mst_irn(env, src));
529                                 goto absorbed;
530                         }
531                 }
532         } else if (c2 == NULL) {
533                 /* c1 already exists */
534                 if (! aff_chunk_interferes(c1, tgt)) {
535                         aff_chunk_add_node(c1, get_co_mst_irn(env, tgt));
536                         goto absorbed;
537                 }
538         } else if (c1 != c2 && ! aff_chunks_interfere(c1, c2)) {
539                 int idx, len;
540
541                 for (idx = 0, len = ARR_LEN(c2->n); idx < len; ++idx)
542                         aff_chunk_add_node(c1, get_co_mst_irn(env, c2->n[idx]));
543
544                 for (idx = 0, len = ARR_LEN(c2->interfere); idx < len; ++idx) {
545                         const ir_node *irn = c2->interfere[idx];
546                         nodes_insert(&c1->interfere, irn);
547                 }
548
549                 c1->weight_consistent = 0;
550
551                 delete_aff_chunk(c2);
552                 goto absorbed;
553         }
554         DB((dbg, LEVEL_4, " ... c1 interferes with c2, skipped\n"));
555         return 0;
556
557 absorbed:
558         DB((dbg, LEVEL_4, " ... absorbed\n"));
559         return 1;
560 }
561
562 /**
563  * Assures that the weight of the given chunk is consistent.
564  */
565 static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
566 {
567         if (! c->weight_consistent) {
568                 int w = 0;
569                 int idx, len, i;
570
571                 for (i = 0; i < env->n_regs; ++i) {
572                         c->color_affinity[i].col = i;
573                         c->color_affinity[i].cost = REAL(0.0);
574                 }
575
576                 for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
577                         const ir_node         *n       = c->n[idx];
578                         const affinity_node_t *an      = get_affinity_info(env->co, n);
579                         co_mst_irn_t          *node    = get_co_mst_irn(env, n);
580
581                         node->chunk = c;
582                         if (node->constr_factor > REAL(0.0)) {
583                                 bitset_foreach (node->adm_colors, col)
584                                         c->color_affinity[col].cost += node->constr_factor;
585                         }
586
587                         if (an != NULL) {
588                                 co_gs_foreach_neighb(an, neigh) {
589                                         const ir_node *m = neigh->irn;
590
591                                         if (arch_irn_is_ignore(m))
592                                                 continue;
593
594                                         w += node_contains(c->n, m) ? neigh->costs : 0;
595                                 }
596                         }
597                 }
598
599                 for (i = 0; i < env->n_regs; ++i)
600                         c->color_affinity[i].cost *= (REAL(1.0) / ARR_LEN(c->n));
601
602                 c->weight            = w;
603                 // c->weight            = bitset_popcount(c->nodes);
604                 c->weight_consistent = 1;
605         }
606 }
607
608 /**
609  * Count the number of interfering affinity neighbours
610  */
611 static int count_interfering_aff_neighs(co_mst_env_t *env, const affinity_node_t *an)
612 {
613         const ir_node      *irn  = an->irn;
614         const co_mst_irn_t *node = get_co_mst_irn(env, irn);
615         int                res   = 0;
616
617         co_gs_foreach_neighb(an, neigh) {
618                 const ir_node *n = neigh->irn;
619                 int           i;
620
621                 if (arch_irn_is_ignore(n))
622                         continue;
623
624                 /* check if the affinity neighbour interfere */
625                 for (i = 0; i < node->n_neighs; ++i) {
626                         if (node->int_neighs[i] == n) {
627                                 ++res;
628                                 break;
629                         }
630                 }
631         }
632         return res;
633 }
634
635
636 /**
637  * Build chunks of nodes connected by affinity edges.
638  * We start at the heaviest affinity edge.
639  * The chunks of the two edge-defining nodes will be
640  * merged if there are no interference edges from one
641  * chunk to the other.
642  */
643 static void build_affinity_chunks(co_mst_env_t *env)
644 {
645         nodes_iter_t nodes_it;
646         aff_edge_t  *edges    = NEW_ARR_F(aff_edge_t, 0);
647         ir_node     *n;
648         int         i, len;
649         size_t      pn;
650
651         /* at first we create the affinity edge objects */
652         be_ifg_foreach_node(env->ifg, &nodes_it, n) {
653                 int             n_idx = get_irn_idx(n);
654                 co_mst_irn_t    *n1;
655                 affinity_node_t *an;
656
657                 if (arch_irn_is_ignore(n))
658                         continue;
659
660                 n1 = get_co_mst_irn(env, n);
661                 an = get_affinity_info(env->co, n);
662
663                 if (an != NULL) {
664                         if (n1->int_aff_neigh < 0)
665                                 n1->int_aff_neigh = count_interfering_aff_neighs(env, an);
666
667                         /* build the affinity edges */
668                         co_gs_foreach_neighb(an, neigh) {
669                                 const ir_node *m     = neigh->irn;
670                                 int            m_idx = get_irn_idx(m);
671
672                                 /* record the edge in only one direction */
673                                 if (n_idx < m_idx) {
674                                         co_mst_irn_t *n2;
675                                         aff_edge_t   edge;
676
677                                         /* skip ignore nodes */
678                                         if (arch_irn_is_ignore(m))
679                                                 continue;
680
681                                         edge.src = n;
682                                         edge.tgt = m;
683
684                                         n2 = get_co_mst_irn(env, m);
685                                         if (n2->int_aff_neigh < 0) {
686                                                 affinity_node_t *am = get_affinity_info(env->co, m);
687                                                 n2->int_aff_neigh = count_interfering_aff_neighs(env, am);
688                                         }
689                                         /*
690                                          * these weights are pure hackery ;-).
691                                          * It's not chriswue's fault but mine.
692                                          */
693                                         edge.weight = neigh->costs;
694                                         ARR_APP1(aff_edge_t, edges, edge);
695                                 }
696                         }
697                 }
698         }
699
700         /* now: sort edges and build the affinity chunks */
701         len = ARR_LEN(edges);
702         qsort(edges, len, sizeof(edges[0]), cmp_aff_edge);
703         for (i = 0; i < len; ++i) {
704                 DBG((dbg, LEVEL_1, "edge (%u,%u) %f\n", edges[i].src->node_idx, edges[i].tgt->node_idx, edges[i].weight));
705
706                 (void)aff_chunk_absorb(env, edges[i].src, edges[i].tgt);
707         }
708
709         /* now insert all chunks into a priority queue */
710         list_for_each_entry(aff_chunk_t, curr_chunk, &env->chunklist, list) {
711                 aff_chunk_assure_weight(env, curr_chunk);
712
713                 DBG((dbg, LEVEL_1, "entry #%u", curr_chunk->id));
714                 DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
715                 DBG((dbg, LEVEL_1, "\n"));
716
717                 pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
718         }
719
720         for (pn = 0; pn < ARR_LEN(env->map.data); ++pn) {
721                 co_mst_irn_t *mirn = (co_mst_irn_t*)env->map.data[pn];
722                 if (mirn == NULL)
723                         continue;
724                 if (mirn->chunk != NULL)
725                         continue;
726
727                 /* no chunk is allocated so far, do it now */
728                 aff_chunk_t *curr_chunk = new_aff_chunk(env);
729                 aff_chunk_add_node(curr_chunk, mirn);
730
731                 aff_chunk_assure_weight(env, curr_chunk);
732
733                 DBG((dbg, LEVEL_1, "entry #%u", curr_chunk->id));
734                 DBG_AFF_CHUNK(env, LEVEL_1, curr_chunk);
735                 DBG((dbg, LEVEL_1, "\n"));
736
737                 pqueue_put(env->chunks, curr_chunk, curr_chunk->weight);
738         }
739
740         DEL_ARR_F(edges);
741 }
742
743 static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chunk_t *chunk)
744 {
745         pqueue_t      *grow       = new_pqueue();
746         ir_node const *max_node   = NULL;
747         int            max_weight = 0;
748         size_t         i;
749
750         for (i = ARR_LEN(chunk->n); i != 0;) {
751                 const ir_node   *irn = chunk->n[--i];
752                 affinity_node_t *an  = get_affinity_info(env->co, irn);
753                 int w = 0;
754
755                 if (arch_irn_is_ignore(irn))
756                         continue;
757
758                 if (an) {
759                         co_gs_foreach_neighb(an, neigh)
760                                 w += neigh->costs;
761
762                         if (w > max_weight) {
763                                 max_weight = w;
764                                 max_node   = irn;
765                         }
766                 }
767         }
768
769         if (max_node) {
770                 bitset_t *visited = bitset_malloc(get_irg_last_idx(env->co->irg));
771
772                 for (i = ARR_LEN(chunk->n); i != 0;)
773                         bitset_set(visited, get_irn_idx(chunk->n[--i]));
774
775                 pqueue_put(grow, (void *) max_node, max_weight);
776                 bitset_clear(visited, get_irn_idx(max_node));
777                 i = 0;
778                 while (!pqueue_empty(grow)) {
779                         ir_node *irn = (ir_node*)pqueue_pop_front(grow);
780                         affinity_node_t *an = get_affinity_info(env->co, irn);
781
782                         if (arch_irn_is_ignore(irn))
783                                 continue;
784
785                         assert(i <= ARR_LEN(chunk->n));
786                         chunk->n[i++] = irn;
787
788                         assert(an);
789
790                         /* build the affinity edges */
791                         co_gs_foreach_neighb(an, neigh) {
792                                 co_mst_irn_t *node = get_co_mst_irn(env, neigh->irn);
793
794                                 if (bitset_is_set(visited, get_irn_idx(node->irn))) {
795                                         pqueue_put(grow, (void *) neigh->irn, neigh->costs);
796                                         bitset_clear(visited, get_irn_idx(node->irn));
797                                 }
798                         }
799                 }
800
801                 del_pqueue(grow);
802                 bitset_free(visited);
803         }
804 }
805
806 /**
807  * Greedy collect affinity neighbours into thew new chunk @p chunk starting at node @p node.
808  */
809 static void expand_chunk_from(co_mst_env_t *env, co_mst_irn_t *node, bitset_t *visited,
810         aff_chunk_t *chunk, aff_chunk_t *orig_chunk, decide_func_t *decider, int col)
811 {
812         waitq *nodes = new_waitq();
813
814         DBG((dbg, LEVEL_1, "\n\tExpanding new chunk (#%u) from %+F, color %d:", chunk->id, node->irn, col));
815
816         /* init queue and chunk */
817         waitq_put(nodes, node);
818         bitset_set(visited, get_irn_idx(node->irn));
819         aff_chunk_add_node(chunk, node);
820         DB((dbg, LEVEL_1, " %+F", node->irn));
821
822         /* as long as there are nodes in the queue */
823         while (! waitq_empty(nodes)) {
824                 co_mst_irn_t    *n  = (co_mst_irn_t*)waitq_get(nodes);
825                 affinity_node_t *an = get_affinity_info(env->co, n->irn);
826
827                 /* check all affinity neighbors */
828                 if (an != NULL) {
829                         co_gs_foreach_neighb(an, neigh) {
830                                 const ir_node *m    = neigh->irn;
831                                 int            m_idx = get_irn_idx(m);
832                                 co_mst_irn_t *n2;
833
834                                 if (arch_irn_is_ignore(m))
835                                         continue;
836
837                                 n2 = get_co_mst_irn(env, m);
838
839                                 if (! bitset_is_set(visited, m_idx)  &&
840                                         decider(n2, col)                 &&
841                                         ! n2->fixed                      &&
842                                         ! aff_chunk_interferes(chunk, m) &&
843                                         node_contains(orig_chunk->n, m))
844                                 {
845                                         /*
846                                                 following conditions are met:
847                                                 - neighbour is not visited
848                                                 - neighbour likes the color
849                                                 - neighbour has not yet a fixed color
850                                                 - the new chunk doesn't interfere with the neighbour
851                                                 - neighbour belongs or belonged once to the original chunk
852                                         */
853                                         bitset_set(visited, m_idx);
854                                         aff_chunk_add_node(chunk, n2);
855                                         DB((dbg, LEVEL_1, " %+F", n2->irn));
856                                         /* enqueue for further search */
857                                         waitq_put(nodes, n2);
858                                 }
859                         }
860                 }
861         }
862
863         DB((dbg, LEVEL_1, "\n"));
864
865         del_waitq(nodes);
866 }
867
868 /**
869  * Fragment the given chunk into chunks having given color and not having given color.
870  */
871 static aff_chunk_t *fragment_chunk(co_mst_env_t *env, int col, aff_chunk_t *c, waitq *tmp)
872 {
873         bitset_t    *visited = bitset_malloc(get_irg_last_idx(env->co->irg));
874         int         idx, len;
875         aff_chunk_t *best = NULL;
876
877         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
878                 const ir_node *irn;
879                 co_mst_irn_t  *node;
880                 aff_chunk_t   *tmp_chunk;
881                 decide_func_t *decider;
882                 int           check_for_best;
883
884                 irn = c->n[idx];
885                 if (bitset_is_set(visited, get_irn_idx(irn)))
886                         continue;
887
888                 node = get_co_mst_irn(env, irn);
889
890                 if (get_mst_irn_col(node) == col) {
891                         decider        = decider_has_color;
892                         check_for_best = 1;
893                         DBG((dbg, LEVEL_4, "\tcolor %d wanted\n", col));
894                 }
895                 else {
896                         decider        = decider_hasnot_color;
897                         check_for_best = 0;
898                         DBG((dbg, LEVEL_4, "\tcolor %d forbidden\n", col));
899                 }
900
901                 /* create a new chunk starting at current node */
902                 tmp_chunk = new_aff_chunk(env);
903                 waitq_put(tmp, tmp_chunk);
904                 expand_chunk_from(env, node, visited, tmp_chunk, c, decider, col);
905                 assert(ARR_LEN(tmp_chunk->n) > 0 && "No nodes added to chunk");
906
907                 /* remember the local best */
908                 aff_chunk_assure_weight(env, tmp_chunk);
909                 if (check_for_best && (! best || best->weight < tmp_chunk->weight))
910                         best = tmp_chunk;
911         }
912
913         assert(best && "No chunk found?");
914         bitset_free(visited);
915         return best;
916 }
917
918 /**
919  * Resets the temporary fixed color of all nodes within wait queue @p nodes.
920  * ATTENTION: the queue is empty after calling this function!
921  */
922 static inline void reject_coloring(struct list_head *nodes)
923 {
924         DB((dbg, LEVEL_4, "\treject coloring for"));
925         list_for_each_entry_safe(co_mst_irn_t, n, temp, nodes, list) {
926                 DB((dbg, LEVEL_4, " %+F", n->irn));
927                 assert(n->tmp_col >= 0);
928                 n->tmp_col = -1;
929                 list_del_init(&n->list);
930         }
931         DB((dbg, LEVEL_4, "\n"));
932 }
933
934 static inline void materialize_coloring(struct list_head *nodes)
935 {
936         list_for_each_entry_safe(co_mst_irn_t, n, temp, nodes, list) {
937                 assert(n->tmp_col >= 0);
938                 n->col     = n->tmp_col;
939                 n->tmp_col = -1;
940                 list_del_init(&n->list);
941         }
942 }
943
944 static inline void set_temp_color(co_mst_irn_t *node, int col, struct list_head *changed)
945 {
946         assert(col >= 0);
947         assert(!node->fixed);
948         assert(node->tmp_col < 0);
949         assert(node->list.next == &node->list && node->list.prev == &node->list);
950         assert(bitset_is_set(node->adm_colors, col));
951
952         list_add_tail(&node->list, changed);
953         node->tmp_col = col;
954 }
955
956 static inline int is_loose(co_mst_irn_t *node)
957 {
958         return !node->fixed && node->tmp_col < 0;
959 }
960
961 /**
962  * Determines the costs for each color if it would be assigned to node @p node.
963  */
964 static void determine_color_costs(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs)
965 {
966         int   *neigh_cols = ALLOCAN(int, env->n_regs);
967         int    n_loose    = 0;
968         real_t coeff;
969         int    i;
970
971         for (i = 0; i < env->n_regs; ++i) {
972                 neigh_cols[i] = 0;
973                 costs[i].col = i;
974                 costs[i].cost = bitset_is_set(node->adm_colors, i) ? node->constr_factor : REAL(0.0);
975         }
976
977         for (i = 0; i < node->n_neighs; ++i) {
978                 co_mst_irn_t *n = get_co_mst_irn(env, node->int_neighs[i]);
979                 int col = get_mst_irn_col(n);
980                 if (is_loose(n)) {
981                         ++n_loose;
982                         ++neigh_cols[col];
983                 } else
984                         costs[col].cost = REAL(0.0);
985         }
986
987         if (n_loose > 0) {
988                 coeff = REAL(1.0) / n_loose;
989                 for (i = 0; i < env->n_regs; ++i)
990                         costs[i].cost *= REAL(1.0) - coeff * neigh_cols[i];
991         }
992 }
993
994 /* need forward declaration due to recursive call */
995 static int recolor_nodes(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs, struct list_head *changed_ones, int depth, int *max_depth, int *trip);
996
997 /**
998  * Tries to change node to a color but @p explude_col.
999  * @return 1 if succeeded, 0 otherwise.
1000  */
1001 static int change_node_color_excluded(co_mst_env_t *env, co_mst_irn_t *node, int exclude_col, struct list_head *changed, int depth, int *max_depth, int *trip)
1002 {
1003         int col = get_mst_irn_col(node);
1004         int res = 0;
1005
1006         /* neighbours has already a different color -> good, temporary fix it */
1007         if (col != exclude_col) {
1008                 if (is_loose(node))
1009                         set_temp_color(node, col, changed);
1010                 return 1;
1011         }
1012
1013         /* The node has the color it should not have _and_ has not been visited yet. */
1014         if (is_loose(node)) {
1015                 col_cost_t *costs = ALLOCAN(col_cost_t, env->n_regs);
1016
1017                 /* Get the costs for giving the node a specific color. */
1018                 determine_color_costs(env, node, costs);
1019
1020                 /* Since the node must not have the not_col, set the costs for that color to "infinity" */
1021                 costs[exclude_col].cost = REAL(0.0);
1022
1023                 /* sort the colors according costs, cheapest first. */
1024                 qsort(costs, env->n_regs, sizeof(costs[0]), cmp_col_cost_gt);
1025
1026                 /* Try recoloring the node using the color list. */
1027                 res = recolor_nodes(env, node, costs, changed, depth + 1, max_depth, trip);
1028         }
1029
1030         return res;
1031 }
1032
1033 /**
1034  * Tries to bring node @p node to cheapest color and color all interfering neighbours with other colors.
1035  * ATTENTION: Expect @p costs already sorted by increasing costs.
1036  * @return 1 if coloring could be applied, 0 otherwise.
1037  */
1038 static int recolor_nodes(co_mst_env_t *env, co_mst_irn_t *node, col_cost_t *costs, struct list_head *changed, int depth, int *max_depth, int *trip)
1039 {
1040         int   i;
1041         struct list_head local_changed;
1042
1043         ++*trip;
1044         if (depth > *max_depth)
1045                 *max_depth = depth;
1046
1047         DBG((dbg, LEVEL_4, "\tRecoloring %+F with color-costs", node->irn));
1048         DBG_COL_COST(env, LEVEL_4, costs);
1049         DB((dbg, LEVEL_4, "\n"));
1050
1051         if (depth >= recolor_limit) {
1052                 DBG((dbg, LEVEL_4, "\tHit recolor limit\n"));
1053                 return 0;
1054         }
1055
1056         for (i = 0; i < env->n_regs; ++i) {
1057                 int tgt_col  = costs[i].col;
1058                 int neigh_ok = 1;
1059                 int j;
1060
1061                 /* If the costs for that color (and all successive) are infinite, bail out we won't make it anyway. */
1062                 if (costs[i].cost == REAL(0.0)) {
1063                         DBG((dbg, LEVEL_4, "\tAll further colors forbidden\n"));
1064                         return 0;
1065                 }
1066
1067                 /* Set the new color of the node and mark the node as temporarily fixed. */
1068                 assert(node->tmp_col < 0 && "Node must not have been temporary fixed.");
1069                 INIT_LIST_HEAD(&local_changed);
1070                 set_temp_color(node, tgt_col, &local_changed);
1071                 DBG((dbg, LEVEL_4, "\tTemporary setting %+F to color %d\n", node->irn, tgt_col));
1072
1073                 /* try to color all interfering neighbours with current color forbidden */
1074                 for (j = 0; j < node->n_neighs; ++j) {
1075                         co_mst_irn_t *nn;
1076                         ir_node      *neigh;
1077
1078                         neigh = node->int_neighs[j];
1079
1080                         if (arch_irn_is_ignore(neigh))
1081                                 continue;
1082
1083                         nn = get_co_mst_irn(env, neigh);
1084                         DB((dbg, LEVEL_4, "\tHandling neighbour %+F, at position %d (fixed: %d, tmp_col: %d, col: %d)\n",
1085                                 neigh, j, nn->fixed, nn->tmp_col, nn->col));
1086
1087                         /*
1088                                 Try to change the color of the neighbor and record all nodes which
1089                                 get changed in the tmp list. Add this list to the "changed" list for
1090                                 that color. If we did not succeed to change the color of the neighbor,
1091                                 we bail out and try the next color.
1092                         */
1093                         if (get_mst_irn_col(nn) == tgt_col) {
1094                                 /* try to color neighbour with tgt_col forbidden */
1095                                 neigh_ok = change_node_color_excluded(env, nn, tgt_col, &local_changed, depth + 1, max_depth, trip);
1096
1097                                 if (!neigh_ok)
1098                                         break;
1099                         }
1100                 }
1101
1102                 /*
1103                         We managed to assign the target color to all neighbors, so from the perspective
1104                         of the current node, every thing was ok and we can return safely.
1105                 */
1106                 if (neigh_ok) {
1107                         /* append the local_changed ones to global ones */
1108                         list_splice(&local_changed, changed);
1109                         return 1;
1110                 }
1111                 else {
1112                         /* coloring of neighbours failed, so we try next color */
1113                         reject_coloring(&local_changed);
1114                 }
1115         }
1116
1117         DBG((dbg, LEVEL_4, "\tAll colors failed\n"));
1118         return 0;
1119 }
1120
1121 /**
1122  * Tries to bring node @p node and all its neighbours to color @p tgt_col.
1123  * @return 1 if color @p col could be applied, 0 otherwise
1124  */
1125 static int change_node_color(co_mst_env_t *env, co_mst_irn_t *node, int tgt_col, struct list_head *changed)
1126 {
1127         int col = get_mst_irn_col(node);
1128
1129         /* if node already has the target color -> good, temporary fix it */
1130         if (col == tgt_col) {
1131                 DBG((dbg, LEVEL_4, "\t\tCNC: %+F has already color %d, fix temporary\n", node->irn, tgt_col));
1132                 if (is_loose(node))
1133                         set_temp_color(node, tgt_col, changed);
1134                 return 1;
1135         }
1136
1137         /*
1138                 Node has not yet a fixed color and target color is admissible
1139                 -> try to recolor node and its affinity neighbours
1140         */
1141         if (is_loose(node) && bitset_is_set(node->adm_colors, tgt_col)) {
1142                 col_cost_t *costs = env->single_cols[tgt_col];
1143                 int res, max_depth, trip;
1144
1145                 max_depth = 0;
1146                 trip      = 0;
1147
1148                 DBG((dbg, LEVEL_4, "\t\tCNC: Attempt to recolor %+F ===>>\n", node->irn));
1149                 res = recolor_nodes(env, node, costs, changed, 0, &max_depth, &trip);
1150                 DBG((dbg, LEVEL_4, "\t\tCNC: <<=== Recoloring of %+F %s\n", node->irn, res ? "succeeded" : "failed"));
1151                 stat_ev_int("heur4_recolor_depth_max", max_depth);
1152                 stat_ev_int("heur4_recolor_trip", trip);
1153
1154
1155                 return res;
1156         }
1157
1158 #ifdef DEBUG_libfirm
1159                 if (firm_dbg_get_mask(dbg) & LEVEL_4) {
1160                         if (!is_loose(node))
1161                                 DB((dbg, LEVEL_4, "\t\tCNC: %+F has already fixed color %d\n", node->irn, col));
1162                         else {
1163                                 DB((dbg, LEVEL_4, "\t\tCNC: color %d not admissible for %+F (", tgt_col, node->irn));
1164                                 dbg_admissible_colors(env, node);
1165                                 DB((dbg, LEVEL_4, ")\n"));
1166                         }
1167                 }
1168 #endif
1169
1170         return 0;
1171 }
1172
1173 /**
1174  * Tries to color an affinity chunk (or at least a part of it).
1175  * Inserts uncolored parts of the chunk as a new chunk into the priority queue.
1176  */
1177 static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c)
1178 {
1179         aff_chunk_t *best_chunk   = NULL;
1180         int         n_nodes       = ARR_LEN(c->n);
1181         int         best_color    = -1;
1182         int         n_int_chunks  = 0;
1183         waitq       *tmp_chunks   = new_waitq();
1184         waitq       *best_starts  = NULL;
1185         col_cost_t  *order        = ALLOCANZ(col_cost_t, env->n_regs);
1186         bitset_t    *visited;
1187         int         i;
1188         size_t      idx;
1189         size_t      len;
1190         size_t      nidx;
1191         size_t      pos;
1192         struct list_head changed;
1193
1194         DB((dbg, LEVEL_2, "fragmentizing chunk #%u", c->id));
1195         DBG_AFF_CHUNK(env, LEVEL_2, c);
1196         DB((dbg, LEVEL_2, "\n"));
1197
1198         stat_ev_ctx_push_fmt("heur4_color_chunk", "%u", c->id);
1199
1200         ++env->chunk_visited;
1201
1202         /* compute color preference */
1203         for (pos = 0, len = ARR_LEN(c->interfere); pos < len; ++pos) {
1204                 const ir_node *n = c->interfere[pos];
1205                 co_mst_irn_t *node = get_co_mst_irn(env, n);
1206                 aff_chunk_t *chunk = node->chunk;
1207
1208                 if (is_loose(node) && chunk && chunk->visited < env->chunk_visited) {
1209                         assert(!chunk->deleted);
1210                         chunk->visited = env->chunk_visited;
1211                         ++n_int_chunks;
1212
1213                         aff_chunk_assure_weight(env, chunk);
1214                         for (i = 0; i < env->n_regs; ++i)
1215                                 order[i].cost += chunk->color_affinity[i].cost;
1216                 }
1217         }
1218
1219         for (i = 0; i < env->n_regs; ++i) {
1220                 real_t dislike = n_int_chunks > 0 ? REAL(1.0) - order[i].cost / n_int_chunks : REAL(0.0);
1221                 order[i].col  = i;
1222                 order[i].cost = (REAL(1.0) - dislike_influence) * c->color_affinity[i].cost + dislike_influence * dislike;
1223         }
1224
1225         qsort(order, env->n_regs, sizeof(order[0]), cmp_col_cost_gt);
1226
1227         DBG_COL_COST(env, LEVEL_2, order);
1228         DB((dbg, LEVEL_2, "\n"));
1229
1230         /* check which color is the "best" for the given chunk.
1231          * if we found a color which was ok for all nodes, we take it
1232          * and do not look further. (see did_all flag usage below.)
1233          * If we have many colors which fit all nodes it is hard to decide
1234          * which one to take anyway.
1235          * TODO Sebastian: Perhaps we should at all nodes and figure out
1236          * a suitable color using costs as done above (determine_color_costs).
1237          */
1238         for (i = 0; i < env->n_regs; ++i) {
1239                 int         col = order[i].col;
1240                 waitq       *good_starts;
1241                 aff_chunk_t *local_best;
1242                 int          n_succeeded;
1243
1244                 /* skip ignore colors */
1245                 if (!bitset_is_set(env->allocatable_regs, col))
1246                         continue;
1247
1248                 DB((dbg, LEVEL_2, "\ttrying color %d\n", col));
1249
1250                 n_succeeded = 0;
1251                 good_starts = new_waitq();
1252
1253                 /* try to bring all nodes of given chunk to the current color. */
1254                 for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1255                         const ir_node   *irn  = c->n[idx];
1256                         co_mst_irn_t    *node = get_co_mst_irn(env, irn);
1257                         int              good;
1258
1259                         assert(! node->fixed && "Node must not have a fixed color.");
1260                         DB((dbg, LEVEL_4, "\t\tBringing %+F from color %d to color %d ...\n", irn, node->col, col));
1261
1262                         /*
1263                                 The order of the colored nodes is important, so we record the successfully
1264                                 colored ones in the order they appeared.
1265                         */
1266                         INIT_LIST_HEAD(&changed);
1267                         stat_ev_tim_push();
1268                         good = change_node_color(env, node, col, &changed);
1269                         stat_ev_tim_pop("heur4_recolor");
1270                         if (good) {
1271                                 waitq_put(good_starts, node);
1272                                 materialize_coloring(&changed);
1273                                 node->fixed = 1;
1274                         }
1275
1276                         else
1277                                 reject_coloring(&changed);
1278
1279                         n_succeeded += good;
1280                         DB((dbg, LEVEL_4, "\t\t... %+F attempt from %d to %d %s\n", irn, node->col, col, good ? "succeeded" : "failed"));
1281                 }
1282
1283                 /* unfix all nodes */
1284                 for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1285                         co_mst_irn_t *node = get_co_mst_irn(env, c->n[idx]);
1286                         node->fixed = 0;
1287                 }
1288
1289                 /* try next color when failed */
1290                 if (n_succeeded == 0) {
1291                         del_waitq(good_starts);
1292                         continue;
1293                 }
1294
1295                 /* fragment the chunk according to the coloring */
1296                 local_best = fragment_chunk(env, col, c, tmp_chunks);
1297
1298                 /* search the best of the good list
1299                    and make it the new best if it is better than the current */
1300                 if (local_best) {
1301                         aff_chunk_assure_weight(env, local_best);
1302
1303                         DB((dbg, LEVEL_3, "\t\tlocal best chunk (id %u) for color %d: ", local_best->id, col));
1304                         DBG_AFF_CHUNK(env, LEVEL_3, local_best);
1305
1306                         if (! best_chunk || best_chunk->weight < local_best->weight) {
1307                                 best_chunk = local_best;
1308                                 best_color = col;
1309                                 if (best_starts)
1310                                         del_waitq(best_starts);
1311                                 best_starts = good_starts;
1312                                 DB((dbg, LEVEL_3, "\n\t\t... setting global best chunk (id %u), color %d\n", best_chunk->id, best_color));
1313                         } else {
1314                                 DB((dbg, LEVEL_3, "\n\t\t... omitting, global best is better\n"));
1315                                 del_waitq(good_starts);
1316                         }
1317                 }
1318                 else {
1319                         del_waitq(good_starts);
1320                 }
1321
1322                 /* if all nodes were recolored, bail out */
1323                 if (n_succeeded == n_nodes)
1324                         break;
1325         }
1326
1327         stat_ev_int("heur4_colors_tried", i);
1328
1329         /* free all intermediate created chunks except best one */
1330         while (! waitq_empty(tmp_chunks)) {
1331                 aff_chunk_t *tmp = (aff_chunk_t*)waitq_get(tmp_chunks);
1332                 if (tmp != best_chunk)
1333                         delete_aff_chunk(tmp);
1334         }
1335         del_waitq(tmp_chunks);
1336
1337         /* return if coloring failed */
1338         if (! best_chunk) {
1339                 if (best_starts)
1340                         del_waitq(best_starts);
1341                 return;
1342         }
1343
1344         DB((dbg, LEVEL_2, "\tbest chunk #%u ", best_chunk->id));
1345         DBG_AFF_CHUNK(env, LEVEL_2, best_chunk);
1346         DB((dbg, LEVEL_2, "using color %d\n", best_color));
1347
1348         for (idx = 0, len = ARR_LEN(best_chunk->n); idx < len; ++idx) {
1349                 const ir_node *irn  = best_chunk->n[idx];
1350                 co_mst_irn_t  *node = get_co_mst_irn(env, irn);
1351                 int res;
1352
1353                 /* bring the node to the color. */
1354                 DB((dbg, LEVEL_4, "\tManifesting color %d for %+F, chunk #%u\n", best_color, node->irn, best_chunk->id));
1355                 INIT_LIST_HEAD(&changed);
1356                 stat_ev_tim_push();
1357                 res = change_node_color(env, node, best_color, &changed);
1358                 stat_ev_tim_pop("heur4_recolor");
1359                 if (res) {
1360                         materialize_coloring(&changed);
1361                         node->fixed = 1;
1362                 }
1363                 assert(list_empty(&changed));
1364         }
1365
1366         /* remove the nodes in best chunk from original chunk */
1367         len = ARR_LEN(best_chunk->n);
1368         for (idx = 0; idx < len; ++idx) {
1369                 const ir_node *irn = best_chunk->n[idx];
1370                 int pos = nodes_bsearch(c->n, irn);
1371
1372                 if (pos > 0)
1373                         c->n[pos] = NULL;
1374         }
1375         len = ARR_LEN(c->n);
1376         for (idx = nidx = 0; idx < len; ++idx) {
1377                 const ir_node *irn = c->n[idx];
1378
1379                 if (irn != NULL) {
1380                         c->n[nidx++] = irn;
1381                 }
1382         }
1383         ARR_SHRINKLEN(c->n, nidx);
1384
1385
1386         /* we have to get the nodes back into the original chunk because they are scattered over temporary chunks */
1387         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1388                 const ir_node *n  = c->n[idx];
1389                 co_mst_irn_t  *nn = get_co_mst_irn(env, n);
1390                 nn->chunk = c;
1391         }
1392
1393         /* fragment the remaining chunk */
1394         visited = bitset_malloc(get_irg_last_idx(env->co->irg));
1395         for (idx = 0, len = ARR_LEN(best_chunk->n); idx < len; ++idx)
1396                 bitset_set(visited, get_irn_idx(best_chunk->n[idx]));
1397
1398         for (idx = 0, len = ARR_LEN(c->n); idx < len; ++idx) {
1399                 const ir_node *irn = c->n[idx];
1400                 if (! bitset_is_set(visited, get_irn_idx(irn))) {
1401                         aff_chunk_t  *new_chunk = new_aff_chunk(env);
1402                         co_mst_irn_t *node      = get_co_mst_irn(env, irn);
1403
1404                         expand_chunk_from(env, node, visited, new_chunk, c, decider_always_yes, 0);
1405                         aff_chunk_assure_weight(env, new_chunk);
1406                         pqueue_put(env->chunks, new_chunk, new_chunk->weight);
1407                 }
1408         }
1409
1410         for (idx = 0, len = ARR_LEN(best_chunk->n); idx < len; ++idx) {
1411                 const ir_node *n  = best_chunk->n[idx];
1412                 co_mst_irn_t  *nn = get_co_mst_irn(env, n);
1413                 nn->chunk = NULL;
1414         }
1415
1416         /* clear obsolete chunks and free some memory */
1417         delete_aff_chunk(best_chunk);
1418         bitset_free(visited);
1419         if (best_starts)
1420                 del_waitq(best_starts);
1421
1422         stat_ev_ctx_pop("heur4_color_chunk");
1423 }
1424
1425 /**
1426  * Main driver for mst safe coalescing algorithm.
1427  */
1428 static int co_solve_heuristic_mst(copy_opt_t *co)
1429 {
1430         unsigned     n_regs            = co->cls->n_regs;
1431         bitset_t     *allocatable_regs = bitset_alloca(n_regs);
1432         unsigned     i, j;
1433         size_t       pn;
1434         ir_node      *irn;
1435         co_mst_env_t mst_env;
1436
1437         last_chunk_id = 0;
1438
1439         stat_ev_tim_push();
1440
1441         /* init phase */
1442         ir_nodemap_init(&mst_env.map, co->irg);
1443         obstack_init(&mst_env.obst);
1444
1445         be_put_allocatable_regs(co->cenv->irg, co->cls, allocatable_regs);
1446
1447         mst_env.n_regs           = n_regs;
1448         mst_env.chunks           = new_pqueue();
1449         mst_env.co               = co;
1450         mst_env.allocatable_regs = allocatable_regs;
1451         mst_env.ifg              = co->cenv->ifg;
1452         INIT_LIST_HEAD(&mst_env.chunklist);
1453         mst_env.chunk_visited    = 0;
1454         mst_env.single_cols      = OALLOCN(&mst_env.obst, col_cost_t*, n_regs);
1455
1456         for (i = 0; i < n_regs; ++i) {
1457                 col_cost_t *vec = OALLOCN(&mst_env.obst, col_cost_t, n_regs);
1458
1459                 mst_env.single_cols[i] = vec;
1460                 for (j = 0; j < n_regs; ++j) {
1461                         vec[j].col  = j;
1462                         vec[j].cost = REAL(0.0);
1463                 }
1464                 vec[i].col  = 0;
1465                 vec[0].col  = i;
1466                 vec[0].cost = REAL(1.0);
1467         }
1468
1469         DBG((dbg, LEVEL_1, "==== Coloring %+F, class %s ====\n", co->irg, co->cls->name));
1470
1471         /* build affinity chunks */
1472         stat_ev_tim_push();
1473         build_affinity_chunks(&mst_env);
1474         stat_ev_tim_pop("heur4_initial_chunk");
1475
1476         /* color chunks as long as there are some */
1477         while (! pqueue_empty(mst_env.chunks)) {
1478                 aff_chunk_t *chunk = (aff_chunk_t*)pqueue_pop_front(mst_env.chunks);
1479
1480                 color_aff_chunk(&mst_env, chunk);
1481                 DB((dbg, LEVEL_4, "<<<====== Coloring chunk (%u) done\n", chunk->id));
1482                 delete_aff_chunk(chunk);
1483         }
1484
1485         /* apply coloring */
1486         for (pn = 0; pn < ARR_LEN(mst_env.map.data); ++pn) {
1487                 co_mst_irn_t *mirn = (co_mst_irn_t*)mst_env.map.data[pn];
1488                 const arch_register_t *reg;
1489                 if (mirn == NULL)
1490                         continue;
1491                 irn = get_idx_irn(co->irg, pn);
1492                 if (arch_irn_is_ignore(irn))
1493                         continue;
1494
1495                 /* skip nodes where color hasn't changed */
1496                 if (mirn->init_col == mirn->col)
1497                         continue;
1498
1499                 reg = arch_register_for_index(co->cls, mirn->col);
1500                 arch_set_irn_register(irn, reg);
1501                 DB((dbg, LEVEL_1, "%+F set color from %d to %d\n", irn, mirn->init_col, mirn->col));
1502         }
1503
1504         /* free allocated memory */
1505         del_pqueue(mst_env.chunks);
1506         obstack_free(&mst_env.obst, NULL);
1507         ir_nodemap_destroy(&mst_env.map);
1508
1509         stat_ev_tim_pop("heur4_total");
1510
1511         return 0;
1512 }
1513
1514 static const lc_opt_table_entry_t options[] = {
1515         LC_OPT_ENT_INT      ("limit", "limit recoloring",  &recolor_limit),
1516         LC_OPT_ENT_DBL      ("di",    "dislike influence", &dislike_influence),
1517         LC_OPT_LAST
1518 };
1519
1520 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copyheur4)
1521 void be_init_copyheur4(void)
1522 {
1523         lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
1524         lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
1525         lc_opt_entry_t *chordal_grp = lc_opt_get_grp(ra_grp, "chordal");
1526         lc_opt_entry_t *co_grp = lc_opt_get_grp(chordal_grp, "co");
1527         lc_opt_entry_t *heur4_grp = lc_opt_get_grp(co_grp, "heur4");
1528
1529         static co_algo_info copyheur = {
1530                 co_solve_heuristic_mst, 0
1531         };
1532
1533         lc_opt_add_table(heur4_grp, options);
1534         be_register_copyopt("heur4", &copyheur);
1535
1536         FIRM_DBG_REGISTER(dbg, "firm.be.co.heur4");
1537 }