Fixed xConst
[libfirm] / ir / be / becopyheur2.c
1
2 /**
3  * More experiments on coalescing.
4  * @author Sebastian Hack
5  * @date   14.04.2006
6  */
7
8 #include <stdlib.h>
9 #include <limits.h>
10
11 #include "list.h"
12 #include "bitset.h"
13 #include "debug.h"
14
15 #include "irphase_t.h"
16 #include "irgraph_t.h"
17 #include "irnode_t.h"
18 #include "irprintf.h"
19
20 #include "beabi.h"
21 #include "benode_t.h"
22 #include "becopyopt.h"
23 #include "becopyopt_t.h"
24 #include "bechordal_t.h"
25
26 typedef unsigned col_t;
27
28 typedef struct _co2_irn_t co2_irn_t;
29
30 typedef struct {
31         phase_t ph;
32         copy_opt_t *co;
33         bitset_t *ignore_regs;
34         co2_irn_t *touched;
35         DEBUG_ONLY(firm_dbg_module_t *dbg;)
36 } co2_t;
37
38 struct _co2_irn_t {
39         ir_node       *irn;
40         co2_irn_t     *touched_next;
41         int            costs;
42         col_t          tmp_col;
43         col_t          orig_col;
44         unsigned       fixed     : 1;
45         unsigned       tmp_fixed : 1;
46         struct list_head changed_list;
47 };
48
49 #define get_co2_irn(co2, irn)   ((co2_irn_t *) phase_get_or_set_irn_data(&co2->ph, irn))
50
51 static void co2_irn_init(phase_t *ph, ir_node *irn, void *data)
52 {
53         co2_t *env    = (co2_t *) ph;
54         co2_irn_t *ci = data;
55
56         memset(ci, 0, sizeof(ci[0]));
57         INIT_LIST_HEAD(&ci->changed_list);
58         ci->irn          = irn;
59         ci->touched_next = env->touched;
60         ci->orig_col     = get_irn_col(env->co, irn);
61         env->touched     = ci;
62 }
63
64
65 static int co2_irn_cmp(const void *a, const void *b)
66 {
67         const co2_irn_t **p = a;
68         const co2_irn_t **q = b;
69         return (*q)->costs - (*p)->costs;
70 }
71
72 typedef struct {
73         col_t col;
74         int costs;
75 } col_cost_pair_t;
76
77 /**
78  * An order on color/costs pairs.
79  * If the costs are equal, we use the color as a kind of normalization.
80  */
81 static int col_cost_pair_lt(const void *a, const void *b)
82 {
83         const col_cost_pair_t *p = a;
84         const col_cost_pair_t *q = b;
85         int cost_diff = p->costs - q->costs;
86
87         return cost_diff;
88         // return cost_diff != 0 ? cost_diff : p->col - q->col;
89 }
90
91 static col_t get_col(co2_t *env, ir_node *irn)
92 {
93         co2_irn_t *ci = get_co2_irn(env, irn);
94         return ci->tmp_fixed ? ci->tmp_col : ci->orig_col;
95 }
96
97 static INLINE color_is_fix(co2_t *env, ir_node *irn)
98 {
99         co2_irn_t *ci = get_co2_irn(env, irn);
100         return ci->fixed || ci->tmp_fixed;
101 }
102
103 static void incur_constraint_costs(co2_t *env, ir_node *irn, col_cost_pair_t *col_costs, int costs)
104 {
105         bitset_t *aux = bitset_alloca(env->co->cls->n_regs);
106         arch_register_req_t req;
107
108         arch_get_register_req(env->co->aenv, &req, irn, BE_OUT_POS(0));
109
110         if(arch_register_req_is(&req, limited)) {
111                 bitset_pos_t elm;
112                 int n_constr;
113
114                 req.limited(req.limited_env, aux);
115                 n_constr = bitset_popcnt(aux);
116                 bitset_foreach(aux, elm)
117                         col_costs[elm].costs += costs / n_constr;
118         }
119 }
120
121 /**
122  * Determine costs which shall indicate how cheap/expensive it is to try
123  * to assign a node some color.
124  * The costs are computed for all colors. INT_MAX means that it is impossible
125  * to give the node that specific color.
126  *
127  * @param env       The co2 this pointer.
128  * @param irn       The node.
129  * @param col_costs An array of colors x costs where the costs are written to.
130  */
131 static void determine_color_costs(co2_t *env, ir_node *irn, col_cost_pair_t *col_costs)
132 {
133         be_ifg_t *ifg      = env->co->cenv->ifg;
134         int n_regs         = env->co->cls->n_regs;
135         bitset_t *forb     = bitset_alloca(n_regs);
136         affinity_node_t *a = get_affinity_info(env->co, irn);
137
138         arch_register_req_t req;
139         bitset_pos_t elm;
140         ir_node *pos;
141         void *it;
142         int i;
143
144         /* Put all forbidden colors into the aux bitset. */
145         arch_get_register_req(env->co->aenv, &req, irn, BE_OUT_POS(0));
146         if(arch_register_req_is(&req, limited)) {
147                 req.limited(req.limited_env, forb);
148                 bitset_flip_all(forb);
149         }
150         else
151                 bitset_copy(forb, env->ignore_regs);
152
153         for(i = 0; i < n_regs; ++i) {
154                 col_costs[i].col   = i;
155                 col_costs[i].costs = 0;
156         }
157
158         if(a) {
159                 neighb_t *n;
160
161                 co_gs_foreach_neighb(a, n) {
162                         co2_irn_t *ni = get_co2_irn(env, n->irn);
163
164                         if(ni->fixed) {
165                                 col_t col = get_col(env, n->irn);
166                                 col_costs[col].costs -= 100 * n->costs;
167                         }
168
169                         incur_constraint_costs(env, n->irn, col_costs, -n->costs);
170                 }
171         }
172
173         it = be_ifg_neighbours_iter_alloca(ifg);
174         be_ifg_foreach_neighbour(ifg, it, irn, pos) {
175                 col_t col = get_col(env, pos);
176                 if(color_is_fix(env, pos))
177                         col_costs[col].costs = INT_MAX;
178                 else {
179                         incur_constraint_costs(env, pos, col_costs, INT_MAX);
180                         col_costs[col].costs++;
181                 }
182         }
183
184         /* Set the costs to infinity for each color which is not allowed at this node. */
185         bitset_foreach(forb, elm)
186                 col_costs[elm].costs = INT_MAX;
187
188 }
189
190 static int curr_costs(co2_t *env, affinity_node_t *a)
191 {
192         col_t a_col = get_col(env, a->irn);
193         int costs   = 0;
194         neighb_t *n;
195
196         co_gs_foreach_neighb(a, n) {
197                 col_t n_col = get_col(env, n->irn);
198                 costs += n_col != a_col ? n->costs : 0;
199         }
200
201         return costs;
202 }
203
204 static void reject_coloring(struct list_head *h)
205 {
206         co2_irn_t *pos;
207
208         list_for_each_entry(co2_irn_t, pos, h, changed_list)
209                 pos->tmp_fixed = 0;
210 }
211
212 static void materialize_coloring(co2_t *env, struct list_head *h)
213 {
214         const arch_register_class_t *cls = env->co->cls;
215         const arch_env_t *aenv           = env->co->aenv;
216         co2_irn_t *pos;
217
218         list_for_each_entry(co2_irn_t, pos, h, changed_list) {
219                 pos->orig_col = pos->tmp_col;
220                 pos->tmp_fixed = 0;
221         }
222 }
223
224 static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth);
225
226
227 static INLINE int recolor(co2_t *env, ir_node *irn, col_cost_pair_t *col_list, int n_regs, struct list_head *parent_changed, int depth)
228 {
229         be_ifg_t *ifg = env->co->cenv->ifg;
230         co2_irn_t *ci = get_co2_irn(env, irn);
231         int res       = 0;
232
233         int i;
234
235         for(i = 0; i < n_regs; ++i) {
236                 col_t tgt_col  = col_list[i].col;
237                 unsigned costs = col_list[i].costs;
238                 int neigh_ok   = 1;
239
240                 struct list_head changed;
241                 ir_node *n;
242                 void *it;
243
244                 DBG((env->dbg, LEVEL_2, "\t%2Dtrying color %d(%d) on %+F\n", depth, tgt_col, costs, irn));
245
246                 /* If the costs for that color (and all successive) are infinite, bail out we won't make it anyway. */
247                 if(costs == INT_MAX) {
248                         ci->tmp_fixed = 0;
249                         return 0;
250                 }
251
252                 /* Set the new color of the node and mark the node as temporarily fixed. */
253                 ci->tmp_col   = tgt_col;
254                 ci->tmp_fixed = 1;
255
256                 /*
257                 If that color has costs > 0, there's at least one neighbor having that color,
258                 so we will try to change the neighbors' colors, too.
259                 */
260                 INIT_LIST_HEAD(&changed);
261                 list_add(&ci->changed_list, &changed);
262
263                 it = be_ifg_neighbours_iter_alloca(ifg);
264                 be_ifg_foreach_neighbour(ifg, it, irn, n) {
265
266                         /* try to re-color the neighbor if it has the target color. */
267                         if(get_col(env, n) == tgt_col) {
268                                 struct list_head tmp;
269
270                                 /*
271                                 Try to change the color of the neighbor and record all nodes which
272                                 get changed in the tmp list. Add this list to the "changed" list for
273                                 that color. If we did not succeed to change the color of the neighbor,
274                                 we bail out and try the next color.
275                                 */
276                                 INIT_LIST_HEAD(&tmp);
277                                 neigh_ok = change_color_not(env, n, tgt_col, &tmp, depth + 1);
278                                 list_splice(&tmp, &changed);
279                                 if(!neigh_ok)
280                                         break;
281                         }
282                 }
283
284
285                 /*
286                 We managed to assign the target color to all neighbors, so from the perspective
287                 of the current node, every thing was ok and we can return safely.
288                 */
289                 if(neigh_ok) {
290                         DBG((env->dbg, LEVEL_2, "\t%2Dcolor %d(%d) was ok\n", depth, tgt_col, costs));
291                         list_splice(&changed, parent_changed);
292                         res = 1;
293                         break;
294                 }
295
296                 /*
297                 If not, that color did not succeed and we unfix all nodes we touched
298                 by traversing the changed list and setting tmp_fixed to 0 for these nodes.
299                 */
300                 else
301                         reject_coloring(&changed);
302         }
303
304         return res;
305 }
306
307 static int change_color_not(co2_t *env, ir_node *irn, col_t not_col, struct list_head *parent_changed, int depth)
308 {
309         co2_irn_t *ci = get_co2_irn(env, irn);
310         int res       = 0;
311         col_t col     = get_col(env, irn);
312
313         DBG((env->dbg, LEVEL_2, "\t%2Dclearing %+F(%d) of color %d\n", depth, irn, col, not_col));
314
315         /* the node does not have to forbidden color. That's fine, mark it as visited and return. */
316         if(col != not_col) {
317                 if(!ci->tmp_fixed) {
318                         ci->tmp_col   = col;
319                         ci->tmp_fixed = 1;
320                 }
321
322                 list_add(&ci->changed_list, parent_changed);
323                 return 1;
324         }
325
326         /* The node has the color it should not have _and_ has not been visited yet. */
327         if(!color_is_fix(env, irn)) {
328                 int n_regs            = env->co->cls->n_regs;
329                 col_cost_pair_t *csts = alloca(n_regs * sizeof(csts[0]));
330
331                 /* Get the costs for giving the node a specific color. */
332                 determine_color_costs(env, irn, csts);
333
334                 /* Since the node must not have the not_col, set the costs for that color to "infinity" */
335                 csts[not_col].costs = INT_MAX;
336
337                 /* sort the colors according costs, cheapest first. */
338                 qsort(csts, n_regs, sizeof(csts[0]), col_cost_pair_lt);
339
340                 /* Try recoloring the node using the color list. */
341                 res = recolor(env, irn, csts, n_regs, parent_changed, depth);
342         }
343
344         /* If we came here, everything went ok. */
345         return res;
346 }
347
348 /**
349  * Try to bring a node to a certain color.
350  */
351 static int try_color(co2_t *env, ir_node *irn, col_t tgt_col, struct list_head *changed)
352 {
353         co2_irn_t *ci = get_co2_irn(env, irn);
354         be_ifg_t *ifg = env->co->cenv->ifg;
355
356         ir_node *n;
357         void *it;
358
359         ci->tmp_fixed = 1;
360         ci->tmp_col   = tgt_col;
361         list_add(&ci->changed_list, changed);
362
363         it = be_ifg_neighbours_iter_alloca(ifg);
364         be_ifg_foreach_neighbour(ifg, it, irn, n) {
365                 col_t c = get_col(env, n);
366
367                 /* If the neighbor has the target color, re-color the neighbor. */
368                 if(c == tgt_col) {
369                         int ok = change_color_not(env, n, tgt_col, changed, 1);
370                         if(!ok)
371                                 return 0;
372                 }
373         }
374
375         return 1;
376 }
377
378 static INLINE int costs_sufficient(co2_irn_t *irn, int costs)
379 {
380         return costs == -irn->costs;
381 }
382
383 static void process_affinity_node(co2_t *env, co2_irn_t *ci)
384 {
385         int n_regs               = env->co->cls->n_regs;
386         col_cost_pair_t *col_seq = alloca(n_regs * sizeof(col_seq[0]));
387         affinity_node_t *a       = get_affinity_info(env->co, ci->irn);
388         int best_cost            = curr_costs(env, a);
389         col_t best_col           = ci->orig_col;
390
391         neighb_t *n;
392         int i;
393
394         assert(a != NULL && "This node must be an affinity node");
395
396         /* If that node has already been fixed, leave it alone. */
397         if(ci->fixed)
398                 return;
399
400         DB((env->dbg, LEVEL_1, "affinity node %+F cost %d\n", ci->irn, ci->costs));
401
402         /* determine the order in which the colors shall be tried. */
403         determine_color_costs(env, ci->irn, col_seq);
404         qsort(col_seq, n_regs, sizeof(col_seq[0]), col_cost_pair_lt);
405
406         /* Try the colors. */
407         for(i = 0; i < n_regs; ++i) {
408                 col_t col = col_seq[i].col;
409                 int costs = col_seq[i].costs;
410
411                 struct list_head changed;
412                 int ok;
413
414                 DB((env->dbg, LEVEL_2, "\tbest color %d incurring costs %d\n", best_col, best_cost));
415
416                 /* Also, if the costs are not more optimizable, we do not try additional colors and finish this node. */
417                 if(best_cost == 0)
418                         break;
419
420                 if(costs == INT_MAX) {
421                         DB((env->dbg, LEVEL_1, "\tall following colors after %d will be infeasible\n", col));
422                         break;
423                 }
424
425                 INIT_LIST_HEAD(&changed);
426
427                 DB((env->dbg, LEVEL_1, "\ttrying color %d costing %d\n", col, costs));
428
429                 /* try to assign the same color to the node and all its neighbors. */
430                 ok = try_color(env, a->irn, col, &changed);
431
432                 if(!ok) {
433                         DBG((env->dbg, LEVEL_2, "\t-> failed.\n"));
434                         reject_coloring(&changed);
435                         continue;
436                 }
437
438                 /*
439                 Evaluate the recoloring and mark it is as new best if it was better
440                 as the best current known solution.
441                 */
442                 costs = curr_costs(env, a);
443                 DBG((env->dbg, LEVEL_2, "\t-> cost: %d\n", costs));
444
445                 if(costs < best_cost) {
446                         best_cost = costs;
447                         best_col  = col;
448
449                         materialize_coloring(env, &changed);
450                 }
451
452                 /* If we had a better coloring already, reject the current one. */
453                 else
454                         reject_coloring(&changed);
455
456         }
457
458         /* We found the definite color for this node, so fix it. */
459         ci->fixed = 1;
460
461         DB((env->dbg, LEVEL_1, "\tusing %d(%d)\n", best_col, best_cost));
462
463         /* Now, investigate all affinity neighbors of this node. */
464         if(0) {
465                 co2_irn_t **neighbors = alloca(a->degree * sizeof(neighbors[0]));
466
467                 i = 0;
468                 co_gs_foreach_neighb(a, n)
469                         neighbors[i++] = get_co2_irn(env, n->irn);
470
471                 qsort(neighbors, a->degree, sizeof(neighbors[0]), co2_irn_cmp);
472                 for(i = 0; i < a->degree; ++i)
473                         process_affinity_node(env, neighbors[i]);
474         }
475 }
476
477 static void process(co2_t *env)
478 {
479         struct obstack obst;
480         affinity_node_t *an;
481         co2_irn_t **nodes;
482         int i, n;
483
484         obstack_init(&obst);
485
486         n = 0;
487         co_gs_foreach_aff_node(env->co, an) {
488                 ir_node *irn   = an->irn;
489                 co2_irn_t *ci  = get_co2_irn(env, irn);
490
491                 neighb_t *neighb;
492
493                 co_gs_foreach_neighb(an, neighb)
494                         ci->costs += neighb->costs;
495
496                 obstack_ptr_grow(&obst, ci);
497                 n++;
498         }
499
500         nodes = obstack_finish(&obst);
501
502         /* sort the nodes according to processing order. */
503         qsort(nodes, n, sizeof(nodes[0]), co2_irn_cmp);
504
505         for(i = 0; i < n; ++i) {
506                 if(!nodes[i]->fixed)
507                         process_affinity_node(env, nodes[i]);
508         }
509
510         obstack_free(&obst, NULL);
511 }
512
513 static void writeback_colors(co2_t *env)
514 {
515         const arch_env_t *aenv = env->co->aenv;
516         co2_irn_t *irn;
517
518         for(irn = env->touched; irn; irn = irn->touched_next) {
519                 const arch_register_t *reg = arch_register_for_index(env->co->cls, irn->orig_col);
520                 arch_set_irn_register(aenv, irn->irn, reg);
521         }
522 }
523
524 void co_solve_heuristic_new(copy_opt_t *co)
525 {
526         co2_t env;
527
528         phase_init(&env.ph, "co2", co->cenv->birg->irg, sizeof(co2_irn_t), PHASE_DEFAULT_GROWTH, co2_irn_init);
529         env.touched     = NULL;
530         env.co          = co;
531         env.ignore_regs = bitset_alloca(co->cls->n_regs);
532         arch_put_non_ignore_regs(co->aenv, co->cls, env.ignore_regs);
533         bitset_flip_all(env.ignore_regs);
534         be_abi_put_ignore_regs(co->cenv->birg->abi, co->cls, env.ignore_regs);
535         FIRM_DBG_REGISTER(env.dbg, "firm.be.co2");
536
537         process(&env);
538         writeback_colors(&env);
539         phase_free(&env.ph);
540 }