Removed unused variable.
[libfirm] / ir / be / becopyheur2.c
1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       More experiments on coalescing.
23  * @author      Sebastian Hack
24  * @date        14.04.2006
25  * @version     $Id$
26  */
27 #include "config.h"
28
29 #include "lc_opts.h"
30 #include "lc_opts_enum.h"
31
32 #include <stdlib.h>
33 #include <limits.h>
34
35 #include "list.h"
36 #include "pdeq.h"
37 #include "bitset.h"
38 #include "raw_bitset.h"
39
40 #include "debug.h"
41 #include "bitfiddle.h"
42
43 #include "irphase_t.h"
44 #include "irgraph_t.h"
45 #include "irnode_t.h"
46 #include "irprintf.h"
47 #include "irtools.h"
48
49 #include "bemodule.h"
50 #include "beabi.h"
51 #include "benode.h"
52 #include "becopyopt.h"
53 #include "becopyopt_t.h"
54 #include "bechordal_t.h"
55 #include "beirg.h"
56
57 #define DUMP_BEFORE 1
58 #define DUMP_AFTER  2
59 #define DUMP_CLOUD  4
60 #define DUMP_ALL    2 * DUMP_CLOUD - 1
61
62 static unsigned dump_flags      = 0;
63 static int      subtree_iter    = 4;
64 static int      max_depth       = 20;
65 static double   constr_factor   = 0.9;
66
67 static const lc_opt_enum_mask_items_t dump_items[] = {
68         { "before",  DUMP_BEFORE },
69         { "after",   DUMP_AFTER  },
70         { "cloud",   DUMP_CLOUD  },
71         { "all",     DUMP_ALL    },
72         { NULL,      0 }
73 };
74
75 static lc_opt_enum_mask_var_t dump_var = {
76         &dump_flags, dump_items
77 };
78
79 static const lc_opt_table_entry_t options[] = {
80         LC_OPT_ENT_ENUM_MASK("dump", "dump ifg cloud",                                         &dump_var),
81         LC_OPT_ENT_INT      ("iter", "iterations for subtree nodes",                           &subtree_iter),
82         LC_OPT_ENT_DBL      ("cf",   "factor of constraint importance (between 0.0 and 1.0)",  &constr_factor),
83         LC_OPT_ENT_INT      ("max",  "maximum recursion depth",                                &max_depth),
84         LC_OPT_LAST
85 };
86
87 /*
88   ____  _             _
89  / ___|| |_ __ _ _ __| |_
90  \___ \| __/ _` | '__| __|
91   ___) | || (_| | |  | |_
92  |____/ \__\__,_|_|   \__|
93
94 */
95
96 #define INFEASIBLE(cost) ((cost) == INT_MAX)
97
98 typedef unsigned col_t;
99
100 typedef struct co2_irn_t       co2_irn_t;
101 typedef struct co2_cloud_t     co2_cloud_t;
102 typedef struct co2_cloud_irn_t co2_cloud_irn_t;
103
104 typedef struct {
105         col_t col;
106         int costs;
107 } col_cost_pair_t;
108
109 typedef struct {
110         ir_phase     ph;
111         copy_opt_t *co;
112         bitset_t   *allocatable_regs;
113         co2_irn_t  *touched;
114         int         visited;
115         int         n_regs;
116         struct list_head cloud_head;
117         DEBUG_ONLY(firm_dbg_module_t *dbg;)
118 } co2_t;
119
120 struct co2_irn_t {
121         const ir_node   *irn;
122         affinity_node_t *aff;
123         co2_irn_t       *touched_next;
124         col_t            tmp_col;
125         col_t            orig_col;
126         int              last_color_change;
127         bitset_t        *adm_cache;
128         unsigned         fixed          : 1;
129         unsigned         tmp_fixed      : 1;
130         unsigned         is_constrained : 1;
131         struct list_head changed_list;
132 };
133
134 struct co2_cloud_irn_t {
135         struct co2_irn_t   inh;
136         co2_cloud_t       *cloud;
137         int                visited;
138         int                index;
139         co2_cloud_irn_t   *mst_parent;
140         int                mst_costs;
141         int                mst_n_childs;
142         co2_cloud_irn_t  **mst_childs;
143         int               *col_costs;
144         int                costs;
145         int               *fronts;
146         int               *color_badness;
147         col_cost_pair_t   *tmp_coloring;
148         struct list_head   cloud_list;
149         struct list_head   mst_list;
150 };
151
152 struct co2_cloud_t {
153         co2_t            *env;
154         struct obstack    obst;
155         int               costs;
156         int               mst_costs;
157         int               inevit;
158         int               best_costs;
159         int               n_memb;
160         int               n_constr;
161         int               max_degree;
162         int               ticks;
163         double            freedom;
164         co2_cloud_irn_t  *master;
165         co2_cloud_irn_t  *mst_root;
166         co2_cloud_irn_t **seq;
167         struct list_head  members_head;
168         struct list_head  list;
169 };
170
171 typedef struct {
172         co2_cloud_irn_t *src, *tgt;
173         int costs;
174 } edge_t;
175
176 #define FRONT_BASE(ci,col)  ((ci)->fronts + col * (ci)->mst_n_childs)
177
178 #define get_co2_irn(co2, irn)         ((co2_irn_t *)       phase_get_or_set_irn_data(&co2->ph, irn))
179 #define get_co2_cloud_irn(co2, irn)   ((co2_cloud_irn_t *) phase_get_or_set_irn_data(&co2->ph, irn))
180
181 static void *co2_irn_init(ir_phase *ph, const ir_node *irn)
182 {
183         co2_t *env         = (co2_t *) ph;
184         affinity_node_t *a = get_affinity_info(env->co, irn);
185         size_t size        = a ? sizeof(co2_cloud_irn_t) : sizeof(co2_irn_t);
186         co2_irn_t *ci      = (co2_irn_t*)phase_alloc(ph, size);
187
188         memset(ci, 0, size);
189         INIT_LIST_HEAD(&ci->changed_list);
190         ci->touched_next = env->touched;
191         ci->orig_col     = get_irn_col(irn);
192         env->touched     = ci;
193         ci->irn          = irn;
194         ci->aff          = a;
195
196         if (a) {
197                 co2_cloud_irn_t *cci = (co2_cloud_irn_t *) ci;
198                 INIT_LIST_HEAD(&cci->cloud_list);
199                 cci->mst_parent   = cci;
200         }
201
202         return ci;
203 }
204
205 #define CLOUD_WEIGHT(c) ((1 - constr_factor) * (c)->costs + constr_factor * (c)->freedom)
206
207 static int cmp_clouds_gt(const void *a, const void *b)
208 {
209         const co2_cloud_t * const *p = (const co2_cloud_t*const*)a;
210         const co2_cloud_t * const *q = (const co2_cloud_t*const*)b;
211         double c = CLOUD_WEIGHT(*p);
212         double d = CLOUD_WEIGHT(*q);
213         return QSORT_CMP(d, c);
214 }
215
216 /**
217  * An order on color/costs pairs.
218  * If the costs are equal, we use the color as a kind of normalization.
219  */
220 static int col_cost_pair_lt(const void *a, const void *b)
221 {
222         const col_cost_pair_t *p = (const col_cost_pair_t*)a;
223         const col_cost_pair_t *q = (const col_cost_pair_t*)b;
224         int c = p->costs;
225         int d = q->costs;
226         return QSORT_CMP(c, d);
227 }
228
229 static int cmp_edges(const void *a, const void *b)
230 {
231         const edge_t *p = (const edge_t*)a;
232         const edge_t *q = (const edge_t*)b;
233         return QSORT_CMP(q->costs, p->costs);
234 }
235
236 static col_t get_col(co2_t *env, const ir_node *irn)
237 {
238         co2_irn_t *ci = get_co2_irn(env, irn);
239         return ci->tmp_fixed ? ci->tmp_col : ci->orig_col;
240 }
241
242 static inline int color_is_fix(co2_t *env, const ir_node *irn)
243 {
244         co2_irn_t *ci = get_co2_irn(env, irn);
245         return ci->fixed || ci->tmp_fixed;
246 }
247
248 static inline bitset_t *get_adm(co2_t *env, co2_irn_t *ci)
249 {
250         if (ci->adm_cache == NULL) {
251                 const arch_register_req_t *req;
252                 ci->adm_cache = bitset_obstack_alloc(phase_obst(&env->ph), env->n_regs);
253                 req = arch_get_register_req_out(ci->irn);
254
255                 if (arch_register_req_is(req, limited)) {
256                         int i, n;
257
258                         n = env->n_regs;
259                         for (i = 0; i < n; ++i) {
260                                 if (rbitset_is_set(req->limited, i))
261                                         bitset_set(ci->adm_cache, i);
262                         }
263                         ci->is_constrained = 1;
264                 } else {
265                         bitset_copy(ci->adm_cache, env->allocatable_regs);
266                 }
267         }
268
269         return ci->adm_cache;
270 }
271
272 static inline bitset_t *admissible_colors(co2_t *env, co2_irn_t *ci, bitset_t *bs)
273 {
274         bitset_copy(bs, get_adm(env, ci));
275         return bs;
276 }
277
278 static inline int is_color_admissible(co2_t *env, co2_irn_t *ci, col_t col)
279 {
280         bitset_t *bs = get_adm(env, ci);
281         return bitset_is_set(bs, col);
282 }
283
284 static inline int is_constrained(co2_t *env, co2_irn_t *ci)
285 {
286         if (!ci->adm_cache)
287                 get_adm(env, ci);
288         return ci->is_constrained;
289 }
290
291 static void incur_constraint_costs(co2_t *env, const ir_node *irn, col_cost_pair_t *col_costs, int costs)
292 {
293         const arch_register_req_t *req = arch_get_register_req_out(irn);
294
295         if (arch_register_req_is(req, limited)) {
296                 unsigned n_regs   = env->co->cls->n_regs;
297                 unsigned n_constr = 0;
298                 unsigned i;
299
300                 n_constr = rbitset_popcount(req->limited, n_regs);
301                 for (i = 0; i < n_regs; ++i) {
302                         if (rbitset_is_set(req->limited, i)) {
303                                 col_costs[i].costs = add_saturated(col_costs[i].costs, costs / n_constr);
304                         }
305                 }
306         }
307 }
308
309 /**
310  * Determine costs which shall indicate how cheap/expensive it is to try
311  * to assign a node some color.
312  * The costs are computed for all colors. INT_MAX means that it is impossible
313  * to give the node that specific color.
314  *
315  * @param env       The co2 this pointer.
316  * @param irn       The node.
317  * @param col_costs An array of colors x costs where the costs are written to.
318  */
319 static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *col_costs)
320 {
321         const ir_node *irn = ci->irn;
322         be_ifg_t *ifg      = env->co->cenv->ifg;
323         int n_regs         = env->co->cls->n_regs;
324         bitset_t *forb     = bitset_alloca(n_regs);
325         affinity_node_t *a = ci->aff;
326
327         size_t elm;
328         const ir_node *pos;
329         neighbours_iter_t it;
330         int i;
331
332         /* Put all forbidden colors into the aux bitset. */
333         admissible_colors(env, ci, forb);
334         bitset_flip_all(forb);
335
336         for (i = 0; i < n_regs; ++i) {
337                 col_costs[i].col   = i;
338                 col_costs[i].costs = 0;
339         }
340
341         if (a) {
342                 neighb_t *n;
343
344                 co_gs_foreach_neighb(a, n) {
345                         if (color_is_fix(env, n->irn)) {
346                                 col_t col = get_col(env, n->irn);
347                                 col_costs[col].costs = add_saturated(col_costs[col].costs, -n->costs * 128);
348                         }
349
350                         incur_constraint_costs(env, n->irn, col_costs, -n->costs);
351                 }
352         }
353
354         be_ifg_foreach_neighbour(ifg, &it, irn, pos) {
355                 col_t col = get_col(env, pos);
356                 if (color_is_fix(env, pos)) {
357                         col_costs[col].costs  = INT_MAX;
358                 }
359                 else {
360                         incur_constraint_costs(env, pos, col_costs, INT_MAX);
361                         col_costs[col].costs = add_saturated(col_costs[col].costs, 8 * be_ifg_degree(ifg, pos));
362                 }
363         }
364         be_ifg_neighbours_break(&it);
365
366         /* Set the costs to infinity for each color which is not allowed at this node. */
367         bitset_foreach(forb, elm) {
368                 col_costs[elm].costs  = INT_MAX;
369         }
370
371 }
372
373 static void single_color_cost(co2_t *env, co2_irn_t *ci, col_t col, col_cost_pair_t *seq)
374 {
375         int n_regs = env->co->cls->n_regs;
376         int i;
377
378         for (i = 0; i < n_regs; ++i) {
379                 seq[i].col   = i;
380                 seq[i].costs = INT_MAX;
381         }
382
383         (void) ci;
384         assert(is_color_admissible(env, ci, col));
385         seq[col].col = 0;
386         seq[0].col   = col;
387         seq[0].costs = 0;
388 }
389
390 static void reject_coloring(struct list_head *h)
391 {
392         co2_irn_t *pos;
393
394         list_for_each_entry(co2_irn_t, pos, h, changed_list)
395                 pos->tmp_fixed = 0;
396 }
397
398 static void materialize_coloring(struct list_head *h)
399 {
400         co2_irn_t *pos;
401
402         list_for_each_entry(co2_irn_t, pos, h, changed_list) {
403                 pos->orig_col  = pos->tmp_col;
404                 pos->tmp_fixed = 0;
405         }
406 }
407
408 static int change_color_not(co2_t *env, const ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth);
409
410 static int recolor(co2_t *env, const ir_node *irn, col_cost_pair_t *col_list, struct list_head *parent_changed, int depth)
411 {
412         int n_regs         = env->co->cls->n_regs;
413         be_ifg_t *ifg      = env->co->cenv->ifg;
414         co2_irn_t *ci      = get_co2_irn(env, irn);
415         int res            = 0;
416
417         int i;
418
419         if (depth >= max_depth)
420           return 0;
421
422         for (i = 0; i < n_regs; ++i) {
423                 col_t tgt_col  = col_list[i].col;
424                 unsigned costs = col_list[i].costs;
425                 int neigh_ok   = 1;
426
427                 struct list_head changed;
428                 const ir_node *n;
429                 neighbours_iter_t it;
430
431                 DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying color %d(%d) on %+F\n", depth, tgt_col, costs, irn));
432
433                 /* If the costs for that color (and all successive) are infinite, bail out we won't make it anyway. */
434                 if (INFEASIBLE(costs)) {
435                         DB((env->dbg, LEVEL_4, "\t\t%2{firm:indent}color %d infeasible\n", depth, tgt_col));
436                         ci->tmp_fixed = 0;
437                         return 0;
438                 }
439
440                 /* Set the new color of the node and mark the node as temporarily fixed. */
441                 ci->tmp_col     = tgt_col;
442                 ci->tmp_fixed   = 1;
443
444                 /*
445                 If that color has costs > 0, there's at least one neighbor having that color,
446                 so we will try to change the neighbors' colors, too.
447                 */
448                 INIT_LIST_HEAD(&changed);
449                 list_add(&ci->changed_list, &changed);
450
451                 be_ifg_foreach_neighbour(ifg, &it, irn, n) {
452
453                         /* try to re-color the neighbor if it has the target color. */
454                         if (get_col(env, n) == tgt_col) {
455                                 struct list_head tmp;
456
457                                 /*
458                                 Try to change the color of the neighbor and record all nodes which
459                                 get changed in the tmp list. Add this list to the "changed" list for
460                                 that color. If we did not succeed to change the color of the neighbor,
461                                 we bail out and try the next color.
462                                 */
463                                 INIT_LIST_HEAD(&tmp);
464                                 neigh_ok = change_color_not(env, n, tgt_col, &tmp, depth + 1);
465                                 list_splice(&tmp, &changed);
466                                 if (!neigh_ok)
467                                         break;
468                         }
469                 }
470                 be_ifg_neighbours_break(&it);
471
472                 /*
473                 We managed to assign the target color to all neighbors, so from the perspective
474                 of the current node, every thing was ok and we can return safely.
475                 */
476                 if (neigh_ok) {
477                         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}color %d(%d) was ok\n", depth, tgt_col, costs));
478                         list_splice(&changed, parent_changed);
479                         res = 1;
480                         break;
481                 }
482
483                 /*
484                 If not, that color did not succeed and we unfix all nodes we touched
485                 by traversing the changed list and setting tmp_fixed to 0 for these nodes.
486                 */
487                 else
488                         reject_coloring(&changed);
489         }
490
491         return res;
492 }
493
494 static int change_color_not(co2_t *env, const ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth)
495 {
496         co2_irn_t *ci = get_co2_irn(env, irn);
497         int res       = 0;
498         col_t col     = get_col(env, irn);
499
500         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}clearing %+F(%d) of color %d\n", depth, irn, col, not_col));
501
502         /* the node does not have to forbidden color. That's fine, mark it as visited and return. */
503         if (col != not_col) {
504                 if (!ci->tmp_fixed) {
505                         ci->tmp_col     = col;
506                         ci->tmp_fixed   = 1;
507                 }
508
509                 list_add(&ci->changed_list, parent_changed);
510                 return 1;
511         }
512
513         /* The node has the color it should not have _and_ has not been visited yet. */
514         if (!color_is_fix(env, irn)) {
515                 int n_regs            = env->co->cls->n_regs;
516                 col_cost_pair_t *csts = ALLOCAN(col_cost_pair_t, n_regs);
517
518                 /* Get the costs for giving the node a specific color. */
519                 determine_color_costs(env, ci, csts);
520
521                 /* Since the node must not have the not_col, set the costs for that color to "infinity" */
522                 csts[not_col].costs = INT_MAX;
523
524                 /* sort the colors according costs, cheapest first. */
525                 qsort(csts, n_regs, sizeof(csts[0]), col_cost_pair_lt);
526
527                 /* Try recoloring the node using the color list. */
528                 res = recolor(env, irn, csts, parent_changed, depth);
529         }
530
531         /* If we came here, everything went ok. */
532         return res;
533 }
534
535 static int change_color_single(co2_t *env, const ir_node *irn, col_t tgt_col, struct list_head *parent_changed, int depth)
536 {
537         co2_irn_t *ci = get_co2_irn(env, irn);
538         col_t col     = get_col(env, irn);
539         int res       = 0;
540
541         DBG((env->dbg, LEVEL_3, "\t\t%2{firm:indent}trying to set %+F(%d) to color %d\n", depth, irn, col, tgt_col));
542
543         /* the node has the wanted color. That's fine, mark it as visited and return. */
544         if (col == tgt_col) {
545                 if (!ci->tmp_fixed) {
546                         ci->tmp_col     = col;
547                         ci->tmp_fixed   = 1;
548                         list_add(&ci->changed_list, parent_changed);
549                 }
550
551                 res = 1;
552                 goto end;
553         }
554
555         if (!color_is_fix(env, irn) && is_color_admissible(env, ci, tgt_col)) {
556                 int n_regs           = env->co->cls->n_regs;
557                 col_cost_pair_t *seq = ALLOCAN(col_cost_pair_t, n_regs);
558
559                 /* Get the costs for giving the node a specific color. */
560                 single_color_cost(env, ci, tgt_col, seq);
561
562                 /* Try recoloring the node using the color list. */
563                 res = recolor(env, irn, seq, parent_changed, depth);
564
565         }
566
567 end:
568         DB((env->dbg, LEVEL_3, "\t\t%2{firm:indent}color %d %s for %+F\n", depth, tgt_col, res ? "was ok" : "failed", irn));
569         return res;
570 }
571
572 /**
573  * Examine the costs of the current coloring concerning a MST subtree.
574  * @param ci  The subtree root.
575  * @param col The color of @p ci.
576  * @return    The best coloring for that subtree under the assumption that @p ci has color @p col.
577  */
578 static int examine_subtree_coloring(co2_cloud_irn_t *ci, col_t col)
579 {
580         int *front = FRONT_BASE(ci, col);
581         int cost   = 0;
582         int i;
583
584         for (i = 0; i < ci->mst_n_childs; ++i) {
585                 co2_cloud_irn_t *chld = ci->mst_childs[i];
586                 col_t chld_col        = front[i];
587
588                 cost += examine_subtree_coloring(chld, chld_col);
589                 cost += col != chld_col ? chld->mst_costs : 0;
590         }
591
592         return cost;
593 }
594
595 /**
596  * Determine color badnesses of a node.
597  * Badness means that it is unlikely that the node in question can
598  * obtain a color. The higher the badness, the more unlikely it is that
599  * the node can be assigned that color.
600  * @param ci      The node.
601  * @param badness An integer array as long as there are registers.
602  * @note          The array <code>badness</code> is not cleared.
603  */
604 static void node_color_badness(co2_cloud_irn_t *ci, int *badness)
605 {
606         co2_t *env     = ci->cloud->env;
607         co2_irn_t *ir  = &ci->inh;
608         int n_regs     = env->n_regs;
609         be_ifg_t *ifg  = env->co->cenv->ifg;
610         bitset_t *bs   = bitset_alloca(n_regs);
611
612         size_t elm;
613         const ir_node *irn;
614         neighbours_iter_t it;
615
616         admissible_colors(env, &ci->inh, bs);
617         bitset_flip_all(bs);
618         bitset_foreach(bs, elm)
619                 badness[elm] = ci->costs;
620
621         /* Use constrained/fixed interfering neighbors to influence the color badness */
622         be_ifg_foreach_neighbour(ifg, &it, ir->irn, irn) {
623                 co2_irn_t *ni = get_co2_irn(env, irn);
624
625                 admissible_colors(env, ni, bs);
626                 if (bitset_popcount(bs) == 1) {
627                         size_t c = bitset_next_set(bs, 0);
628                         badness[c] += ci->costs;
629                 }
630
631                 else if (ni->fixed) {
632                         col_t c = get_col(env, ni->irn);
633                         badness[c] += ci->costs;
634                 }
635         }
636         be_ifg_neighbours_break(&it);
637 }
638
639 /**
640  * Determine the badness of a MST subtree.
641  * The badness is written into the <code>color_badness</code> array of each node and accumulated in the parents.
642  * @see node_color_badness() for a definition of badness.
643  * @param ci    The root of the subtree.
644  * @param depth Depth for debugging purposes.
645  */
646 static void determine_color_badness(co2_cloud_irn_t *ci, int depth)
647 {
648         co2_t *env     = ci->cloud->env;
649         int i, j;
650
651         node_color_badness(ci, ci->color_badness);
652
653         /* Collect the color badness for the whole subtree */
654         for (i = 0; i < ci->mst_n_childs; ++i) {
655                 co2_cloud_irn_t *child = ci->mst_childs[i];
656                 determine_color_badness(child, depth + 1);
657
658                 for (j = 0; j < env->n_regs; ++j)
659                         ci->color_badness[j] += child->color_badness[j];
660         }
661
662         for (j = 0; j < env->n_regs; ++j)
663                 DBG((env->dbg, LEVEL_2, "%2{firm:indent}%+F col %d badness %d\n", depth, ci->inh.irn, j, ci->color_badness[j]));
664 }
665
666 /**
667  * Unfix all nodes in a MST subtree.
668  */
669 static void unfix_subtree(co2_cloud_irn_t *ci)
670 {
671         int i;
672
673         ci->inh.fixed = 0;
674         for (i = 0; i < ci->mst_n_childs; ++i)
675                 unfix_subtree(ci->mst_childs[i]);
676 }
677
678 static int coalesce_top_down(co2_cloud_irn_t *ci, int child_nr, int depth)
679 {
680         co2_t *env           = ci->cloud->env;
681         col_cost_pair_t *seq = ALLOCAN(col_cost_pair_t, env->n_regs);
682         int is_root          = ci->mst_parent == ci;
683         col_t parent_col     = is_root ? (col_t) -1 : get_col(env, ci->mst_parent->inh.irn);
684         int min_badness      = INT_MAX;
685         int best_col_costs   = INT_MAX;
686         int best_col         = -1;
687         int n_regs           = env->n_regs;
688         int n_iter           = is_root ? MIN(n_regs, subtree_iter) : 1;
689
690         struct list_head changed;
691         int ok, i, j;
692
693         for (i = 0; i < n_regs; ++i) {
694                 int badness = ci->color_badness[i];
695
696                 seq[i].col   = i;
697                 seq[i].costs = is_color_admissible(env, &ci->inh, i) ? badness : INT_MAX;
698
699                 min_badness = MIN(min_badness, badness);
700         }
701
702         /* If we are not the root and the parent's color is allowed for this node give it top prio. */
703         if (!is_root && is_color_admissible(env, &ci->inh, parent_col))
704                 seq[parent_col].costs = min_badness - 1;
705
706         /* Sort the colors. The will be processed in that ordering. */
707         qsort(seq, env->n_regs, sizeof(seq[0]), col_cost_pair_lt);
708
709         DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}starting top-down coalesce for %+F\n", depth, ci->inh.irn));
710         INIT_LIST_HEAD(&changed);
711         for (i = 0; i < (best_col < 0 ? n_regs : n_iter); ++i) {
712                 col_t col    = seq[i].col;
713                 int add_cost = !is_root && col != parent_col ? ci->mst_costs : 0;
714
715                 int subtree_costs, sum_costs;
716
717                 DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}%+F trying color %d\n", depth, ci->inh.irn, col));
718
719                 unfix_subtree(ci);
720                 INIT_LIST_HEAD(&changed);
721                 ok = change_color_single(env, ci->inh.irn, col, &changed, depth);
722                 if (ok) {
723                         materialize_coloring(&changed);
724                         ci->inh.fixed = 1;
725                 }
726
727                 else
728                         continue;
729
730                 for (j = 0; j < ci->mst_n_childs; ++j) {
731                         co2_cloud_irn_t *child = ci->mst_childs[j];
732                         ok = coalesce_top_down(child, j, depth + 1) >= 0;
733                         if (ok)
734                                 child->inh.fixed = 1;
735                         else
736                                 break;
737                 }
738
739                 /* If the subtree could not be colored, we have to try another color. */
740                 if (!ok)
741                         continue;
742
743                 subtree_costs      = examine_subtree_coloring(ci, col);
744                 sum_costs          = subtree_costs + add_cost;
745                 DBG((env->dbg, LEVEL_2, "\t%2{firm:indent}-> %+F costing %d + %d is ok.\n", depth, ci->inh.irn, subtree_costs, add_cost));
746
747                 if (sum_costs < best_col_costs) {
748                         best_col           = col;
749                         best_col_costs     = sum_costs;
750                         ci->col_costs[col] = subtree_costs;
751                 }
752
753                 if (sum_costs == 0)
754                         break;
755         }
756
757         if (!is_root) {
758                 int *front = FRONT_BASE(ci->mst_parent, parent_col);
759                 front[child_nr] = best_col;
760         }
761
762         return best_col;
763 }
764
765 static void populate_cloud(co2_t *env, co2_cloud_t *cloud, affinity_node_t *a, int curr_costs)
766 {
767         be_ifg_t *ifg       = env->co->cenv->ifg;
768         co2_cloud_irn_t *ci = get_co2_cloud_irn(env, a->irn);
769         int costs           = 0;
770         neighb_t *n;
771
772         if (ci->cloud)
773                 return;
774
775         /* mark the node as visited and add it to the cloud. */
776         ci->cloud   = cloud;
777         list_add(&ci->cloud_list, &cloud->members_head);
778
779         DB((env->dbg, LEVEL_2, "\t%+F\n", ci->inh.irn));
780
781         /* determine the nodes costs */
782         co_gs_foreach_neighb(a, n) {
783                 costs += n->costs;
784                 DB((env->dbg, LEVEL_3, "\t\tneigh %+F cost %d\n", n->irn, n->costs));
785                 if (be_ifg_connected(ifg, a->irn, n->irn))
786                         cloud->inevit += n->costs;
787         }
788
789         /* add the node's cost to the total costs of the cloud. */
790         ci->costs          = costs;
791         cloud->costs      += costs;
792         cloud->n_constr   += is_constrained(env, &ci->inh);
793         cloud->freedom    += bitset_popcount(get_adm(env, &ci->inh));
794         cloud->max_degree  = MAX(cloud->max_degree, ci->inh.aff->degree);
795         cloud->n_memb++;
796
797         /* If this is the heaviest node in the cloud, set it as the cloud's master. */
798         if (costs >= curr_costs) {
799                 curr_costs    = costs;
800                 cloud->master = ci;
801         }
802
803         /* add all the neighbors of the node to the cloud. */
804         co_gs_foreach_neighb(a, n) {
805                 affinity_node_t *an = get_affinity_info(env->co, n->irn);
806                 assert(an);
807                 populate_cloud(env, cloud, an, curr_costs);
808         }
809 }
810
811 static co2_cloud_t *new_cloud(co2_t *env, affinity_node_t *a)
812 {
813         co2_cloud_t *cloud = (co2_cloud_t*)phase_alloc(&env->ph, sizeof(cloud[0]));
814         co2_cloud_irn_t *ci;
815         int i;
816
817         DBG((env->dbg, LEVEL_2, "new cloud with %+F\n", a->irn));
818         memset(cloud, 0, sizeof(cloud[0]));
819         INIT_LIST_HEAD(&cloud->members_head);
820         INIT_LIST_HEAD(&cloud->list);
821         list_add(&cloud->list, &env->cloud_head);
822         cloud->best_costs = INT_MAX;
823         cloud->env = env;
824         env->visited++;
825         populate_cloud(env, cloud, a, 0);
826         cloud->freedom = (cloud->n_memb * env->n_regs) / cloud->freedom;
827
828         /* Also allocate space for the node sequence and compute that sequence. */
829         cloud->seq = (co2_cloud_irn_t**)phase_alloc(&env->ph, cloud->n_memb * sizeof(cloud->seq[0]));
830
831         i = 0;
832         list_for_each_entry(co2_cloud_irn_t, ci, &cloud->members_head, cloud_list) {
833                 ci->index       = i;
834                 cloud->seq[i++] = ci;
835         }
836         DBG((env->dbg, LEVEL_2, "cloud cost %d, freedom %f\n", cloud->costs, cloud->freedom));
837
838         return cloud;
839 }
840
841 static void apply_coloring(co2_cloud_irn_t *ci, col_t col, int depth)
842 {
843         const ir_node *irn = ci->inh.irn;
844         int *front   = FRONT_BASE(ci, col);
845         int i;
846         struct list_head changed;
847
848         INIT_LIST_HEAD(&changed);
849
850         DBG((ci->cloud->env->dbg, LEVEL_2, "%2{firm:indent}setting %+F to %d\n", depth, irn, col));
851         change_color_single(ci->cloud->env, irn, col, &changed, depth);
852         materialize_coloring(&changed);
853
854         for (i = 0; i < ci->mst_n_childs; ++i) {
855                 apply_coloring(ci->mst_childs[i], front[i], depth + 1);
856         }
857 }
858
859 static co2_cloud_irn_t *find_mst_root(co2_cloud_irn_t *ci)
860 {
861         while (ci != ci->mst_parent)
862                 ci = ci->mst_parent;
863         return ci;
864 }
865
866
867 static void process_cloud(co2_cloud_t *cloud)
868 {
869         co2_t *env  = cloud->env;
870         int n_regs  = env->n_regs;
871         int n_edges = 0;
872         int *mst_edges = XMALLOCNZ(int, cloud->n_memb * cloud->n_memb);
873         pdeq *q;
874
875         edge_t *edges;
876         int i;
877         int best_col;
878
879         /* Collect all edges in the cloud on an obstack and sort the increasingly */
880         obstack_init(&cloud->obst);
881         for (i = 0; i < cloud->n_memb; ++i) {
882                 co2_cloud_irn_t *ci = cloud->seq[i];
883                 neighb_t *n;
884
885                 co_gs_foreach_neighb(ci->inh.aff, n) {
886                         co2_cloud_irn_t *ni = get_co2_cloud_irn(cloud->env, n->irn);
887                         if (ci->index < ni->index) {
888                                 edge_t e;
889                                 e.src   = ci;
890                                 e.tgt   = ni;
891                                 e.costs = n->costs;
892                                 obstack_grow(&cloud->obst, &e, sizeof(e));
893                                 n_edges++;
894                         }
895                 }
896         }
897         edges = (edge_t*)obstack_finish(&cloud->obst);
898         qsort(edges, n_edges, sizeof(edges[0]), cmp_edges);
899
900         /* Compute the maximum spanning tree using Kruskal/Union-Find */
901         DBG((env->dbg, LEVEL_2, "computing spanning tree of cloud with master %+F\n", cloud->master->inh.irn));
902         for (i = 0; i < n_edges; ++i) {
903                 edge_t *e        = &edges[i];
904                 co2_cloud_irn_t *rs = find_mst_root(e->src);
905                 co2_cloud_irn_t *rt = find_mst_root(e->tgt);
906
907                 /* if the union/find roots are different */
908                 if (rs != rt) {
909                         int si = e->src->index;
910                         int ti = e->tgt->index;
911
912                         /* unify the sets */
913                         rs->mst_parent = rt;
914                         DBG((env->dbg, LEVEL_2, "\tadding edge %+F -- %+F cost %d\n", rs->inh.irn, rt->inh.irn, e->costs));
915
916                         /* this edge is in the MST, so set it in the bitset. */
917                         mst_edges[si * cloud->n_memb + ti] = e->costs;
918                         mst_edges[ti * cloud->n_memb + si] = e->costs;
919                 }
920         }
921         obstack_free(&cloud->obst, edges);
922
923         cloud->master->mst_parent = cloud->master;
924         cloud->mst_root = cloud->master;
925         q = new_pdeq1(cloud->master);
926         while (!pdeq_empty(q)) {
927                 co2_cloud_irn_t *ci = (co2_cloud_irn_t*)pdeq_getl(q);
928                 int ofs    = ci->index * cloud->n_memb;
929                 int end    = ofs + cloud->n_memb;
930                 int i;
931
932                 ci->mst_n_childs = 0;
933                 for (i = ofs; i < end; ++i) {
934                         if (mst_edges[i] != 0) {
935                                 int other = i - ofs;
936                                 co2_cloud_irn_t *child = cloud->seq[i - ofs];
937
938                                 /* put the child to the worklist */
939                                 pdeq_putr(q, child);
940
941                                 /* make ci the parent of the child and add the child to the children array of the parent */
942                                 child->mst_parent = ci;
943                                 child->mst_costs  = mst_edges[i];
944                                 ci->mst_n_childs++;
945                                 obstack_ptr_grow(&cloud->obst, child);
946
947                                 mst_edges[other * cloud->n_memb + ci->index] = 0;
948                                 mst_edges[i] = 0;
949                         }
950                 }
951
952                 obstack_ptr_grow(&cloud->obst, NULL);
953                 ci->mst_childs = (co2_cloud_irn_t**)obstack_finish(&cloud->obst);
954         }
955         del_pdeq(q);
956         free(mst_edges);
957
958
959         DBG((env->dbg, LEVEL_3, "mst:\n"));
960         for (i = 0; i < cloud->n_memb; ++i) {
961                 DEBUG_ONLY(co2_cloud_irn_t *ci = cloud->seq[i]);
962                 DBG((env->dbg, LEVEL_3, "\t%+F -> %+F\n", ci->inh.irn, ci->mst_parent->inh.irn));
963         }
964
965         for (i = 0; i < cloud->n_memb; ++i) {
966                 co2_cloud_irn_t *ci = cloud->seq[i];
967                 int n_childs = ci->mst_n_childs;
968                 int j;
969
970                 ci->col_costs       = OALLOCNZ(&cloud->obst, int,             n_regs);
971                 ci->tmp_coloring    = OALLOCNZ(&cloud->obst, col_cost_pair_t, n_regs);
972                 ci->fronts          = OALLOCNZ(&cloud->obst, int,             n_regs * n_childs);
973                 ci->color_badness   = OALLOCNZ(&cloud->obst, int,             n_regs);
974
975                 for (j = 0; j < env->n_regs; j++)
976                         ci->col_costs[j] = INT_MAX;
977         }
978
979         determine_color_badness(cloud->mst_root, 0);
980         best_col = coalesce_top_down(cloud->mst_root, -1, 0);
981         unfix_subtree(cloud->mst_root);
982         apply_coloring(cloud->mst_root, best_col, 0);
983
984         /* The coloring should represent the one with the best costs. */
985         //materialize_coloring(&changed);
986         DBG((env->dbg, LEVEL_2, "\tbest coloring for root %+F was %d costing %d\n",
987                 cloud->mst_root->inh.irn, best_col, examine_subtree_coloring(cloud->mst_root, best_col)));
988
989         /* Fix all nodes in the cloud. */
990         for (i = 0; i < cloud->n_memb; ++i)
991                 cloud->seq[i]->inh.fixed = 1;
992
993         /* Free all space used while optimizing this cloud. */
994         obstack_free(&cloud->obst, NULL);
995 }
996
997 static int cloud_costs(co2_cloud_t *cloud)
998 {
999         int i, costs = 0;
1000         neighb_t *n;
1001
1002         for (i = 0; i < cloud->n_memb; ++i) {
1003                 co2_irn_t *ci = (co2_irn_t *) cloud->seq[i];
1004                 col_t col = get_col(cloud->env, ci->irn);
1005                 co_gs_foreach_neighb(ci->aff, n) {
1006                         col_t n_col = get_col(cloud->env, n->irn);
1007                         costs += col != n_col ? n->costs : 0;
1008                 }
1009         }
1010
1011         return costs / 2;
1012 }
1013
1014 static void writeback_colors(co2_t *env)
1015 {
1016         co2_irn_t *irn;
1017
1018         for (irn = env->touched; irn; irn = irn->touched_next) {
1019                 const arch_register_t *reg = arch_register_for_index(env->co->cls, irn->orig_col);
1020                 arch_set_irn_register((ir_node*)irn->irn, reg);
1021         }
1022 }
1023
1024
1025 /*
1026   ___ _____ ____   ____   ___ _____   ____                        _
1027  |_ _|  ___/ ___| |  _ \ / _ \_   _| |  _ \ _   _ _ __ ___  _ __ (_)_ __   __ _
1028   | || |_ | |  _  | | | | | | || |   | | | | | | | '_ ` _ \| '_ \| | '_ \ / _` |
1029   | ||  _|| |_| | | |_| | |_| || |   | |_| | |_| | | | | | | |_) | | | | | (_| |
1030  |___|_|   \____| |____/ \___/ |_|   |____/ \__,_|_| |_| |_| .__/|_|_| |_|\__, |
1031                                                            |_|            |___/
1032 */
1033
1034 static const char *get_dot_color_name(size_t col)
1035 {
1036         static const char *const names[] = {
1037                 "blue",
1038                 "red",
1039                 "green",
1040                 "yellow",
1041                 "cyan",
1042                 "magenta",
1043                 "orange",
1044                 "chocolate",
1045                 "beige",
1046                 "navy",
1047                 "darkgreen",
1048                 "darkred",
1049                 "lightPink",
1050                 "chartreuse",
1051                 "lightskyblue",
1052                 "linen",
1053                 "pink",
1054                 "lightslateblue",
1055                 "mintcream",
1056                 "red",
1057                 "darkolivegreen",
1058                 "mediumblue",
1059                 "mistyrose",
1060                 "salmon",
1061                 "darkseagreen",
1062                 "mediumslateblue"
1063                 "moccasin",
1064                 "tomato",
1065                 "forestgreen",
1066                 "darkturquoise",
1067                 "palevioletred"
1068         };
1069
1070         return col < (sizeof(names)/sizeof(names[0])) ? names[col] : "white";
1071 }
1072
1073 static const char *get_dot_shape_name(co2_irn_t *ci)
1074 {
1075         const arch_register_req_t *req = arch_get_register_req_out(ci->irn);
1076
1077         if (arch_register_req_is(req, limited))
1078                 return "diamond";
1079
1080         if (ci->fixed)
1081                 return "rectangle";
1082
1083         if (ci->tmp_fixed)
1084                 return "hexagon";
1085
1086         return "ellipse";
1087 }
1088
1089 static void ifg_dump_graph_attr(FILE *f, void *self)
1090 {
1091         (void) self;
1092         fprintf(f, "overlay=false");
1093 }
1094
1095 static int ifg_is_dump_node(void *self, ir_node *irn)
1096 {
1097         const arch_register_req_t *req = arch_get_register_req_out(irn);
1098         (void)self;
1099         return !(req->type & arch_register_req_type_ignore);
1100 }
1101
1102 static void ifg_dump_node_attr(FILE *f, void *self, ir_node *irn)
1103 {
1104         co2_t *env    = (co2_t*)self;
1105         co2_irn_t *ci = get_co2_irn(env, irn);
1106         int peri      = 1;
1107
1108         char buf[128] = "";
1109
1110         if (ci->aff) {
1111                 co2_cloud_irn_t *cci = (co2_cloud_irn_t*) ci;
1112                 if (cci->cloud && cci->cloud->mst_root == cci)
1113                         peri = 2;
1114
1115                 if (cci->cloud && cci->cloud->mst_root)
1116                         ir_snprintf(buf, sizeof(buf), "%+F", cci->cloud->mst_root->inh.irn);
1117         }
1118
1119         ir_fprintf(f, "label=\"%+F%s\" style=filled peripheries=%d color=%s shape=%s", irn, buf, peri,
1120                 get_dot_color_name(get_col(env, irn)), get_dot_shape_name(ci));
1121 }
1122
1123 static void ifg_dump_at_end(FILE *file, void *self)
1124 {
1125         co2_t *env = (co2_t*)self;
1126         affinity_node_t *a;
1127
1128         co_gs_foreach_aff_node(env->co, a) {
1129                 co2_cloud_irn_t *ai = get_co2_cloud_irn(env, a->irn);
1130                 int idx = get_irn_idx(a->irn);
1131                 neighb_t *n;
1132
1133                 if (ai->mst_parent != ai)
1134                         fprintf(file, "\tn%d -- n%u [style=dotted color=blue arrowhead=normal];\n", idx, get_irn_idx(ai->mst_parent->inh.irn));
1135
1136                 co_gs_foreach_neighb(a, n) {
1137                         int nidx = get_irn_idx(n->irn);
1138                         co2_cloud_irn_t *ci = get_co2_cloud_irn(env, n->irn);
1139
1140                         if (idx < nidx) {
1141                                 const char *color = get_col(env, a->irn) == get_col(env, n->irn) ? "black" : "red";
1142                                 const char *arr = "arrowhead=dot arrowtail=dot";
1143
1144                                 if (ci->mst_parent == ai)
1145                                         arr = "arrowtail=normal";
1146                                 else if (ai->mst_parent == ci)
1147                                         arr = "arrowhead=normal";
1148
1149                                 fprintf(file, "\tn%d -- n%d [label=\"%d\" %s style=dashed color=%s weight=0.01];\n", idx, nidx, n->costs, arr, color);
1150                         }
1151                 }
1152         }
1153 }
1154
1155 static be_ifg_dump_dot_cb_t ifg_dot_cb = {
1156         ifg_is_dump_node,
1157         ifg_dump_graph_attr,
1158         ifg_dump_node_attr,
1159         NULL,
1160         NULL,
1161         ifg_dump_at_end
1162 };
1163
1164 static void process(co2_t *env)
1165 {
1166         affinity_node_t *a;
1167         co2_cloud_t *pos;
1168         co2_cloud_t **clouds;
1169         int n_clouds;
1170         int i;
1171         int init_costs  = 0;
1172         int all_costs   = 0;
1173         int final_costs = 0;
1174
1175         n_clouds = 0;
1176         co_gs_foreach_aff_node(env->co, a) {
1177                 co2_cloud_irn_t *ci = get_co2_cloud_irn(env, a->irn);
1178
1179                 if (!ci->cloud) {
1180                         new_cloud(env, a);
1181                         n_clouds++;
1182                 }
1183         }
1184
1185         i = 0;
1186         clouds = XMALLOCN(co2_cloud_t*, n_clouds);
1187         list_for_each_entry(co2_cloud_t, pos, &env->cloud_head, list)
1188                 clouds[i++] = pos;
1189         qsort(clouds, n_clouds, sizeof(clouds[0]), cmp_clouds_gt);
1190
1191         for (i = 0; i < n_clouds; ++i) {
1192                 init_costs  += cloud_costs(clouds[i]);
1193
1194                 /* Process the cloud. */
1195                 process_cloud(clouds[i]);
1196
1197                 all_costs   += clouds[i]->costs;
1198                 final_costs += cloud_costs(clouds[i]);
1199
1200                 /* Dump the IFG if the user demanded it. */
1201                 if (dump_flags & DUMP_CLOUD) {
1202                         char buf[256];
1203                         FILE *f;
1204
1205                         ir_snprintf(buf, sizeof(buf), "ifg_%F_%s_cloud_%d.dot", env->co->irg, env->co->cls->name, i);
1206                         f = fopen(buf, "wt");
1207                         if (f != NULL) {
1208                                 be_ifg_dump_dot(env->co->cenv->ifg, env->co->irg, f, &ifg_dot_cb, env);
1209                                 fclose(f);
1210                         }
1211                 }
1212         }
1213
1214         DB((env->dbg, LEVEL_1, "all costs: %d, init costs: %d, final costs: %d\n", all_costs, init_costs, final_costs));
1215
1216         xfree(clouds);
1217 }
1218
1219 int co_solve_heuristic_new(copy_opt_t *co)
1220 {
1221         char  buf[256];
1222         co2_t env;
1223         FILE  *f;
1224
1225         phase_init(&env.ph, co->cenv->irg, co2_irn_init);
1226         env.touched     = NULL;
1227         env.visited     = 0;
1228         env.co          = co;
1229         env.n_regs      = co->cls->n_regs;
1230         env.allocatable_regs = bitset_alloca(co->cls->n_regs);
1231         be_put_allocatable_regs(co->cenv->irg, co->cls, env.allocatable_regs);
1232         FIRM_DBG_REGISTER(env.dbg, "firm.be.co2");
1233         INIT_LIST_HEAD(&env.cloud_head);
1234
1235         if (dump_flags & DUMP_BEFORE) {
1236                 ir_snprintf(buf, sizeof(buf), "ifg_%F_%s_before.dot", co->irg, co->cls->name);
1237                 f = fopen(buf, "wt");
1238                 if (f != NULL) {
1239                         be_ifg_dump_dot(co->cenv->ifg, co->irg, f, &ifg_dot_cb, &env);
1240                         fclose(f);
1241                 }
1242         }
1243
1244         process(&env);
1245
1246         if (dump_flags & DUMP_AFTER) {
1247                 ir_snprintf(buf, sizeof(buf), "ifg_%F_%s_after.dot", co->irg, co->cls->name);
1248                 f = fopen(buf, "wt");
1249                 if (f != NULL) {
1250                         be_ifg_dump_dot(co->cenv->ifg, co->irg, f, &ifg_dot_cb, &env);
1251                         fclose(f);
1252                 }
1253         }
1254
1255         writeback_colors(&env);
1256         phase_deinit(&env.ph);
1257         return 0;
1258 }
1259
1260 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_copyheur2)
1261 void be_init_copyheur2(void)
1262 {
1263         lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
1264         lc_opt_entry_t *ra_grp = lc_opt_get_grp(be_grp, "ra");
1265         lc_opt_entry_t *chordal_grp = lc_opt_get_grp(ra_grp, "chordal");
1266         lc_opt_entry_t *co2_grp = lc_opt_get_grp(chordal_grp, "co2");
1267
1268         static co_algo_info copyheur = {
1269                 co_solve_heuristic_new, 0
1270         };
1271
1272         lc_opt_add_table(co2_grp, options);
1273         be_register_copyopt("heur2", &copyheur);
1274 }