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