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