adcf8d9d3dad42f5d9bd681a01660dd48e759ee1
[libfirm] / ir / be / bechordal.c
1 /**
2  * Chordal register allocation.
3  * @author Sebastian Hack
4  * @date 8.12.2004
5  *
6  * Copyright (C) Universitaet Karlsruhe
7  * Released under the GPL
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #ifdef HAVE_MALLOC_H
15 #include <malloc.h>
16 #endif
17
18 #ifdef HAVE_ALLOCA_H
19 #include <alloca.h>
20 #endif
21
22 #include <ctype.h>
23
24 #include "obst.h"
25 #include "pset.h"
26 #include "list.h"
27 #include "bitset.h"
28 #include "iterator.h"
29
30 #include "irmode_t.h"
31 #include "irgraph_t.h"
32 #include "irprintf_t.h"
33 #include "irgwalk.h"
34 #include "irdump.h"
35 #include "irdom.h"
36 #include "debug.h"
37 #include "xmalloc.h"
38
39 #include "beutil.h"
40 #include "besched.h"
41 #include "benumb_t.h"
42 #include "besched_t.h"
43 #include "belive_t.h"
44 #include "benode_t.h"
45 #include "bearch.h"
46 #include "beifg.h"
47
48 #include "bechordal_t.h"
49 #include "bechordal_draw.h"
50
51 #define DBG_LEVEL SET_LEVEL_0
52 #define DBG_LEVEL_CHECK SET_LEVEL_0
53
54 #define NO_COLOR (-1)
55
56 #undef DUMP_INTERVALS
57
58 typedef struct _be_chordal_alloc_env_t {
59         be_chordal_env_t *chordal_env;
60
61         pset *pre_colored;    /**< Set of precolored nodes. */
62         bitset_t *live;                         /**< A liveness bitset. */
63         bitset_t *colors;                       /**< The color mask. */
64         bitset_t *in_colors;        /**< Colors used by live in values. */
65         int colors_n;               /**< The number of colors. */
66 } be_chordal_alloc_env_t;
67
68 #include "fourcc.h"
69
70 /* Make a fourcc for border checking. */
71 #define BORDER_FOURCC                           FOURCC('B', 'O', 'R', 'D')
72
73 static void check_border_list(struct list_head *head)
74 {
75   border_t *x;
76   list_for_each_entry(border_t, x, head, list) {
77     assert(x->magic == BORDER_FOURCC);
78   }
79 }
80
81 static void check_heads(be_chordal_env_t *env)
82 {
83   pmap_entry *ent;
84   for(ent = pmap_first(env->border_heads); ent; ent = pmap_next(env->border_heads)) {
85     /* ir_printf("checking border list of block %+F\n", ent->key); */
86     check_border_list(ent->value);
87   }
88 }
89
90
91 /**
92  * Add an interval border to the list of a block's list
93  * of interval border.
94  * @note You always have to create the use before the def.
95  * @param env The environment.
96  * @param head The list head to enqueue the borders.
97  * @param irn The node (value) the border belongs to.
98  * @param pressure The pressure at this point in time.
99  * @param step A time step for the border.
100  * @param is_def Is the border a use or a def.
101  * @return The created border.
102  */
103 static INLINE border_t *border_add(be_chordal_env_t *env, struct list_head *head,
104                         ir_node *irn, unsigned step, unsigned pressure,
105                         unsigned is_def, unsigned is_real)
106 {
107         border_t *b;
108
109         if(!is_def) {
110                 border_t *def;
111
112                 b = obstack_alloc(&env->obst, sizeof(*b));
113
114                 /* also allocate the def and tie it to the use. */
115                 def = obstack_alloc(&env->obst, sizeof(*def));
116                 memset(def, 0, sizeof(*def));
117                 b->other_end = def;
118                 def->other_end = b;
119
120                 /*
121                  * Set the link field of the irn to the def.
122                  * This strongly relies on the fact, that the use is always
123                  * made before the def.
124                  */
125                 set_irn_link(irn, def);
126
127                 b->magic = BORDER_FOURCC;
128                 def->magic = BORDER_FOURCC;
129         }
130
131         /*
132          * If the def is encountered, the use was made and so was the
133          * the def node (see the code above). It was placed into the
134          * link field of the irn, so we can get it there.
135          */
136         else {
137                 b = get_irn_link(irn);
138
139                 assert(b && b->magic == BORDER_FOURCC && "Illegal border encountered");
140         }
141
142         b->pressure = pressure;
143         b->is_def = is_def;
144         b->is_real = is_real;
145         b->irn = irn;
146         b->step = step;
147         list_add_tail(&b->list, head);
148         DBG((env->dbg, LEVEL_5, "\t\t%s adding %+F, step: %d\n", is_def ? "def" : "use", irn, step));
149
150
151         return b;
152 }
153
154 /**
155  * Check, if an irn is of the register class currently under processing.
156  * @param env The chordal environment.
157  * @param irn The node.
158  * @return 1, if the node is of that register class, 0 if not.
159  */
160 static INLINE int has_reg_class(const be_chordal_env_t *env, const ir_node *irn)
161 {
162   return arch_irn_has_reg_class(env->main_env->arch_env, irn, -1, env->cls);
163 }
164
165 #define has_limited_constr(req, irn) \
166         (arch_get_register_req(arch_env, (req), irn, -1) && (req)->type == arch_register_req_type_limited)
167
168 static int try_pre_color(be_chordal_env_t *env, ir_node *irn,
169                                                  pset *pre_colored, bitset_t *colors_used)
170 {
171         arch_register_req_t req;
172
173         if(arch_get_register_req(env->main_env->arch_env, &req, irn, -1)
174                 && req.type == arch_register_req_type_limited) {
175
176                 bitset_t *bs          = bitset_alloca(env->cls->n_regs);
177                 const arch_register_t *reg;
178                 int col;
179
180                 req.data.limited(irn, -1, bs);
181                 col = bitset_next_set(bs, 0);
182                 reg = arch_register_for_index(env->cls, col);
183
184                 pset_insert_ptr(pre_colored, irn);
185                 arch_set_irn_register(env->main_env->arch_env, irn, reg);
186
187                 bitset_set(colors_used, col);
188
189                 DBG((env->dbg, LEVEL_2, "pre coloring %+F with %s\n", irn, reg->name));
190
191                 return 1;
192         }
193
194         return 0;
195 }
196
197 /**
198  * Handle register targeting constraints signaled by a Perm.
199  * @param alloc_env    Private data for the allocation phase.
200  * @param perm         The Perm node guarding the constrained node.
201  * @return             The constrained node.
202
203                 Pro-coloring works as follows:
204
205          +-----------------------------------+
206          |            Perm                   |
207          +---.-------.--------.---------.----+
208              |       |        |         |
209          +---+--+    |        |         |
210          | Proj |    |        |         |
211          +------+    |        |         |
212                      |        |         |
213                   +--+---+    |         |
214                   | Proj |    |         |
215                   +--.---+    |         |
216                      |        |         |
217                      |     +--+---+     |
218                      |     | Proj |     |
219                      |     +------+     |
220                       |                 |
221                       |             +---+--+
222                        `-.          | Proj | Result:
223                           `._       +---.--+ R1
224                              `.         |
225                                `-.      |
226                                   `._   |
227                                     +`.-+--+
228                                     |Constr| Result:
229                                     +------+ R2
230
231                 1) Look at all Projs of the Perm if they have output constraints.
232                    If one has an output constraint, pre-color it, else record it
233                    in the set leftover. Its color has to be chosen after all
234                    constrained nodes are colored. Furthermore record all colors
235                    used in the pre-coloring in the set colors_used.
236
237                 2) Look whether the first node not a Proj (this is the constrained
238                    node due to which the Perm has been inserted) has an output
239                    constraint. If yes, pre-color the node accordingly else do nothing
240                    since the node's input constraints are modelled by the Proj's
241                    output constraint.
242
243                    There's one subtle point here: If thenode has an output constraint
244                    and the live range of some Proj ends at that node, we must give
245                    that Proj the color of the constrained node. Otherwise the
246                    available colors may not suffice for the rest of the projs.
247
248                 3) At last, color the Projs which have not been colored yet with the
249                    left over colors.
250
251                    So afterwards, everything including the constrained node will
252                    be colored and the assign() phase can complete this coloring.
253                    Note that therefore, we put the pre-colored nodes in a set
254                    called pre_colored().
255
256  */
257 static ir_node *handle_constraints_at_perm(be_chordal_alloc_env_t *alloc_env, ir_node *perm)
258 {
259         be_chordal_env_t *env      = alloc_env->chordal_env;
260         firm_dbg_module_t *dbg     = env->dbg;
261         const arch_env_t *arch_env = env->main_env->arch_env;
262
263         pset *leftover        = pset_new_ptr(8);
264         pset *pre_colored     = pset_new_ptr(8);
265         bitset_t *colors_used = bitset_alloca(env->cls->n_regs);
266         ir_node *irn, *cnstr, *last;
267         int has_cnstr = 0;
268
269         assert(be_is_Perm(perm));
270
271         DBG((dbg, LEVEL_2, "Constraints on %+F\n", perm));
272
273         /*
274          * Color constrained Projs first.
275          */
276         for(irn = sched_next(perm); is_Proj(irn); irn = sched_next(irn))
277                 if(!try_pre_color(env, irn, pre_colored, colors_used))
278                         pset_insert_ptr(leftover, irn);
279
280         cnstr = irn;
281         last  = irn;
282
283         if(get_irn_mode(cnstr) == mode_T) {
284                 for(irn = sched_next(cnstr); is_Proj(irn); irn = sched_next(irn))
285                         if(!try_pre_color(env, irn, pre_colored, colors_used))
286                                 pset_insert_ptr(leftover, irn);
287
288                 last = sched_prev(irn);
289         }
290
291         else
292                 try_pre_color(env, cnstr, pre_colored, colors_used);
293
294         for(irn = pset_first(leftover); irn; irn = pset_next(leftover)) {
295                 const arch_register_t *reg;
296                 ir_node *precol;
297                 int colored = 0;
298
299                 for(precol = pset_first(pre_colored); precol; precol = pset_next(pre_colored)) {
300                         if(!values_interfere(irn, precol)) {
301                                 reg = arch_get_irn_register(arch_env, irn);
302                                 arch_set_irn_register(arch_env, irn, reg);
303                                 pset_break(pre_colored);
304                                 colored = 1;
305                                 break;
306                         }
307                 }
308
309                 if(!colored) {
310                         int col = bitset_next_clear(colors_used, 0);
311
312                         assert(col >=0 && "There must be a register left");
313                         reg = arch_register_for_index(env->cls, col);
314                         arch_set_irn_register(arch_env, irn, reg);
315                         bitset_set(colors_used, reg->index);
316                         pset_insert_ptr(alloc_env->pre_colored, irn);
317
318                         DBG((dbg, LEVEL_2, "coloring leftover %+F with %s\n", irn, reg->name));
319                 }
320         }
321
322         pset_insert_pset_ptr(alloc_env->pre_colored, pre_colored);
323
324         del_pset(leftover);
325         del_pset(pre_colored);
326
327         return last;
328 }
329
330 /**
331  * Handle constraint nodes in each basic block.
332  * be_insert_constr_perms() inserts Perm nodes which perm
333  * over all values live at the constrained node right in front
334  * of the constrained node. These Perms signal a constrained node.
335  * For further comments, refer to handle_constraints_at_perm().
336  */
337 static void constraints(ir_node *bl, void *data)
338 {
339         be_chordal_alloc_env_t *env = data;
340         arch_env_t *arch_env        = env->chordal_env->main_env->arch_env;
341         ir_node *irn;
342
343         for(irn = sched_first(bl); !sched_is_end(irn); irn = sched_next(irn)) {
344                 if(be_is_Perm(irn) && arch_irn_has_reg_class(arch_env, irn, 0, env->chordal_env->cls))
345                         irn = handle_constraints_at_perm(env, irn);
346         }
347 }
348
349 /**
350  * Annotate the register pressure to the nodes and compute
351  * the liveness intervals.
352  * @param block The block to do it for.
353  * @param env_ptr The environment.
354  */
355 static void pressure(ir_node *block, void *env_ptr)
356 {
357 /* Convenience macro for a def */
358 #define border_def(irn, step, real) \
359         border_add(env, head, irn, step, pressure--, 1, real)
360
361 /* Convenience macro for a use */
362 #define border_use(irn, step, real) \
363         border_add(env, head, irn, step, ++pressure, 0, real)
364
365         be_chordal_alloc_env_t *alloc_env = env_ptr;
366         be_chordal_env_t *env             = alloc_env->chordal_env;
367         bitset_t *live                    = alloc_env->live;
368         firm_dbg_module_t *dbg            = env->dbg;
369         ir_node *irn;
370
371         int i, n;
372         unsigned step = 0;
373         unsigned pressure = 0;
374         struct list_head *head;
375         pset *live_in = put_live_in(block, pset_new_ptr_default());
376         pset *live_end = put_live_end(block, pset_new_ptr_default());
377
378         DBG((dbg, LEVEL_1, "Computing pressure in block %+F\n", block));
379         bitset_clear_all(live);
380
381         /* Set up the border list in the block info */
382         head = obstack_alloc(&env->obst, sizeof(*head));
383         INIT_LIST_HEAD(head);
384         assert(pmap_get(env->border_heads, block) == NULL);
385         pmap_insert(env->border_heads, block, head);
386
387         /*
388          * Make final uses of all values live out of the block.
389          * They are necessary to build up real intervals.
390          */
391         for(irn = pset_first(live_end); irn; irn = pset_next(live_end)) {
392                 if(has_reg_class(env, irn)) {
393                         DBG((dbg, LEVEL_3, "\tMaking live: %+F/%d\n", irn, get_irn_graph_nr(irn)));
394                         bitset_set(live, get_irn_graph_nr(irn));
395                         border_use(irn, step, 0);
396                 }
397         }
398         ++step;
399
400         /*
401          * Determine the last uses of a value inside the block, since they are
402          * relevant for the interval borders.
403          */
404         sched_foreach_reverse(block, irn) {
405                 DBG((dbg, LEVEL_1, "\tinsn: %+F, pressure: %d\n", irn, pressure));
406                 DBG((dbg, LEVEL_2, "\tlive: %b\n", live));
407
408                 /*
409                  * If the node defines some value, which can put into a
410                  * register of the current class, make a border for it.
411                  */
412                 if(has_reg_class(env, irn)) {
413                         int nr = get_irn_graph_nr(irn);
414
415                         bitset_clear(live, nr);
416                         border_def(irn, step, 1);
417                 }
418
419                 /*
420                  * If the node is no phi node we can examine the uses.
421                  */
422                 if(!is_Phi(irn)) {
423                         for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
424                                 ir_node *op = get_irn_n(irn, i);
425
426                                 if(has_reg_class(env, op)) {
427                                         int nr = get_irn_graph_nr(op);
428
429                                         DBG((dbg, LEVEL_4, "\t\tpos: %d, use: %+F\n", i, op));
430
431                                         if(!bitset_is_set(live, nr)) {
432                                                 border_use(op, step, 1);
433                                                 bitset_set(live, nr);
434                                         }
435                                 }
436                         }
437                 }
438                 ++step;
439         }
440
441         /*
442          * Add initial defs for all values live in.
443          */
444         for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) {
445                 if(has_reg_class(env, irn)) {
446
447                         /* Mark the value live in. */
448                         bitset_set(live, get_irn_graph_nr(irn));
449
450                         /* Add the def */
451                         border_def(irn, step, 0);
452                 }
453         }
454
455
456   del_pset(live_in);
457   del_pset(live_end);
458 }
459
460 static void assign(ir_node *block, void *env_ptr)
461 {
462         be_chordal_alloc_env_t *alloc_env = env_ptr;
463         be_chordal_env_t *env       = alloc_env->chordal_env;
464         firm_dbg_module_t *dbg      = env->dbg;
465         bitset_t *live              = alloc_env->live;
466         bitset_t *colors            = alloc_env->colors;
467         bitset_t *in_colors         = alloc_env->in_colors;
468         const arch_env_t *arch_env  = env->main_env->arch_env;
469
470         const ir_node *irn;
471         border_t *b;
472         struct list_head *head = get_block_border_head(env, block);
473         pset *live_in = put_live_in(block, pset_new_ptr_default());
474
475         bitset_clear_all(live);
476         bitset_clear_all(colors);
477         bitset_clear_all(in_colors);
478
479         DBG((dbg, LEVEL_4, "Assigning colors for block %+F\n", block));
480         DBG((dbg, LEVEL_4, "\tusedef chain for block\n"));
481         list_for_each_entry(border_t, b, head, list) {
482                 DBG((dbg, LEVEL_4, "\t%s %+F/%d\n", b->is_def ? "def" : "use",
483                                         b->irn, get_irn_graph_nr(b->irn)));
484         }
485
486         /*
487          * Add initial defs for all values live in.
488          * Since their colors have already been assigned (The dominators were
489          * allocated before), we have to mark their colors as used also.
490          */
491         for(irn = pset_first(live_in); irn; irn = pset_next(live_in)) {
492                 if(has_reg_class(env, irn)) {
493                         const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
494                         int col;
495
496                         assert(reg && "Node must have been assigned a register");
497                         col = arch_register_get_index(reg);
498
499                         /* Mark the color of the live in value as used. */
500                         bitset_set(colors, col);
501                         bitset_set(in_colors, col);
502
503                         /* Mark the value live in. */
504                         bitset_set(live, get_irn_graph_nr(irn));
505                 }
506         }
507
508         /*
509          * Mind that the sequence of defs from back to front defines a perfect
510          * elimination order. So, coloring the definitions from first to last
511          * will work.
512          */
513         list_for_each_entry_reverse(border_t, b, head, list) {
514                 ir_node *irn = b->irn;
515                 int nr = get_irn_graph_nr(irn);
516
517                 /*
518                  * Assign a color, if it is a local def. Global defs already have a
519                  * color.
520                  */
521                 if(b->is_def && !is_live_in(block, irn)) {
522                         const arch_register_t *reg;
523                         int col = NO_COLOR;
524
525                         DBG((dbg, LEVEL_4, "\tcolors in use: %b\n", colors));
526
527                         if(pset_find_ptr(alloc_env->pre_colored, irn)) {
528                                 reg = arch_get_irn_register(arch_env, irn);
529                                 col = reg->index;
530                                 assert(!bitset_is_set(colors, col) && "pre-colored register must be free");
531                         }
532
533                         else {
534                                 col = bitset_next_clear(colors, 0);
535                                 reg = arch_register_for_index(env->cls, col);
536                                 assert(arch_get_irn_register(arch_env, irn) == NULL && "This node must not have been assigned a register yet");
537                         }
538
539                         bitset_set(colors, col);
540                         arch_set_irn_register(arch_env, irn, reg);
541
542                         DBG((dbg, LEVEL_1, "\tassigning register %s(%d) to %+F\n",
543             arch_register_get_name(reg), col, irn));
544
545                         assert(!bitset_is_set(live, nr) && "Value's definition must not have been encountered");
546                         bitset_set(live, nr);
547                 }
548
549                 /* Clear the color upon a use. */
550                 else if(!b->is_def) {
551                         const arch_register_t *reg = arch_get_irn_register(arch_env, irn);
552                         int col;
553
554                         assert(reg && "Register must have been assigned");
555
556                         col = arch_register_get_index(reg);
557                         assert(bitset_is_set(live, nr) && "Cannot have a non live use");
558
559                         bitset_clear(colors, col);
560                         bitset_clear(live, nr);
561                 }
562         }
563
564         del_pset(live_in);
565 }
566
567 void be_ra_chordal_color(be_chordal_env_t *chordal_env)
568 {
569         int node_count        = get_graph_node_count(chordal_env->irg);
570         int colors_n          = arch_register_class_n_regs(chordal_env->cls);
571         ir_graph *irg         = chordal_env->irg;
572
573         be_chordal_alloc_env_t env;
574
575         if(get_irg_dom_state(irg) != dom_consistent)
576                 compute_doms(irg);
577
578         env.chordal_env  = chordal_env;
579         env.live         = bitset_malloc(node_count);
580         env.colors       = bitset_malloc(colors_n);
581         env.in_colors    = bitset_malloc(colors_n);
582         env.colors_n     = colors_n;
583         env.pre_colored  = pset_new_ptr_default();
584
585         /* Handle register targeting constraints */
586         dom_tree_walk_irg(irg, constraints, NULL, &env);
587
588         /* First, determine the pressure */
589         dom_tree_walk_irg(irg, pressure, NULL, &env);
590
591         /* Assign the colors */
592         dom_tree_walk_irg(irg, assign, NULL, &env);
593
594 #ifdef DUMP_INTERVALS
595         {
596                 char buf[128];
597         plotter_t *plotter;
598
599                 ir_snprintf(buf, sizeof(buf), "ifg_%s_%F.eps", cls->name, irg);
600         plotter = new_plotter_ps(buf);
601
602         draw_interval_tree(&draw_chordal_def_opts, chordal_env, plotter, env->arch_env, cls);
603         plotter_free(plotter);
604         }
605 #endif
606
607         free(env.live);
608         free(env.colors);
609         free(env.in_colors);
610
611         del_pset(env.pre_colored);
612 }