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