Added misc stuff
[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      Sebastian Hack, Matthias Braun, Daniel Grund
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 #include <libcore/lc_opts.h>
72 #include <libcore/lc_opts_enum.h>
73 #include <libcore/lc_timing.h>
74
75 #define DBG_SPILL     1
76 #define DBG_WSETS     2
77 #define DBG_FIX       4
78 #define DBG_DECIDE    8
79 #define DBG_START    16
80 #define DBG_SLOTS    32
81 #define DBG_TRACE    64
82 #define DBG_WORKSET 128
83 #define DBG_GLOBAL  256
84
85 #define ALREADY_SPILLED_FACTOR 2
86
87 #define DEAD       UINT_MAX
88 #define LIVE_END   (DEAD-1)
89 #define REMAT_DIST (DEAD-2)
90
91 static int already_spilled_factor = 2;
92 static int remat_live_range_ext   = 1;
93 static int global_pass_enabled    = 1;
94
95 static const lc_opt_table_entry_t options[] = {
96         LC_OPT_ENT_ENUM_INT      ("asf",     "already spilled factor",                                  &already_spilled_factor),
97         LC_OPT_ENT_BOOL          ("remat",   "rematerializable ops get infinite long live ranges",      &remat_live_range_ext),
98         LC_OPT_ENT_BOOL          ("global",   "rematerializable ops get infinite long live ranges",     &global_pass_enabled),
99         LC_OPT_LAST
100 };
101
102 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
103
104 /**
105  * An association between a node and a point in time.
106  */
107 typedef struct _loc_t {
108   ir_node *irn;        /**< A node. */
109   unsigned time;       /**< A use time.
110                                                  In the global pass this is used
111                                                  as the version number and not as a time.
112                                                  Only to save space...
113                                                 */
114 } loc_t;
115
116 typedef struct _workset_t {
117         int len;                        /**< current length */
118         loc_t vals[0];          /**< inlined array of the values/distances in this working set */
119 } workset_t;
120
121 typedef struct _belady_env_t {
122         struct obstack ob;
123         ir_graph *irg;
124         const arch_env_t *arch;
125         const arch_register_class_t *cls;
126         be_lv_t *lv;
127         ir_exec_freq *ef;
128
129         ir_node **blocks;   /**< Array of all blocks. */
130         int n_blocks;       /**< Number of blocks in the graph. */
131         int n_regs;                     /**< number of regs in this reg-class */
132         workset_t *ws;          /**< the main workset used while processing a block. ob-allocated */
133         ir_node *instr;         /**< current instruction */
134         int instr_nr;           /**< current instruction number (relative to block start) */
135
136         spill_env_t *senv;      /**< see bespill.h */
137         bitset_t *spilled;  /**< bitset to keep all the irns which have already been spilled. */
138 } belady_env_t;
139
140
141 static int loc_compare(const void *a, const void *b)
142 {
143         const loc_t *p = a;
144         const loc_t *q = b;
145         return (p->time > q->time) - (p->time < q->time);
146 }
147
148 static INLINE void workset_print(const workset_t *w)
149 {
150         int i;
151
152         for(i = 0; i < w->len; ++i) {
153                 ir_fprintf(stderr, "%+F %d\n", w->vals[i].irn, w->vals[i].time);
154         }
155 }
156
157 /**
158  * Alloc a new workset on obstack @p ob with maximum size @p max
159  */
160 static INLINE workset_t *new_workset(belady_env_t *env, struct obstack *ob) {
161         workset_t *res;
162         size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
163         res = obstack_alloc(ob, size);
164         memset(res, 0, size);
165         return res;
166 }
167
168 /**
169  * Alloc a new instance on obstack and make it equal to @param ws
170  */
171 static INLINE workset_t *workset_clone(belady_env_t *env, struct obstack *ob, workset_t *ws) {
172         workset_t *res;
173         size_t size = sizeof(*res) + (env->n_regs)*sizeof(res->vals[0]);
174         res = obstack_alloc(ob, size);
175         memcpy(res, ws, size);
176         return res;
177 }
178
179 /**
180  * Do NOT alloc anything. Make @param tgt equal to @param src.
181  * returns @param tgt for convenience
182  */
183 static INLINE workset_t *workset_copy(belady_env_t *env, workset_t *tgt, workset_t *src) {
184         size_t size = sizeof(*src) + (env->n_regs)*sizeof(src->vals[0]);
185         memcpy(tgt, src, size);
186         return tgt;
187 }
188
189 /**
190  * Overwrites the current content array of @param ws with the
191  * @param count locations given at memory @param locs.
192  * Set the length of @param ws to count.
193  */
194 static INLINE void workset_bulk_fill(workset_t *workset, int count, const loc_t *locs) {
195         workset->len = count;
196         memcpy(&(workset->vals[0]), locs, count * sizeof(locs[0]));
197 }
198
199 /**
200  * Inserts the value @p val into the workset, iff it is not
201  * already contained. The workset must not be full.
202  */
203 static INLINE void workset_insert(belady_env_t *env, workset_t *ws, ir_node *val) {
204         int i;
205         /* check for current regclass */
206         if (!arch_irn_consider_in_reg_alloc(env->arch, env->cls, val)) {
207                 DBG((dbg, DBG_WORKSET, "Skipped %+F\n", val));
208                 return;
209         }
210
211         /* check if val is already contained */
212         for(i=0; i<ws->len; ++i)
213                 if (ws->vals[i].irn == val)
214                         return;
215
216         /* insert val */
217         assert(ws->len < env->n_regs && "Workset already full!");
218         ws->vals[ws->len++].irn = val;
219 }
220
221 /**
222  * Removes all entries from this workset
223  */
224 static INLINE void workset_clear(workset_t *ws) {
225         ws->len = 0;
226 }
227
228 /**
229  * Removes the value @p val from the workset if present.
230  */
231 static INLINE void workset_remove(workset_t *ws, ir_node *val) {
232         int i;
233         for(i=0; i<ws->len; ++i) {
234                 if (ws->vals[i].irn == val) {
235                         ws->vals[i] = ws->vals[--ws->len];
236                         return;
237                 }
238         }
239 }
240
241 static INLINE int workset_get_index(const workset_t *ws, const ir_node *val) {
242         int i;
243         for(i=0; i<ws->len; ++i) {
244                 if (ws->vals[i].irn == val)
245                         return i;
246         }
247
248         return -1;
249 }
250
251 /**
252  * Iterates over all values in the working set.
253  * @p ws The workset to iterate
254  * @p v  A variable to put the current value in
255  * @p i  An integer for internal use
256  */
257 #define workset_foreach(ws, v, i)       for(i=0; \
258                                                                                 v=(i < ws->len) ? ws->vals[i].irn : NULL, i < ws->len; \
259                                                                                 ++i)
260
261 #define workset_set_time(ws, i, t) (ws)->vals[i].time=t
262 #define workset_get_time(ws, i) (ws)->vals[i].time
263 #define workset_set_length(ws, length) (ws)->len = length
264 #define workset_get_length(ws) ((ws)->len)
265 #define workset_get_val(ws, i) ((ws)->vals[i].irn)
266 #define workset_sort(ws) qsort((ws)->vals, (ws)->len, sizeof((ws)->vals[0]), loc_compare);
267 #define workset_contains(ws, n) (workset_get_index(ws, n) >= 0)
268
269 typedef struct _block_info_t {
270         belady_env_t *bel;
271         const ir_node *bl;
272         workset_t *ws_start, *ws_end;
273         ir_phase next_uses;
274         int id;
275
276         ir_node *first_non_in;   /**< First node in block which is not a phi.  */
277         ir_node *last_ins;       /**< The instruction before which end of
278                                                            block reloads will be inserted. */
279
280         workset_t *entrance_reg; /**< That set will contain all values
281                                                                   transported into the block which
282                                                                   are used before they are displaced.
283                                                                   That means, we later have to care to
284                                                                   bring them into the block in a register
285                                                                   or reload them at the entry of the block. */
286
287         int pressure; /**< The amount of registers which remain free
288                                         in this block. This capacity can be used to let
289                                         global variables, transported into other blocks,
290                                         live through this block. */
291
292         double exec_freq; /**< The execution frequency of this block. */
293 } block_info_t;
294
295 static INLINE void *new_block_info(belady_env_t *bel, int id)
296 {
297         ir_node      *bl  = bel->blocks[id];
298         block_info_t *res = obstack_alloc(&bel->ob, sizeof(*res));
299         memset(res, 0, sizeof(res[0]));
300         res->first_non_in = NULL;
301         res->last_ins = NULL;
302         res->bel = bel;
303         res->bl  = bl;
304         res->id  = id;
305         res->entrance_reg = new_workset(bel, &bel->ob);
306         res->exec_freq    = get_block_execfreq(bel->ef, bl);
307         set_irn_link(bl, res);
308         return res;
309 }
310
311 #define get_block_info(block)        ((block_info_t *)get_irn_link(block))
312 #define set_block_info(block, info)  set_irn_link(block, info)
313
314 static INLINE ir_node *block_info_get_last_ins(block_info_t *bi)
315 {
316         if (!bi->last_ins)
317                 bi->last_ins = be_get_end_of_block_insertion_point(bi->bl);
318
319         return bi->last_ins;
320 }
321
322 typedef struct _next_use_t {
323         unsigned is_first_use : 1; /**< Indicate that this use is the first
324                                                                  in the block. Needed to identify
325                                                                  transport in values for the global
326                                                                  pass. */
327         int step;                  /**< The time step of the use. */
328         ir_node *irn;
329         struct _next_use_t *next;  /**< The next use int this block
330                                                                  or NULL. */
331 } next_use_t;
332
333 static void *next_use_init(ir_phase *phase, ir_node *irn, void *old)
334 {
335         (void) phase;
336         (void) irn;
337         (void) old;
338         return NULL;
339 }
340
341 static void build_next_uses(block_info_t *bi)
342 {
343         ir_node *irn;
344
345         sched_renumber(bi->bl);
346
347         phase_init(&bi->next_uses, "next uses", bi->bel->irg, PHASE_DEFAULT_GROWTH, next_use_init, NULL);
348         sched_foreach_reverse(bi->bl, irn) {
349                 int i;
350
351                 if (is_Phi(irn))
352                         break;
353
354                 for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
355                         ir_node *op = get_irn_n(irn, i);
356                         next_use_t *curr = phase_get_irn_data(&bi->next_uses, op);
357                         next_use_t *use  = phase_alloc(&bi->next_uses, sizeof(use[0]));
358
359                         use->is_first_use = 1;
360                         use->step         = sched_get_time_step(irn);
361                         use->next         = curr;
362                         use->irn          = irn;
363
364                         if (curr)
365                                 curr->is_first_use = 0;
366
367                         phase_set_irn_data(&bi->next_uses, op, use);
368                 }
369         }
370 }
371
372 #define get_current_use(bi, irn)         phase_get_irn_data(&(bi)->next_uses, (irn))
373
374 static INLINE void advance_current_use(block_info_t *bi, const ir_node *irn)
375 {
376         next_use_t *use = get_current_use(bi, irn);
377
378         assert(use);
379         phase_set_irn_data(&bi->next_uses, irn, use->next);
380 }
381
382 static INLINE unsigned get_curr_distance(block_info_t *bi, const ir_node *irn, int is_usage)
383 {
384         belady_env_t *env = bi->bel;
385         next_use_t *use   = get_current_use(bi, irn);
386         int curr_step     = sched_get_time_step(irn);
387         int flags         = arch_irn_get_flags(env->arch, irn);
388
389         assert(!(flags & arch_irn_flags_ignore));
390
391         /* We have to keep nonspillable nodes in the workingset */
392         if(flags & arch_irn_flags_dont_spill)
393                 return 0;
394
395         if (!is_usage && use && use->step == curr_step)
396                 use = use->next;
397
398         if (use) {
399                 unsigned res = use->step - curr_step;
400
401                 assert(use->step >= curr_step);
402
403                 if (res != 0) {
404                         if (remat_live_range_ext && be_is_rematerializable(env->senv, irn, use->irn))
405                                 res = REMAT_DIST;
406                         else if (bitset_contains_irn(env->spilled, irn))
407                                 res *= already_spilled_factor;
408                 }
409
410                 return res;
411         }
412
413         return be_is_live_end(env->lv, bi->bl, irn) ? LIVE_END : DEAD;
414 }
415
416 static INLINE int is_local_phi(const ir_node *bl, const ir_node *irn)
417 {
418         return is_Phi(irn) && get_nodes_block(irn) == bl;
419 }
420
421 /**
422  * Check, if the value is something that is transported into a block.
423  * That is, the value is defined elsewhere or defined by a Phi in the block.
424  * @param env  The belady environment.
425  * @param bl   The block in question.
426  * @param irn  The node in question.
427  * @return     1, if node is something transported into @p bl, 0 if not.
428  * @note       The function will only give correct answers in the case
429  *             where @p irn is unsed in the block @p bl which is always
430  *             the case in our usage scenario.
431  */
432 static INLINE int is_transport_in(const ir_node *bl, const ir_node *irn)
433 {
434         return is_local_phi(bl, irn) || get_nodes_block(irn) != bl;
435 }
436
437 /**
438  * Performs the actions necessary to grant the request that:
439  * - new_vals can be held in registers
440  * - as few as possible other values are disposed
441  * - the worst values get disposed
442  *
443  * @p is_usage indicates that the values in new_vals are used (not defined)
444  * In this case reloads must be performed
445  */
446 static void displace(block_info_t *bi, workset_t *new_vals, int is_usage) {
447         belady_env_t *env       = bi->bel;
448         workset_t    *ws        = env->ws;
449         ir_node     **to_insert = alloca(env->n_regs * sizeof(to_insert[0]));
450
451         int i, len, max_allowed, demand, iter;
452         ir_node *val;
453
454         /*
455                 1. Identify the number of needed slots and the values to reload
456         */
457         demand = 0;
458         workset_foreach(new_vals, val, iter) {
459                 /* mark value as used */
460
461                 if (! workset_contains(ws, val)) {
462                         DBG((dbg, DBG_DECIDE, "    insert %+F\n", val));
463                         to_insert[demand++] = val;
464                         if (is_usage) {
465                                 int insert_reload = 1;
466                                 next_use_t *use = get_current_use(bi, val);
467
468                                 /*
469                                  * if we use a value which is transported in this block, i.e. a
470                                  * phi defined here or a live in, for the first time, we check
471                                  * if there is room for that guy to survive from the block's
472                                  * entrance to here or not.
473                                  */
474                                 assert(use);
475                                 assert(sched_get_time_step(env->instr) == use->step);
476                                 if (is_transport_in(bi->bl, val) && use->is_first_use) {
477                                         DBG((dbg, DBG_DECIDE, "entrance node %+F, pressure %d:\n", val, bi->pressure));
478                                         if (bi->pressure < env->n_regs) {
479                                                 workset_insert(env, bi->entrance_reg, val);
480                                                 insert_reload = 0;
481                                                 ++bi->pressure;
482                                                 DBG((dbg, DBG_DECIDE, "... no reload. must be considered at block start\n"));
483                                         }
484                                 }
485
486                                 if (insert_reload) {
487                                         bitset_add_irn(env->spilled, val);
488                                         DBG((dbg, DBG_SPILL, "Reload %+F before %+F\n", val, env->instr));
489                                         be_add_reload(env->senv, val, env->instr, env->cls, 1);
490                                 }
491                         }
492                 } else {
493                         assert(is_usage || "Defined value already in workset?!?");
494                         DBG((dbg, DBG_DECIDE, "    skip %+F\n", val));
495                 }
496         }
497         DBG((dbg, DBG_DECIDE, "    demand = %d\n", demand));
498
499         /*
500                 2. Make room for at least 'demand' slots
501         */
502         len         = workset_get_length(ws);
503         max_allowed = env->n_regs - demand;
504
505         /* Only make more free room if we do not have enough */
506         if (len > max_allowed) {
507                 DBG((dbg, DBG_DECIDE, "    disposing %d values\n", len - max_allowed));
508
509                 /* get current next-use distance */
510                 for (i = 0; i < ws->len; ++i) {
511                         ir_node *val  = workset_get_val(ws, i);
512                         unsigned dist = get_curr_distance(bi, val, is_usage);
513                         workset_set_time(ws, i, dist);
514                 }
515
516                 /* sort entries by increasing nextuse-distance*/
517                 workset_sort(ws);
518
519                 /* kill the last 'demand' entries in the array */
520                 workset_set_length(ws, max_allowed);
521         }
522
523         /*
524                 3. Insert the new values into the workset
525                    Also, we update the pressure in the block info.
526                    That is important for the global pass to decide
527                    how many values can live through the block.
528         */
529         for (i = 0; i < demand; ++i)
530                 workset_insert(env, env->ws, to_insert[i]);
531
532         bi->pressure = MAX(bi->pressure, workset_get_length(env->ws));
533 }
534
535 /**
536  * For the given block @p block, decide for each values
537  * whether it is used from a register or is reloaded
538  * before the use.
539  */
540 static void belady(belady_env_t *env, int id) {
541         block_info_t *block_info = new_block_info(env, id);
542         const ir_node *block     = block_info->bl;
543         void *obst_state         = obstack_base(&env->ob);
544
545         workset_t *new_vals;
546         ir_node *irn;
547         int iter;
548
549         DBG((dbg, DBG_WSETS, "Processing %+F...\n", block_info->bl));
550         new_vals = new_workset(env, &env->ob);
551         workset_clear(env->ws);
552
553         /* build the next use information for this block. */
554         build_next_uses(block_info);
555
556         env->instr_nr = 0;
557         block_info->first_non_in = NULL;
558
559         /* process the block from start to end */
560         sched_foreach(block, irn) {
561                 int i, arity;
562                 assert(workset_get_length(env->ws) <= env->n_regs && "Too much values in workset!");
563
564                 /* projs are handled with the tuple value.
565                  * Phis are no real instr (see insert_starters())
566                  * instr_nr does not increase */
567                 if (is_Proj(irn) || is_Phi(irn)) {
568                         DBG((dbg, DBG_DECIDE, "  ...%+F skipped\n", irn));
569                         continue;
570                 }
571                 DBG((dbg, DBG_DECIDE, "  ...%+F\n", irn));
572
573                 if (!block_info->first_non_in)
574                         block_info->first_non_in = irn;
575
576                 /* set instruction in the workset */
577                 env->instr = irn;
578
579                 /* allocate all values _used_ by this instruction */
580                 workset_clear(new_vals);
581                 for(i = 0, arity = get_irn_arity(irn); i < arity; ++i) {
582                         workset_insert(env, new_vals, get_irn_n(irn, i));
583                 }
584                 displace(block_info, new_vals, 1);
585
586                 /*
587                  * set all used variables to the next use in their next_use_t list
588                  * Also, kill all dead variables from the workset. They are only
589                  * augmenting the pressure. Note, that a variable is dead
590                  * if it has no further use in this block and is *not* live end
591                  */
592                 for(i = 0, arity = get_irn_arity(irn); i < arity; ++i) {
593                         ir_node *op = get_irn_n(irn, i);
594                         next_use_t *use = get_current_use(block_info, op);
595
596                         assert(use);
597                         if (!use->next && !be_is_live_end(env->lv, block, op))
598                                 workset_remove(env->ws, op);
599
600                         advance_current_use(block_info, op);
601                 }
602
603                 /* allocate all values _defined_ by this instruction */
604                 workset_clear(new_vals);
605                 if (get_irn_mode(irn) == mode_T) { /* special handling for tuples and projs */
606                         const ir_edge_t *edge;
607
608                         foreach_out_edge(irn, edge) {
609                                 ir_node *proj = get_edge_src_irn(edge);
610                                 workset_insert(env, new_vals, proj);
611                         }
612                 } else {
613                         workset_insert(env, new_vals, irn);
614                 }
615                 displace(block_info, new_vals, 0);
616
617                 env->instr_nr++;
618         }
619
620         phase_free(&block_info->next_uses);
621         obstack_free(&env->ob, obst_state);
622
623         /* Remember end-workset for this block */
624         block_info->ws_end = workset_clone(env, &env->ob, env->ws);
625         DBG((dbg, DBG_WSETS, "End workset for %+F:\n", block));
626         workset_foreach(block_info->ws_end, irn, iter)
627                 DBG((dbg, DBG_WSETS, "  %+F (%u)\n", irn, workset_get_time(block_info->ws_end, iter)));
628         DBG((dbg, DBG_WSETS, "Max pressure in block: %d\n", block_info->pressure));
629 }
630
631 /*
632  _____ _                  _       _           _   ____            _
633 |_   _| |__   ___    __ _| | ___ | |__   __ _| | |  _ \ __ _ _ __| |_
634   | | | '_ \ / _ \  / _` | |/ _ \| '_ \ / _` | | | |_) / _` | '__| __|
635   | | | | | |  __/ | (_| | | (_) | |_) | (_| | | |  __/ (_| | |  | |_
636   |_| |_| |_|\___|  \__, |_|\___/|_.__/ \__,_|_| |_|   \__,_|_|   \__|
637                     |___/
638
639 */
640
641 #define workset_set_version(ws, i, t) ((ws)->vals[(i)].time = (t))
642 #define workset_get_version(ws, i)    ((ws)->vals[(i)].time)
643
644 #define ver_oldest                        (0)
645 #define ver_youngest                      ((unsigned) -1)
646 #define ver_make_newer(v)                 ((v) + 1)
647 #define ver_is_older(v, w)                ((v) < (w))
648 #define ver_is_younger(v, w)              ((v) > (w))
649
650 static int block_freq_gt(const void *a, const void *b)
651 {
652         const ir_node * const *p = a;
653         const ir_node * const *q = b;
654         block_info_t *pi = get_block_info(*p);
655         block_info_t *qi = get_block_info(*q);
656         double diff = qi->exec_freq - pi->exec_freq;
657         return (diff > 0) - (diff < 0);
658 }
659
660 enum {
661         irn_act_none = 0,
662         irn_act_reload,
663         irn_act_live_through
664 };
665
666 typedef struct _block_state_t {
667         struct _block_state_t *next;
668         struct _block_state_t *next_intern;
669         block_info_t *bi;
670         unsigned pressure;
671         workset_t *end_state;
672 } block_state_t;
673
674 typedef struct _irn_action_t {
675         struct _irn_action_t *next;
676         ir_node *irn;
677         const ir_node *bl;
678         int act;
679 } irn_action_t;
680
681 typedef struct _global_end_state_t {
682         belady_env_t *env;
683         bitset_t *succ_phis;
684         bitset_t *committed;
685         struct obstack obst;
686         void *reset_level;
687         unsigned version;
688
689         unsigned       *bs_tops_vers;
690         block_state_t **bs_tops;
691         block_state_t  *bs_top;
692         irn_action_t   *ia_top;
693 } global_end_state_t;
694
695 typedef struct {
696         void          *obst_level;
697         block_state_t *bs_top;
698         irn_action_t  *ia_top;
699 } rollback_info_t;
700
701 static INLINE block_state_t *get_block_state(global_end_state_t *ges, block_info_t *bi)
702 {
703         int id = bi->id;
704         assert(!ver_is_younger(ges->bs_tops_vers[id], ges->version));
705         return ver_is_older(ges->bs_tops_vers[id], ges->version) ? NULL : ges->bs_tops[bi->id];
706 }
707
708 static INLINE const workset_t *get_end_state(global_end_state_t *ges, block_info_t *bi)
709 {
710         block_state_t *bs = get_block_state(ges, bi);
711         return bs ? bs->end_state : bi->ws_end;
712 }
713
714 static block_state_t *new_block_state(global_end_state_t *ges, block_info_t *bi)
715 {
716         block_state_t *bs = get_block_state(ges, bi);
717         block_state_t *nw = obstack_alloc(&ges->obst, sizeof(nw[0]));
718
719         nw->next_intern = bs;
720         nw->next        = ges->bs_top;
721         nw->bi          = bi;
722
723         if (bs) {
724                 nw->pressure  = bs->pressure;
725                 nw->end_state = workset_clone(ges->env, &ges->obst, bs->end_state);
726         }
727         else {
728                 nw->pressure  = bi->pressure;
729                 nw->end_state = workset_clone(ges->env, &ges->obst, bi->ws_end);
730         }
731
732         ges->bs_top               = nw;
733         ges->bs_tops[bi->id]      = nw;
734         ges->bs_tops_vers[bi->id] = ges->version;
735         return nw;
736 }
737
738 static irn_action_t *new_irn_action(global_end_state_t *ges, ir_node *irn, const ir_node *bl)
739 {
740         irn_action_t *ia = obstack_alloc(&ges->obst, sizeof(ia[0]));
741
742         ia->irn  = irn;
743         ia->bl   = bl;
744         ia->act  = irn_act_none;
745         ia->next = ges->ia_top;
746         ges->ia_top = ia;
747         return ia;
748 }
749
750 static INLINE rollback_info_t trans_begin(global_end_state_t *ges)
751 {
752         rollback_info_t rb;
753         rb.obst_level = obstack_base(&ges->obst);
754         rb.bs_top     = ges->bs_top;
755         rb.ia_top     = ges->ia_top;
756         return rb;
757 }
758
759 static INLINE void trans_rollback(global_end_state_t *ges, rollback_info_t *rb)
760 {
761         block_state_t *bs;
762
763         /* unwind all the stacks indiced with the block number */
764         for (bs = ges->bs_top; bs != rb->bs_top; bs = bs->next) {
765                 unsigned id = bs->bi->id;
766                 ges->bs_tops[id] = bs->next_intern;
767         }
768
769         ges->ia_top = rb->ia_top;
770         ges->bs_top = rb->bs_top;
771         obstack_free(&ges->obst, rb->obst_level);
772 }
773
774
775 static double can_bring_in(global_end_state_t *ges, ir_node *bl, ir_node *irn, double limit, int level);
776
777 static double can_make_available_at_end(global_end_state_t *ges, ir_node *bl, ir_node *irn, double limit, int level)
778 {
779         block_info_t *bi     = get_block_info(bl);
780         const workset_t *end = get_end_state(ges, bi);
781         double res;
782         int index;
783
784         DBG((dbg, DBG_GLOBAL, "\t%2Dcan make avail %+F at end of %+F\n", level, irn, bl));
785
786         /*
787          * to make the value available at end,
788          * we have several cases here.
789          *
790          * - we already visited that block.
791          * - If the value is in the final end set, return 0.
792          *   somebody else already allocated it there.
793          * - If not and the final end set is already full,
794          *   we cannot make the value available at the end
795          *   of this block. return INFINITY.
796          * - Else (value not in final end set and there is room):
797          *   1) The value is in a register at the end of the local Belady pass.
798          *      Allocate a slot in  the final end set and return 0.
799          *   2) The value is not in the Belady end set:
800          *      If the block's capacity is < k then check what it costs
801          *      to transport the value from upper blocks to this block.
802          *      Compare that against the reload cost in this block. If
803          *      cheaper, do the other thing. If not, reload it here.
804          */
805
806         /* if the end set contains it already, it is in a reg and it costs nothing
807          * to load it to one. */
808         index = workset_get_index(end, irn);
809         if (index >= 0) {
810                 unsigned ver = workset_get_version(end, index);
811                 DBG((dbg, DBG_GLOBAL, "\t%2Dnode is in the end set and is %s fixed\n",
812                                         level, ver_is_older(ver, ges->version) ? "already" : "not yet"));
813
814                 /*
815                  * if the version is older, the value is already fixed
816                  * and cannot be removed from the end set.
817                  *
818                  * If not, we will create a new block state for that block since
819                  * we modify it by giving the end state a new version.
820                  */
821                 if (ver_is_younger(ver, ges->version)) {
822                         block_state_t *bs = new_block_state(ges, bi);
823                         workset_set_version(bs->end_state, index, ges->version);
824                 }
825
826                 res = 0.0;
827                 goto end;
828         }
829
830         /*
831          * Now we have two options:
832          * 1) Reload the value at the end of the block.
833          *    Therefore, perhaps, we have to erase another one from the workset.
834          *    This may only be done if it has not been fixed.
835          *    Since fixed means that a previous pass has decided that that value
836          *    *has* to stay in the end set.
837          * 2) we can try, if the capacity of the block allows it, to let
838          *    the value live through the block and make it available at
839          *    the entrance.
840          *
841          * First, we test the local (reload in this block) alternative
842          * and compare against the other alternative.
843          * Of course, we chose the cheaper one.
844          */
845
846         {
847                 int n_regs = bi->bel->n_regs;
848                 int len  = workset_get_length(end);
849                 int slot = -1;
850                 int i;
851
852                 res = HUGE_VAL;
853
854                 /*
855                  * look if there is room in the end array
856                  * for the variable. Note that this does not
857                  * mean that the var can live through the block.
858                  * There is just room at the *end*
859                  */
860                 if (len < n_regs) {
861                         DBG((dbg, DBG_GLOBAL, "\t%2Dthe end set has %d free slots\n", level, n_regs - len));
862                         slot = len;
863                 } else {
864                         for (i = 0; i < len; ++i) {
865                                 unsigned ver = workset_get_version(end, i);
866                                 if (ver_is_younger(ver, ges->version))
867                                         break;
868                         }
869
870                         if (i < len) {
871                                 DBG((dbg, DBG_GLOBAL, "\t%2D%+F (slot %d) can be erased from the end set\n",
872                                                         level, end->vals[i].irn, i));
873                                 slot = i;
874                         }
875                 }
876
877                 /*
878                  * finally there is some room. we can at least reload the value.
879                  * but we will try to let ot live through anyhow.
880                  */
881                 if (slot >= 0) {
882                         irn_action_t *vs    = new_irn_action(ges, irn, bi->bl);
883                         block_state_t *bs   = new_block_state(ges, bi);
884                         workset_t *end      = bs->end_state;
885                         ir_node *ins_before = block_info_get_last_ins(bi);
886                         double reload_here  = be_get_reload_costs(bi->bel->senv, irn, ins_before);
887                         int pressure_ok     = bs->pressure < (unsigned) n_regs;
888
889                         /*
890                          * No matter what we do, the value will be in the end set
891                          * if the block from now on (of course only regarding the
892                          * current state). Enter it and set the new length
893                          * appropriately.
894                          */
895                         end->vals[slot].irn     = irn;
896                         workset_set_version(end, slot, ges->version);
897                         workset_set_length(end, MAX(workset_get_length(end), slot + 1));
898
899                         vs->act = irn_act_reload;
900                         res     = reload_here;
901
902                         DBG((dbg, DBG_GLOBAL, "\t%2Dthere is a free slot. capacity=%d, reload here=%f, pressure %s\n",
903                                                 level, n_regs - bs->pressure, reload_here, pressure_ok ? "ok" : "insufficient"));
904
905                         /* look if we can bring the value in. */
906                         if (pressure_ok) {
907                                 rollback_info_t rb = trans_begin(ges);
908                                 double new_limit   = MIN(reload_here, limit);
909
910                                 vs->act = irn_act_live_through;
911                                 bs->pressure += 1;
912                                 res = can_bring_in(ges, bl, irn, new_limit, level + 1);
913
914                                 /*
915                                  * if bring in is too expensive re-adjust the pressure
916                                  * and roll back the state
917                                  */
918                                 if (res >= reload_here) {
919                                         bs->pressure -= 1;
920                                         vs->act = irn_act_reload;
921                                         trans_rollback(ges, &rb);
922                                         res = reload_here;
923                                 }
924                         }
925
926                         DBG((dbg, DBG_GLOBAL, "\t%2D%s\n", level,
927                                                 vs->act == irn_act_reload ? "reloading" : "bringing in"));
928                 }
929         }
930
931 end:
932         DBG((dbg, DBG_GLOBAL, "\t%2D-> %f\n", level, res));
933         return res;
934 }
935
936 static double can_bring_in(global_end_state_t *ges, ir_node *bl, ir_node *irn, double limit, int level)
937 {
938         belady_env_t *env = ges->env;
939         double glob_costs = HUGE_VAL;
940
941         DBG((dbg, DBG_GLOBAL, "\t%2Dcan bring in (max %f) for %+F at block %+F\n", level, limit, irn, bl));
942
943         if (is_transport_in(bl, irn)) {
944                 int i, n           = get_irn_arity(bl);
945                 ir_node **nodes    = alloca(get_irn_arity(bl) * sizeof(nodes[0]));
946                 rollback_info_t rb = trans_begin(ges);
947
948
949                 glob_costs = 0.0;
950                 for (i = 0; i < n; ++i) {
951                         ir_node *pr = get_Block_cfgpred_block(bl, i);
952                         ir_node *op = is_local_phi(bl, irn) ? get_irn_n(irn, i) : irn;
953                         double c;
954
955                         /*
956                          * there might by unknwons as operands of phis in that case
957                          * we set the costs to zero, since they won't get spilled.
958                          */
959                         if (arch_irn_consider_in_reg_alloc(env->arch, env->cls, op))
960                                 c = can_make_available_at_end(ges, pr, op, limit - glob_costs, level + 1);
961                         else
962                                 c = 0.0;
963
964                         glob_costs += c;
965
966                         if (glob_costs >= limit) {
967                                 glob_costs = HUGE_VAL;
968                                 trans_rollback(ges, &rb);
969                                 goto end;
970                         }
971                 }
972         }
973
974 end:
975         DBG((dbg, DBG_GLOBAL, "\t%2D-> %f\n", level, glob_costs));
976         return glob_costs;
977 }
978
979 static void materialize_and_commit_end_state(global_end_state_t *ges)
980 {
981         belady_env_t *env = ges->env;
982         irn_action_t *ia;
983         block_state_t *bs;
984
985         DBG((dbg, DBG_GLOBAL, "\tmaterializing\n"));
986
987         /*
988          * Perform all the variable actions.
989          */
990         for (ia = ges->ia_top; ia != NULL; ia = ia->next) {
991                 switch (ia->act) {
992                         case irn_act_live_through:
993                                 if (is_local_phi(ia->bl, ia->irn)) {
994                                         bitset_add_irn(ges->succ_phis, ia->irn);
995                                         DBG((dbg, DBG_GLOBAL, "\t\tlive through phi kept alive: %+F\n", ia->irn));
996                                 }
997                                 break;
998                         case irn_act_reload:
999                                 be_add_reload_at_end(env->senv, ia->irn, ia->bl, env->cls, 1);
1000                                 DBG((dbg, DBG_GLOBAL, "\t\tadding reload of %+F at end of %+F\n", ia->irn, ia->bl));
1001                                 break;
1002                         default:
1003                                 DBG((dbg, DBG_GLOBAL, "\t\t%+F is in the end set of %+F\n", ia->irn, ia->bl));
1004                 }
1005         }
1006
1007         /*
1008          * Commit the block end states
1009          */
1010         for (bs = ges->bs_top; bs != NULL; bs = bs->next) {
1011                 block_info_t *bi = bs->bi;
1012
1013                 if (!bitset_is_set(ges->committed, bi->id)) {
1014                         DBG((dbg, DBG_GLOBAL, "\t\tcommiting workset of %+F with version %x\n", bi->bl, ges->version));
1015                         // bes->bs->end_state->vals[idx].version = ges->version;
1016                         workset_copy(env, bi->ws_end, bs->end_state);
1017                         DBG((dbg, DBG_GLOBAL, "\t\told pressure: %d, new pressure: %d, end length: %d\n",
1018                                                 bi->pressure, bs->pressure, workset_get_length(bs->end_state)));
1019                         bi->pressure = bs->pressure;
1020                         bitset_set(ges->committed, bi->id);
1021                 }
1022         }
1023
1024         /* clear the committed bitset. the next call is expecting it. */
1025         bitset_clear_all(ges->committed);
1026 }
1027
1028 /**
1029  * Examine all irns which shall be in regs at the beginning of the
1030  * block.
1031  */
1032 static void fix_block_borders(global_end_state_t *ges, ir_node *block) {
1033         block_info_t *bi  = get_block_info(block);
1034         belady_env_t *env = ges->env;
1035         void *reset_level = obstack_base(&ges->obst);
1036
1037         ir_node *irn;
1038         int i;
1039
1040         for (i = workset_get_length(bi->ws_end) - 1; i >= 0; --i)
1041                 workset_set_version(bi->ws_end, i, ver_youngest);
1042
1043         DBG((dbg, DBG_GLOBAL, "fixing block borders at %+F (%f)\n", block, bi->exec_freq));
1044
1045         /* process all variables which shall be in a reg at
1046          * the beginning of the block in the order of the next use. */
1047         workset_foreach(bi->entrance_reg, irn, i) {
1048                 double local_costs = be_get_reload_costs(env->senv, irn, bi->first_non_in);
1049                 double bring_in_costs;
1050
1051                 /* reset the lists */
1052                 ges->bs_top  = NULL;
1053                 ges->ia_top  = NULL;
1054
1055                 DBG((dbg, DBG_GLOBAL, "\ttrans in var %+F, version %x\n", irn, ges->version));
1056
1057                 bring_in_costs = can_bring_in(ges, block, irn, local_costs, 1);
1058
1059                 DBG((dbg, DBG_GLOBAL, "\tbring in: %f, local: %f", bring_in_costs, local_costs));
1060
1061                 /*
1062                  * we were not able to let the value arrive
1063                  * in a register at the entrance of the block
1064                  * or it is too costly, so we have to do the reload locally
1065                  */
1066                 if (bring_in_costs >= local_costs) {
1067                         DBG((dbg, DBG_GLOBAL, " -> do local reload\n"));
1068                         be_add_reload(env->senv, irn, bi->first_non_in, env->cls, 1);
1069                 } else {
1070                         /*
1071                          * if the transport-in was a phi (that is actually used in block)
1072                          * it will no longer remain and we have to spill it completely.
1073                          */
1074                         if (is_local_phi(block, irn))
1075                                 bitset_add_irn(ges->succ_phis, irn);
1076
1077                         DBG((dbg, DBG_GLOBAL, " -> bring it in\n"));
1078                         materialize_and_commit_end_state(ges);
1079                 }
1080
1081                 DBG((dbg, DBG_GLOBAL, "\n"));
1082
1083                 /* reset the obstack and create a new version. */
1084                 obstack_free(&ges->obst, reset_level);
1085                 ges->version = ver_make_newer(ges->version);
1086         }
1087 }
1088
1089 static void global_assign(belady_env_t *env)
1090 {
1091         global_end_state_t ges;
1092         int i;
1093
1094         /*
1095          * sort the blocks according to execution frequency.
1096          * That's not necessary for belady() but for the global pass later on.
1097          */
1098         qsort(env->blocks, env->n_blocks, sizeof(env->blocks[0]), block_freq_gt);
1099
1100         memset(&ges, 0, sizeof(ges));
1101         obstack_init(&ges.obst);
1102         ges.env          = env;
1103         ges.version      = ver_make_newer(ver_oldest);
1104         ges.succ_phis    = bitset_irg_obstack_alloc(&ges.obst, env->irg);
1105         ges.committed    = bitset_obstack_alloc(&ges.obst, env->n_blocks);
1106         ges.bs_tops      = obstack_alloc(&ges.obst, sizeof(ges.bs_tops[0])      * env->n_blocks);
1107         ges.bs_tops_vers = obstack_alloc(&ges.obst, sizeof(ges.bs_tops_vers[0]) * env->n_blocks);
1108
1109         for (i = 0; i < env->n_blocks; ++i)
1110                 ges.bs_tops_vers[i] = ver_oldest;
1111
1112         for (i = 0; i < env->n_blocks; ++i)
1113                 fix_block_borders(&ges, env->blocks[i]);
1114
1115         /*
1116          * Now we spill phis which cannot be kept since they were replaced
1117          * by reloads at the block entrances.
1118          */
1119         for (i = 0; i < env->n_blocks; ++i) {
1120                 ir_node *bl = env->blocks[i];
1121                 ir_node *irn;
1122
1123                 sched_foreach(bl, irn) {
1124                         if (!is_Phi(irn))
1125                                 break;
1126
1127                         if (arch_irn_consider_in_reg_alloc(env->arch, env->cls, irn)
1128                                         && !bitset_contains_irn(ges.succ_phis, irn))
1129                                 be_spill_phi(env->senv, irn);
1130                 }
1131         }
1132 }
1133
1134 static void collect_blocks(ir_node *bl, void *data)
1135 {
1136         belady_env_t *env = data;
1137         ++env->n_blocks;
1138         obstack_ptr_grow(&env->ob, bl);
1139 }
1140
1141 /**
1142  * Do spilling for a register class on a graph using the belady heuristic.
1143  * In the transformed graph, the register pressure never exceeds the number
1144  * of available registers.
1145  *
1146  * @param birg  The backend graph
1147  * @param cls   The register class to spill
1148  */
1149 void be_spill_belady(be_irg_t *birg, const arch_register_class_t *cls)
1150 {
1151         ir_graph *irg = be_get_birg_irg(birg);
1152         belady_env_t env;
1153         int i, n_regs;
1154
1155         /* some special classes contain only ignore regs, nothing to do then */
1156         n_regs = cls->n_regs - be_put_ignore_regs(birg, cls, NULL);
1157         if(n_regs == 0)
1158                 return;
1159
1160         be_clear_links(irg);
1161
1162         /* init belady env */
1163         obstack_init(&env.ob);
1164         env.irg       = irg;
1165         env.arch      = birg->main_env->arch_env;
1166         env.cls       = cls;
1167         env.lv        = be_get_birg_liveness(birg);
1168         env.n_regs    = n_regs;
1169         env.ws        = new_workset(&env, &env.ob);
1170         env.senv      = be_new_spill_env(birg);
1171         env.ef        = be_get_birg_exec_freq(birg);
1172         env.spilled   = bitset_irg_obstack_alloc(&env.ob, irg);
1173         env.n_blocks  = 0;
1174
1175         irg_block_walk_graph(irg, NULL, collect_blocks, &env);
1176         obstack_ptr_grow(&env.ob, NULL);
1177         env.blocks = obstack_finish(&env.ob);
1178
1179         /* Fix high register pressure in blocks with belady algorithm */
1180         for (i = 0; i < env.n_blocks; ++i)
1181                 belady(&env, i);
1182
1183         global_assign(&env);
1184
1185         /* Insert spill/reload nodes into the graph and fix usages */
1186         be_insert_spills_reloads(env.senv);
1187
1188         /* clean up */
1189         be_delete_spill_env(env.senv);
1190
1191         obstack_free(&env.ob, NULL);
1192 }
1193
1194 void be_init_spillbelady2(void)
1195 {
1196         lc_opt_entry_t *be_grp    = lc_opt_get_grp(firm_opt_get_root(), "be");
1197         lc_opt_entry_t *spill_grp = lc_opt_get_grp(be_grp, "spill");
1198         lc_opt_entry_t *bel2_grp  = lc_opt_get_grp(spill_grp, "belady2");
1199
1200         static be_spiller_t belady_spiller = {
1201                 be_spill_belady
1202         };
1203
1204         lc_opt_add_table(bel2_grp, options);
1205         be_register_spiller("belady2", &belady_spiller);
1206         FIRM_DBG_REGISTER(dbg, "firm.be.spill.belady2");
1207 }
1208
1209 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillbelady2);