Fixed again some bugs
[libfirm] / ir / be / bespillbelady2.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       Beladys spillalgorithm version 2.
23  * @author      Daniel Grund, Matthias Braun, Sebastian Hack
24  * @date        01.08.2007
25  * @version     $Id$
26  *
27  * The main differences to the original Belady are:
28  * - The workset is empty at the start of a block
29  *   There is no attempt to fill it with variables which
30  *   are not used in the block.
31  * - There is a global pass which tries to use the remaining
32  *   capacity of the blocks to let global variables live through
33  *   them.
34  */
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include <math.h>
40 #include <limits.h>
41
42 #include "obst.h"
43 #include "irnodeset.h"
44 #include "irbitset.h"
45 #include "irprintf_t.h"
46 #include "irgraph.h"
47 #include "irnode.h"
48 #include "irmode.h"
49 #include "irgwalk.h"
50 #include "irloop.h"
51 #include "iredges_t.h"
52 #include "irphase_t.h"
53 #include "ircons_t.h"
54 #include "irprintf.h"
55 #include "execfreq.h"
56 #include "xmalloc.h"
57
58 #include "beutil.h"
59 #include "bearch_t.h"
60 #include "bespillbelady.h"
61 #include "besched_t.h"
62 #include "beirgmod.h"
63 #include "belive_t.h"
64 #include "benode_t.h"
65 #include "bechordal_t.h"
66 #include "bespilloptions.h"
67 #include "beloopana.h"
68 #include "beirg_t.h"
69 #include "bemodule.h"
70
71 #define DBG_SPILL     1
72 #define DBG_WSETS     2
73 #define DBG_FIX       4
74 #define DBG_DECIDE    8
75 #define DBG_START    16
76 #define DBG_SLOTS    32
77 #define DBG_TRACE    64
78 #define DBG_WORKSET 128
79 #define DBG_GLOBAL  256
80
81 #define DEAD UINT_MAX
82 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
83
84 /**
85  * An association between a node and a point in time.
86  */
87 typedef struct _loc_t {
88   ir_node *irn;        /**< A node. */
89   unsigned time;       /**< A use time (see beuses.h). */
90   unsigned version;    /**< That is used in the global pass below.
91                                                  For usage see the comments below.
92                                                  In the local belady pass, this is not
93                                                  important. */
94 } loc_t;
95
96 typedef struct _workset_t {
97         int len;                        /**< current length */
98         loc_t vals[0];          /**< inlined array of the values/distances in this working set */
99 } workset_t;
100
101 typedef struct _belady_env_t {
102         struct obstack ob;
103         ir_graph *irg;
104         const arch_env_t *arch;
105         const arch_register_class_t *cls;
106         be_lv_t *lv;
107         ir_exec_freq *ef;
108
109         ir_node **blocks;   /**< Array of all blocks. */
110         int n_blocks;       /**< Number of blocks in the graph. */
111         int n_regs;                     /**< number of regs in this reg-class */
112         workset_t *ws;          /**< the main workset used while processing a block. ob-allocated */
113         ir_node *instr;         /**< current instruction */
114         unsigned instr_nr;      /**< current instruction number (relative to block start) */
115
116         spill_env_t *senv;      /**< see bespill.h */
117 } belady_env_t;
118
119
120 static int loc_compare(const void *a, const void *b)
121 {
122         const loc_t *p = a;
123         const loc_t *q = b;
124         return (int) p->time - (int) q->time;
125 }
126
127 static INLINE void workset_print(const workset_t *w)
128 {
129         int i;
130
131         for(i = 0; i < w->len; ++i) {
132                 ir_fprintf(stderr, "%+F %d\n", w->vals[i].irn, w->vals[i].time);
133         }
134 }
135
136 /**
137  * Alloc a new workset on obstack @p ob with maximum size @p max
138  */
139 static INLINE workset_t *new_workset(belady_env_t *env, struct obstack *ob) {
140         workset_t *res;
141         size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
142         res = obstack_alloc(ob, size);
143         memset(res, 0, size);
144         return res;
145 }
146
147 /**
148  * Alloc a new instance on obstack and make it equal to @param ws
149  */
150 static INLINE workset_t *workset_clone(belady_env_t *env, struct obstack *ob, workset_t *ws) {
151         workset_t *res;
152         size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
153         res = obstack_alloc(ob, size);
154         memcpy(res, ws, size);
155         return res;
156 }
157
158 /**
159  * Do NOT alloc anything. Make @param tgt equal to @param src.
160  * returns @param tgt for convenience
161  */
162 static INLINE workset_t *workset_copy(belady_env_t *env, workset_t *tgt, workset_t *src) {
163         size_t size = sizeof(*src) + (env->n_regs)*sizeof(src->vals[0]);
164         memcpy(tgt, src, size);
165         return tgt;
166 }
167
168 /**
169  * Overwrites the current content array of @param ws with the
170  * @param count locations given at memory @param locs.
171  * Set the length of @param ws to count.
172  */
173 static INLINE void workset_bulk_fill(workset_t *workset, int count, const loc_t *locs) {
174         workset->len = count;
175         memcpy(&(workset->vals[0]), locs, count * sizeof(locs[0]));
176 }
177
178 /**
179  * Inserts the value @p val into the workset, iff it is not
180  * already contained. The workset must not be full.
181  */
182 static INLINE void workset_insert(belady_env_t *env, workset_t *ws, ir_node *val) {
183         int i;
184         /* check for current regclass */
185         if (!arch_irn_consider_in_reg_alloc(env->arch, env->cls, val)) {
186                 DBG((dbg, DBG_WORKSET, "Skipped %+F\n", val));
187                 return;
188         }
189
190         /* check if val is already contained */
191         for(i=0; i<ws->len; ++i)
192                 if (ws->vals[i].irn == val)
193                         return;
194
195         /* insert val */
196         assert(ws->len < env->n_regs && "Workset already full!");
197         ws->vals[ws->len++].irn = val;
198 }
199
200 /**
201  * Removes all entries from this workset
202  */
203 static INLINE void workset_clear(workset_t *ws) {
204         ws->len = 0;
205 }
206
207 /**
208  * Removes the value @p val from the workset if present.
209  */
210 static INLINE void workset_remove(workset_t *ws, ir_node *val) {
211         int i;
212         for(i=0; i<ws->len; ++i) {
213                 if (ws->vals[i].irn == val) {
214                         ws->vals[i] = ws->vals[--ws->len];
215                         return;
216                 }
217         }
218 }
219
220 static INLINE int workset_get_index(const workset_t *ws, const ir_node *val) {
221         int i;
222         for(i=0; i<ws->len; ++i) {
223                 if (ws->vals[i].irn == val)
224                         return i;
225         }
226
227         return -1;
228 }
229
230 /**
231  * Iterates over all values in the working set.
232  * @p ws The workset to iterate
233  * @p v  A variable to put the current value in
234  * @p i  An integer for internal use
235  */
236 #define workset_foreach(ws, v, i)       for(i=0; \
237                                                                                 v=(i < ws->len) ? ws->vals[i].irn : NULL, i < ws->len; \
238                                                                                 ++i)
239
240 #define workset_set_time(ws, i, t) (ws)->vals[i].time=t
241 #define workset_get_time(ws, i) (ws)->vals[i].time
242 #define workset_set_length(ws, length) (ws)->len = length
243 #define workset_get_length(ws) ((ws)->len)
244 #define workset_get_val(ws, i) ((ws)->vals[i].irn)
245 #define workset_sort(ws) qsort((ws)->vals, (ws)->len, sizeof((ws)->vals[0]), loc_compare);
246 #define workset_contains(ws, n) (workset_get_index(ws, n) >= 0)
247
248 typedef struct _block_info_t {
249         belady_env_t *bel;
250         const ir_node *bl;
251         workset_t *ws_start, *ws_end;
252         ir_phase next_uses;
253
254         ir_node *first_non_in;   /**< First node in block which is not a phi.  */
255         ir_node *last_ins;       /**< The instruction before which end of
256                                                            block reloads will be inserted. */
257
258         workset_t *entrance_reg; /**< That set will contain all values
259                                                                   transported into the block which
260                                                                   are used before they are displaced.
261                                                                   That means, we later have to care to
262                                                                   bring them into the block in a register
263                                                                   or reload them at the entry of the block. */
264
265         int pressure; /**< The amount of registers which remain free
266                                         in this block. This capacity can be used to let
267                                         global variables, transported into other blocks,
268                                         live through this block. */
269
270         double exec_freq; /**< The execution frequency of this block. */
271 } block_info_t;
272
273 static INLINE void *new_block_info(belady_env_t *bel, ir_node *bl) {
274         block_info_t *res = obstack_alloc(&bel->ob, sizeof(*res));
275         memset(res, 0, sizeof(res[0]));
276         res->first_non_in = NULL;
277         res->last_ins = NULL;
278         res->bel = bel;
279         res->bl  = bl;
280         res->entrance_reg = new_workset(bel, &bel->ob);
281         res->exec_freq    = get_block_execfreq(bel->ef, bl);
282         set_irn_link(bl, res);
283         return res;
284 }
285
286 #define get_block_info(block)        ((block_info_t *)get_irn_link(block))
287 #define set_block_info(block, info)  set_irn_link(block, info)
288
289 static INLINE ir_node *block_info_get_last_ins(block_info_t *bi)
290 {
291         if (!bi->last_ins)
292                 bi->last_ins = be_get_end_of_block_insertion_point(bi->bl);
293
294         return bi->last_ins;
295 }
296
297 typedef struct _next_use_t {
298         unsigned is_first_use : 1; /**< Indicate that this use is the first
299                                                                  in the block. Needed to identify
300                                                                  transport in values for the global
301                                                                  pass. */
302         int step;                  /**< The time step of the use. */
303         struct _next_use_t *next;  /**< The next use int this block
304                                                                  or NULL. */
305 } next_use_t;
306
307 static void *next_use_init(ir_phase *phase, ir_node *irn, void *old)
308 {
309         (void) phase;
310         (void) irn;
311         (void) old;
312         return NULL;
313 }
314
315 static void build_next_uses(block_info_t *bi)
316 {
317         ir_node *irn;
318
319         phase_init(&bi->next_uses, "next uses", bi->bel->irg, PHASE_DEFAULT_GROWTH, next_use_init, NULL);
320         sched_foreach_reverse(bi->bl, irn) {
321                 int i, step = sched_get_time_step(irn);
322
323                 if (is_Phi(irn))
324                         break;
325
326                 for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
327                         ir_node *op = get_irn_n(irn, i);
328                         next_use_t *curr = phase_get_irn_data(&bi->next_uses, op);
329                         next_use_t *use  = phase_alloc(&bi->next_uses, sizeof(use[0]));
330
331                         assert(step >= 0);
332                         use->is_first_use = 1;
333                         use->step         = step;
334                         use->next         = curr;
335
336                         if (curr)
337                                 curr->is_first_use = 0;
338
339                         phase_set_irn_data(&bi->next_uses, op, use);
340                 }
341         }
342 }
343
344 #define get_current_use(bi, irn)         phase_get_irn_data(&(bi)->next_uses, (irn))
345
346 static INLINE void advance_current_use(block_info_t *bi, const ir_node *irn)
347 {
348         next_use_t *use = get_current_use(bi, irn);
349
350         assert(use);
351         phase_set_irn_data(&bi->next_uses, irn, use->next);
352 }
353
354
355 static INLINE int is_local_phi(const ir_node *bl, const ir_node *irn)
356 {
357         return is_Phi(irn) && get_nodes_block(irn) == bl;
358 }
359
360 /**
361  * Check, if the value is something that is transported into a block.
362  * That is, the value is defined elsewhere or defined by a Phi in the block.
363  * @param env  The belady environment.
364  * @param bl   The block in question.
365  * @param irn  The node in question.
366  * @return     1, if node is something transported into @p bl, 0 if not.
367  * @note       The function will only give correct answers in the case
368  *             where @p irn is unsed in the block @p bl which is always
369  *             the case in our usage scenario.
370  */
371 static INLINE int is_transport_in(const ir_node *bl, const ir_node *irn)
372 {
373         return is_local_phi(bl, irn) || get_nodes_block(irn) != bl;
374 }
375
376 /**
377  * Performs the actions necessary to grant the request that:
378  * - new_vals can be held in registers
379  * - as few as possible other values are disposed
380  * - the worst values get disposed
381  *
382  * @p is_usage indicates that the values in new_vals are used (not defined)
383  * In this case reloads must be performed
384  */
385 static void displace(block_info_t *bi, workset_t *new_vals, int is_usage) {
386         belady_env_t *env       = bi->bel;
387         workset_t    *ws        = env->ws;
388         ir_node     **to_insert = alloca(env->n_regs * sizeof(to_insert[0]));
389
390         int i, len, max_allowed, demand, iter;
391         ir_node *val;
392
393         /*
394                 1. Identify the number of needed slots and the values to reload
395         */
396         demand = 0;
397         workset_foreach(new_vals, val, iter) {
398                 /* mark value as used */
399
400                 if (! workset_contains(ws, val)) {
401                         DBG((dbg, DBG_DECIDE, "    insert %+F\n", val));
402                         to_insert[demand++] = val;
403                         if (is_usage) {
404                                 int insert_reload = 1;
405                                 next_use_t *use = get_current_use(bi, val);
406
407                                 /*
408                                  * if we use a value which is transported in this block, i.e. a
409                                  * phi defined here or a live in, for the first time, we check
410                                  * if there is room for that guy to survive from the block's
411                                  * entrance to here or not.
412                                  */
413                                 assert(use);
414                                 assert(sched_get_time_step(env->instr) == use->step);
415                                 if (is_transport_in(bi->bl, val) && use->is_first_use) {
416                                         DBG((dbg, DBG_DECIDE, "entrance node %+F, pressure %d:\n", val, bi->pressure));
417                                         if (bi->pressure < env->n_regs) {
418                                                 workset_insert(env, bi->entrance_reg, val);
419                                                 insert_reload = 0;
420                                                 ++bi->pressure;
421                                                 DBG((dbg, DBG_DECIDE, "... no reload. must be considered at block start\n"));
422                                         }
423                                 }
424
425                                 if (insert_reload) {
426                                         DBG((dbg, DBG_SPILL, "Reload %+F before %+F\n", val, env->instr));
427                                         be_add_reload(env->senv, val, env->instr, env->cls, 1);
428                                 }
429                         }
430                 }
431                 else {
432                         assert(is_usage || "Defined value already in workset?!?");
433                         DBG((dbg, DBG_DECIDE, "    skip %+F\n", val));
434                 }
435         }
436         DBG((dbg, DBG_DECIDE, "    demand = %d\n", demand));
437
438         /*
439                 2. Make room for at least 'demand' slots
440         */
441         len         = workset_get_length(ws);
442         max_allowed = env->n_regs - demand;
443
444         /* Only make more free room if we do not have enough */
445         if (len > max_allowed) {
446                 int curr_step = sched_get_time_step(env->instr);
447
448                 DBG((dbg, DBG_DECIDE, "    disposing %d values\n", len - max_allowed));
449
450                 /* get current next-use distance */
451                 for (i = 0; i < ws->len; ++i) {
452                         ir_node *val = workset_get_val(ws, i);
453                         next_use_t *use = phase_get_irn_data(&bi->next_uses, val);
454                         assert(use == NULL || use->step >= curr_step);
455
456                         if (!is_usage && use)
457                                 use = use->next;
458
459                         workset_set_time(ws, i, use ? (unsigned) (use->step - curr_step) : DEAD);
460                 }
461
462                 /* sort entries by increasing nextuse-distance*/
463                 workset_sort(ws);
464
465                 /* kill the last 'demand' entries in the array */
466                 workset_set_length(ws, max_allowed);
467         }
468
469         /*
470                 3. Insert the new values into the workset
471                    Also, we update the pressure in the block info.
472                    That is important for the global pass to decide
473                    how many values can live through the block.
474         */
475         for (i = 0; i < demand; ++i)
476                 workset_insert(env, env->ws, to_insert[i]);
477
478         bi->pressure = MAX(bi->pressure, workset_get_length(env->ws));
479
480 }
481
482 /**
483  * For the given block @p block, decide for each values
484  * whether it is used from a register or is reloaded
485  * before the use.
486  */
487 static void belady(ir_node *block, void *data) {
488         belady_env_t *env        = data;
489         block_info_t *block_info = new_block_info(env, block);
490
491         workset_t *new_vals;
492         ir_node *irn;
493         int iter;
494
495         DBG((dbg, DBG_WSETS, "Processing %+F...\n", block_info->bl));
496         new_vals = new_workset(env, &env->ob);
497         workset_clear(env->ws);
498
499         /* build the next use information for this block. */
500         build_next_uses(block_info);
501
502         env->instr_nr = 0;
503         block_info->first_non_in = NULL;
504
505         /* process the block from start to end */
506         sched_foreach(block, irn) {
507                 int i, arity;
508                 assert(workset_get_length(env->ws) <= env->n_regs && "Too much values in workset!");
509
510                 /* projs are handled with the tuple value.
511                  * Phis are no real instr (see insert_starters())
512                  * instr_nr does not increase */
513                 if (is_Proj(irn) || is_Phi(irn)) {
514                         DBG((dbg, DBG_DECIDE, "  ...%+F skipped\n", irn));
515                         continue;
516                 }
517                 DBG((dbg, DBG_DECIDE, "  ...%+F\n", irn));
518
519                 if (!block_info->first_non_in)
520                         block_info->first_non_in = irn;
521
522                 /* set instruction in the workset */
523                 env->instr = irn;
524
525                 /* allocate all values _used_ by this instruction */
526                 workset_clear(new_vals);
527                 for(i = 0, arity = get_irn_arity(irn); i < arity; ++i) {
528                         workset_insert(env, new_vals, get_irn_n(irn, i));
529                 }
530                 displace(block_info, new_vals, 1);
531
532                 /*
533                  * set all used variables to the next use in their next_use_t list
534                  * Also, kill all dead variables from the workset. They are only
535                  * augmenting the pressure. Note, that a variable is dead
536                  * if it has no further use in this block and is *not* live end
537                  */
538                 for(i = 0, arity = get_irn_arity(irn); i < arity; ++i) {
539                         ir_node *op = get_irn_n(irn, i);
540                         next_use_t *use = get_current_use(block_info, op);
541
542                         assert(use);
543                         if (!use->next && !be_is_live_end(env->lv, block, op))
544                                 workset_remove(env->ws, op);
545
546                         advance_current_use(block_info, op);
547                 }
548
549                 /* allocate all values _defined_ by this instruction */
550                 workset_clear(new_vals);
551                 if (get_irn_mode(irn) == mode_T) { /* special handling for tuples and projs */
552                         const ir_edge_t *edge;
553
554                         foreach_out_edge(irn, edge) {
555                                 ir_node *proj = get_edge_src_irn(edge);
556                                 workset_insert(env, new_vals, proj);
557                         }
558                 } else {
559                         workset_insert(env, new_vals, irn);
560                 }
561                 displace(block_info, new_vals, 0);
562
563                 env->instr_nr++;
564         }
565
566         phase_free(&block_info->next_uses);
567
568         /* Remember end-workset for this block */
569         block_info->ws_end = workset_clone(env, &env->ob, env->ws);
570         DBG((dbg, DBG_WSETS, "End workset for %+F:\n", block));
571         workset_foreach(block_info->ws_end, irn, iter)
572                 DBG((dbg, DBG_WSETS, "  %+F (%u)\n", irn, workset_get_time(block_info->ws_end, iter)));
573         DBG((dbg, DBG_WSETS, "Max pressure in block: %d\n", block_info->pressure));
574 }
575
576 /*
577  _____ _                  _       _           _   ____            _
578 |_   _| |__   ___    __ _| | ___ | |__   __ _| | |  _ \ __ _ _ __| |_
579   | | | '_ \ / _ \  / _` | |/ _ \| '_ \ / _` | | | |_) / _` | '__| __|
580   | | | | | |  __/ | (_| | | (_) | |_) | (_| | | |  __/ (_| | |  | |_
581   |_| |_| |_|\___|  \__, |_|\___/|_.__/ \__,_|_| |_|   \__,_|_|   \__|
582                     |___/
583
584 */
585
586 static int block_freq_gt(const void *a, const void *b)
587 {
588         const ir_node * const *p = a;
589         const ir_node * const *q = b;
590         block_info_t *pi = get_block_info(*p);
591         block_info_t *qi = get_block_info(*q);
592         double diff = qi->exec_freq - pi->exec_freq;
593         return (diff > 0) - (diff < 0);
594 }
595
596 typedef struct _block_end_state_t {
597         ir_node *bl;
598         ir_node *irn;
599         double costs;
600         workset_t *end_state;
601         unsigned reload_at_end : 1;
602         unsigned live_through  : 1;
603 } block_end_state_t;
604
605 typedef struct _global_end_state_t {
606         belady_env_t *env;
607         bitset_t *succ_phis;
608         struct obstack obst;
609         block_end_state_t *end_info;
610         unsigned gauge;
611         unsigned version;
612 } global_end_state_t;
613
614 static block_end_state_t *get_block_end_state(global_end_state_t *state, ir_node *bl, ir_node *irn)
615 {
616         unsigned i;
617
618         for (i = 0; i < state->gauge; ++i) {
619                 block_end_state_t *bei = &state->end_info[i];
620                 if (bei->bl == bl && bei->irn == irn)
621                         return bei;
622         }
623
624         {
625                 block_info_t *bi = get_block_info(bl);
626                 block_end_state_t *curr;
627
628                 /* make sure we have room in the array */
629                 ARR_EXTO(block_end_state_t, state->end_info, (int) state->gauge);
630
631                 curr = &state->end_info[state->gauge];
632
633                 memset(curr, 0, sizeof(curr[0]));
634                 curr->bl  = bl;
635                 curr->irn = irn;
636                 curr->end_state = workset_clone(state->env, &state->obst, bi->ws_end);
637                 curr->costs = -1.0;
638                 ++state->gauge;
639                 return curr;
640         }
641 }
642
643 static double can_bring_in(global_end_state_t *ges, ir_node *bl, ir_node *irn, int level);
644
645 static double can_make_available_at_end(global_end_state_t *ges, ir_node *bl, ir_node *irn, int level)
646 {
647         block_end_state_t *bes = get_block_end_state(ges, bl, irn);
648         workset_t *end         = bes->end_state;
649         block_info_t *bi       = get_block_info(bl);
650         int n_regs             = bi->bel->n_regs;
651         int index;
652
653         DBG((dbg, DBG_GLOBAL, "\t%2Dcan make avail %+F at end of %+F (pressure %d)\n",
654                                 level, irn, bl, bi->pressure));
655
656         /*
657          * to make the value available at end,
658          * we have several cases here.
659          *
660          * - we already visited that block.
661          * - If the value is in the final end set, return 0.
662          *   somebody else already allocated it there.
663          * - If not and the final end set is already full,
664          *   we cannot make the value available at the end
665          *   of this block. return INFINITY.
666          * - Else (value not in final end set and there is room):
667          *   1) The value is in a register at the end of the local Belady pass.
668          *      Allocate a slot in  the final end set and return 0.
669          *   2) The value is not in the Belady end set:
670          *      If the block's capacity is < k then check what it costs
671          *      to transport the value from upper blocks to this block.
672          *      Compare that against the reload cost in this block. If
673          *      cheaper, do the other thing. If not, reload it here.
674          */
675
676         /*
677          * we have been here before and already figured out some costs.
678          * so we can exit safely.
679          */
680         if (bes->costs >= 0.0) {
681                 DBG((dbg, DBG_GLOBAL, "\t%2Dwe\'ve been here before\n", level));
682                 goto end;
683         }
684
685         /* if the end set contains it already, it is in a reg and it costs nothing
686          * to load it to one. */
687         index = workset_get_index(end, irn);
688         if (index >= 0) {
689                 unsigned ver = end->vals[index].version;
690                 DBG((dbg, DBG_GLOBAL, "\t%2Dnode is in the end set and is %s fixed\n",
691                                         level, ver > ges->version ? "already" : "not yet"));
692
693                 /*
694                  * if the version is older, the value is already fixed
695                  * and cannot be removed from the end set. If not,
696                  * we fix it here by giving it our version.
697                  */
698                 if (ver < ges->version)
699                         end->vals[index].version = ges->version;
700
701                 bes->costs = 0.0;
702                 goto end;
703         }
704
705         /*
706          * Now we have two options:
707          * 1) Reload the value at the end of the block.
708          *    Therefore, perhaps, we have to erase another one from the workset.
709          *    This may only be done if it has not been fixed.
710          *    Since fixed means that a previous pass has decided that that value
711          *    *has* to stay in the end set.
712          * 2) we can try, if the capacity of the block allows it, to let
713          *    the value live through the block and make it available at
714          *    the entrance.
715          *
716          * First, we test the local (reload in this block) alternative
717          * and compare against the other alternative.
718          * Of course, we chose the cheaper one.
719          */
720
721         {
722                 int len = workset_get_length(end);
723                 int slot = -1;
724                 int i;
725
726                 bes->costs = HUGE_VAL;
727
728                 /*
729                  * look if there is room in the end array
730                  * for the variable. Note that this does not
731                  * means that the var is living through the block.
732                  * There is just room at the *end*
733                  */
734                 if (len < n_regs) {
735                         DBG((dbg, DBG_GLOBAL, "\t%2Dthe end set has %d free slots\n",
736                                                 level, n_regs - len));
737                         slot = len;
738                 }
739                 else {
740                         for (i = 0; i < len; ++i)
741                                 if (end->vals[i].version < ges->version)
742                                         break;
743
744                         if (i < len) {
745                                 DBG((dbg, DBG_GLOBAL, "\t%2D%+F (slot %d) can be erased from the end set\n",
746                                                         level, end->vals[i].irn, i));
747                                 slot = i;
748                         }
749                 }
750
751                 if (slot >= 0) {
752                         int gauge           = ges->gauge;
753                         ir_node *ins_before = block_info_get_last_ins(bi);
754                         double reload_here  = be_get_reload_costs(bi->bel->senv, irn, ins_before);
755                         double bring_in     = bi->pressure < n_regs ? can_bring_in(ges, bl, irn, level + 1) : HUGE_VAL;
756
757                         DBG((dbg, DBG_GLOBAL, "\t%2Dthere is a free slot. capacity=%d, reload here=%f, bring in=%f\n",
758                                                 level, n_regs - bi->pressure, reload_here, bring_in));
759
760                         /*
761                          * reloading here pays off; bringing the value in from elsewhere
762                          * is too expensive, hence we drop that search by resetting
763                          * the gauge.
764                          */
765                         if (reload_here <= bring_in) {
766                                 ges->gauge = gauge;
767                                 bes->costs = reload_here;
768                                 bes->reload_at_end = 1;
769                         }
770
771                         else {
772                                 bes->live_through = 1;
773                                 bes->costs = bring_in;
774                         }
775
776                         end->vals[slot].irn     = irn;
777                         end->vals[slot].version = ges->version;
778                         end->len = MAX(end->len, slot + 1);
779                 }
780
781                 else
782                         ges->gauge -= 1;
783         }
784
785 end:
786         DBG((dbg, DBG_GLOBAL, "\t%2D-> %f\n", level, bes->costs));
787         return bes->costs;
788 }
789
790 static double can_bring_in(global_end_state_t *ges, ir_node *bl, ir_node *irn, int level)
791 {
792         double glob_costs = HUGE_VAL;
793
794         DBG((dbg, DBG_GLOBAL, "\t%2Dcan bring in for %+F at block %+F\n", level, irn, bl));
795
796         if (is_transport_in(bl, irn)) {
797                 int i, n           = get_irn_arity(bl);
798                 ir_node **nodes    = alloca(get_irn_arity(bl) * sizeof(nodes[0]));
799
800                 int gauge_begin    = ges->gauge;
801
802                 glob_costs = 0.0;
803                 for (i = 0; i < n; ++i) {
804                         ir_node *pr = get_Block_cfgpred_block(bl, i);
805                         ir_node *op = is_local_phi(bl, irn) ? get_irn_n(irn, i) : irn;
806                         double c    = can_make_available_at_end(ges, pr, op, level + 1);
807
808                         if (c >= HUGE_VAL) {
809                                 ges->gauge = gauge_begin;
810                                 glob_costs = HUGE_VAL;
811                                 goto end;
812                         }
813
814                         glob_costs += c;
815                 }
816         }
817
818 end:
819         DBG((dbg, DBG_GLOBAL, "\t%2D-> %f\n", level, glob_costs));
820         return glob_costs;
821 }
822
823 static void materialize_and_commit_end_state(global_end_state_t *ges)
824 {
825         belady_env_t *env = ges->env;
826         unsigned i;
827
828         DBG((dbg, DBG_GLOBAL, "\tmaterializing\n"));
829         for (i = 0; i < ges->gauge; ++i) {
830                 block_end_state_t *bes = &ges->end_info[i];
831                 block_info_t *bi       = get_block_info(bes->bl);
832                 int idx, end_pressure;
833
834                 DBG((dbg, DBG_GLOBAL, "\t\t%+F in %+F, cost %f through: %d, rel: %d\n",
835                                 bes->irn, bes->bl, bes->costs, bes->live_through, bes->reload_at_end));
836
837                 /* insert the reload if the val was reloaded at the block's end */
838                 if (bes->reload_at_end) {
839                         be_add_reload_at_end(env->senv, bes->irn, bes->bl, env->cls, 1);
840                         DBG((dbg, DBG_GLOBAL, "\t\tadding reload of %+F at end of %+F\n", bes->irn, bes->bl));
841                 }
842
843                 end_pressure = 0;
844                 for (idx = workset_get_length(bes->end_state) - 1; idx >= 0; --idx)
845                         if (bes->end_state->vals[idx].version >= ges->version)
846                                 end_pressure += 1;
847
848                 /*
849                  * if the variable is live through the block,
850                  * update the pressure indicator.
851                  */
852                 DBG((dbg, DBG_GLOBAL, "\t\told pressure %d, ", bi->pressure));
853
854                 bi->pressure = MAX(bi->pressure + bes->live_through, end_pressure);
855
856                 DBG((dbg, DBG_GLOBAL, "new pressure: %d, end pressure: %d, end length: %d\n",
857                                         bi->pressure, end_pressure, workset_get_length(bes->end_state)));
858
859 //              workset_print(bes->end_state);
860                 idx = workset_get_index(bes->end_state, bes->irn);
861
862                 if (is_local_phi(bes->bl, bes->irn) && bes->live_through)
863                         bitset_add_irn(ges->succ_phis, bes->irn);
864
865                 /*
866                  * set the version number in the workset.
867                  * That will mark this value as fixed in the end set
868                  * and will prevent further investigations from removing
869                  * it from there.
870                  * Also "commit" the workset;
871                  * by copying it back to the block's end workset.
872                  */
873                 if (idx >= 0) {
874                         DBG((dbg, DBG_GLOBAL, "\t\tcommiting workset of %+F with version %x\n", bes->bl, ges->version));
875                         bes->end_state->vals[idx].version = ges->version;
876                         workset_copy(env, bi->ws_end, bes->end_state);
877                 }
878         }
879 }
880
881 /**
882  * Examine all irns which shall be in regs at the beginning of the
883  * block.
884  */
885 static void fix_block_borders(global_end_state_t *ges, ir_node *block) {
886         block_info_t *bi  = get_block_info(block);
887         belady_env_t *env = ges->env;
888
889         ir_node *irn;
890         int i;
891
892         DBG((dbg, DBG_GLOBAL, "fixing block borders at %+F (%f)\n", block, bi->exec_freq));
893
894         /* process all variables which shall be in a reg at
895          * the beginning of the block in the order of the next use. */
896         workset_foreach(bi->entrance_reg, irn, i) {
897                 double local_costs = be_get_reload_costs(env->senv, irn, bi->first_non_in);
898                 double bring_in_costs;
899
900                 /* reset the gauge and create a new version. */
901                 ges->gauge    = 0;
902                 ges->version -= 1;
903
904                 DBG((dbg, DBG_GLOBAL, "\ttrans in var %+F, version %x\n", irn, ges->version));
905
906                 bring_in_costs = can_bring_in(ges, block, irn, 1);
907
908                 DBG((dbg, DBG_GLOBAL, "\tbring in: %f, local: %f", bring_in_costs, local_costs));
909
910                 /*
911                  * we were not able to let the value arrive
912                  * in a register at the entrance of the block
913                  * or it is too costly, so we have to do the reload locally
914                  */
915                 if (bring_in_costs > local_costs) {
916
917                         DBG((dbg, DBG_GLOBAL, " -> do local reload\n"));
918                         be_add_reload(env->senv, irn, bi->first_non_in, env->cls, 1);
919                 }
920
921                 else  {
922                         /*
923                          * if the transport-in was a phi (that is actually used in block)
924                          * it will no longer remain and we have to spill it completely.
925                          */
926                         if (is_local_phi(block, irn))
927                                 bitset_add_irn(ges->succ_phis, irn);
928
929                         DBG((dbg, DBG_GLOBAL, " -> do remote reload\n"));
930                         materialize_and_commit_end_state(ges);
931                 }
932
933                 DBG((dbg, DBG_GLOBAL, "\n"));
934         }
935 }
936
937 static void global_assign(belady_env_t *env)
938 {
939         global_end_state_t ges;
940         int i;
941
942         obstack_init(&ges.obst);
943         ges.gauge     = 0;
944         ges.env       = env;
945         ges.version   = -1;
946         ges.end_info  = NEW_ARR_F(block_end_state_t, env->n_blocks);
947         ges.succ_phis = bitset_irg_obstack_alloc(&env->ob, env->irg);
948
949         /*
950          * sort the blocks according to execution frequency.
951          * That's not necessary for belady() but for the global pass later on.
952          */
953         qsort(env->blocks, env->n_blocks, sizeof(env->blocks[0]), block_freq_gt);
954
955         for (i = 0; i < env->n_blocks; ++i)
956                 fix_block_borders(&ges, env->blocks[i]);
957
958         /*
959          * Now we spill phis which cannot be kept since they were replaced
960          * by reloads at the block entrances.
961          */
962         for (i = 0; i < env->n_blocks; ++i) {
963                 ir_node *bl = env->blocks[i];
964                 ir_node *irn;
965
966                 sched_foreach(bl, irn) {
967                         if (!is_Phi(irn))
968                                 break;
969
970                         if (arch_irn_consider_in_reg_alloc(env->arch, env->cls, irn)
971                                         && !bitset_contains_irn(ges.succ_phis, irn))
972                                 be_spill_phi(env->senv, irn);
973                 }
974         }
975
976 }
977
978 static void collect_blocks(ir_node *bl, void *data)
979 {
980         belady_env_t *env = data;
981         ++env->n_blocks;
982         obstack_ptr_grow(&env->ob, bl);
983 }
984
985 void be_spill_belady_spill_env2(be_irg_t *birg, const arch_register_class_t *cls, spill_env_t *spill_env) {
986         ir_graph *irg = be_get_birg_irg(birg);
987         belady_env_t env;
988         int i, n_regs;
989
990         /* some special classes contain only ignore regs, nothing to do then */
991         n_regs = cls->n_regs - be_put_ignore_regs(birg, cls, NULL);
992         if(n_regs == 0)
993                 return;
994
995         be_clear_links(irg);
996
997         /* init belady env */
998         obstack_init(&env.ob);
999         env.irg       = irg;
1000         env.arch      = birg->main_env->arch_env;
1001         env.cls       = cls;
1002         env.lv        = be_get_birg_liveness(birg);
1003         env.n_regs    = n_regs;
1004         env.ws        = new_workset(&env, &env.ob);
1005         env.senv      = spill_env ? spill_env : be_new_spill_env(birg);
1006         env.ef        = be_get_birg_exec_freq(birg);
1007         env.n_blocks  = 0;
1008
1009         irg_block_walk_graph(irg, NULL, collect_blocks, &env);
1010         obstack_ptr_grow(&env.ob, NULL);
1011         env.blocks = obstack_finish(&env.ob);
1012
1013         /* Fix high register pressure in blocks with belady algorithm */
1014         for (i = 0; i < env.n_blocks; ++i)
1015                 belady(env.blocks[i], &env);
1016
1017         global_assign(&env);
1018
1019         /* Insert spill/reload nodes into the graph and fix usages */
1020         be_insert_spills_reloads(env.senv);
1021
1022         /* clean up */
1023         if(spill_env == NULL)
1024                 be_delete_spill_env(env.senv);
1025
1026         obstack_free(&env.ob, NULL);
1027 }
1028
1029
1030 /**
1031  * Do spilling for a register class on a graph using the belady heuristic.
1032  * In the transformed graph, the register pressure never exceeds the number
1033  * of available registers.
1034  *
1035  * @param birg  The backend graph
1036  * @param cls   The register class to spill
1037  */
1038 static void be_spill_belady(be_irg_t *birg, const arch_register_class_t *cls) {
1039         be_spill_belady_spill_env2(birg, cls, NULL);
1040 }
1041
1042
1043 void be_init_spillbelady2(void)
1044 {
1045         static be_spiller_t belady_spiller = {
1046                 be_spill_belady
1047         };
1048
1049         be_register_spiller("belady2", &belady_spiller);
1050         FIRM_DBG_REGISTER(dbg, "firm.be.spill.belady2");
1051 }
1052
1053 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillbelady2);