05e6cda3d7aa5dc9be832344c376ec685d58826c
[libfirm] / ir / be / bespill.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       Main spill driver.
23  * @author      Daniel Grund, Sebastian Hack, Matthias Braun
24  * @date                29.09.2005
25  * @version     $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <stdlib.h>
32
33 #include "pset.h"
34 #include "irnode_t.h"
35 #include "ircons_t.h"
36 #include "iredges_t.h"
37 #include "irbackedge_t.h"
38 #include "irprintf.h"
39 #include "ident_t.h"
40 #include "type_t.h"
41 #include "entity_t.h"
42 #include "debug.h"
43 #include "irgwalk.h"
44 #include "array.h"
45 #include "pdeq.h"
46 #include "execfreq.h"
47 #include "irnodeset.h"
48
49 #include "belive_t.h"
50 #include "besched_t.h"
51 #include "bespill.h"
52 #include "belive_t.h"
53 #include "benode_t.h"
54 #include "bechordal_t.h"
55 #include "bejavacoal.h"
56 #include "benodesets.h"
57 #include "bespilloptions.h"
58 #include "bestatevent.h"
59 #include "bessaconstr.h"
60 #include "beirg_t.h"
61 #include "beintlive_t.h"
62
63 /* only rematerialise when costs are less than REMAT_COST_LIMIT */
64 /* TODO determine a good value here... */
65 #define REMAT_COST_LIMIT        10
66
67 typedef struct _reloader_t reloader_t;
68
69 struct _reloader_t {
70         reloader_t *next;
71         ir_node    *reloader;
72         ir_node    *rematted_node;
73         int        allow_remat;     /**< the node may be rematted instead of reloaded if global remat option is on */
74 };
75
76 typedef struct _spill_info_t {
77         /** the value that should get spilled */
78         ir_node *spilled_node;
79         /** list of places where the value should get reloaded */
80         reloader_t *reloaders;
81
82         /** the spill node, or a PhiM node */
83         ir_node *spill;
84         /** if we had the value of a phi spilled before but not the phi itself then
85          * this field contains the spill for the phi value */
86         ir_node *old_spill;
87
88         /** the register class in which the reload should be placed */
89         const arch_register_class_t *reload_cls;
90 } spill_info_t;
91
92 struct _spill_env_t {
93         const arch_env_t *arch_env;
94         ir_graph *irg;
95         struct obstack obst;
96         be_irg_t *birg;
97         int spill_cost;     /**< the cost of a single spill node */
98         int reload_cost;    /**< the cost of a reload node */
99         set *spills;        /**< all spill_info_t's, which must be placed */
100         ir_nodeset_t mem_phis;     /**< set of all special spilled phis. allocated and freed separately */
101
102         DEBUG_ONLY(firm_dbg_module_t *dbg;)
103 };
104
105 /**
106  * Compare two spill infos.
107  */
108 static int cmp_spillinfo(const void *x, const void *y, size_t size) {
109         const spill_info_t *xx = x;
110         const spill_info_t *yy = y;
111         return xx->spilled_node != yy->spilled_node;
112 }
113
114 /**
115  * Returns spill info for a specific value (returns NULL if the info doesn't
116  * exist yet)
117  */
118 static spill_info_t *find_spillinfo(const spill_env_t *env, ir_node *value) {
119         spill_info_t info;
120         int hash = nodeset_hash(value);
121
122         info.spilled_node = value;
123
124         return set_find(env->spills, &info, sizeof(info), hash);
125 }
126
127 /**
128  * Returns spill info for a specific value (the value that is to be spilled)
129  */
130 static spill_info_t *get_spillinfo(const spill_env_t *env, ir_node *value) {
131         spill_info_t info, *res;
132         int hash = nodeset_hash(value);
133
134         info.spilled_node = value;
135         res = set_find(env->spills, &info, sizeof(info), hash);
136
137         if (res == NULL) {
138                 info.reloaders = NULL;
139                 info.spill = NULL;
140                 info.old_spill = NULL;
141                 info.reload_cls = NULL;
142                 res = set_insert(env->spills, &info, sizeof(info), hash);
143         }
144
145         return res;
146 }
147
148 #ifdef DEBUG_libfirm
149 /* Sets the debug module of a spill environment. */
150 void be_set_spill_env_dbg_module(spill_env_t *env, firm_dbg_module_t *dbg) {
151         env->dbg = dbg;
152 }
153 #endif
154
155 /* Creates a new spill environment. */
156 spill_env_t *be_new_spill_env(be_irg_t *birg) {
157         spill_env_t *env        = xmalloc(sizeof(env[0]));
158         env->spills                     = new_set(cmp_spillinfo, 1024);
159         env->irg            = be_get_birg_irg(birg);
160         env->birg           = birg;
161         env->arch_env       = birg->main_env->arch_env;
162         ir_nodeset_init(&env->mem_phis);
163         // TODO, ask backend about costs..., or even ask backend whether we should
164         // rematerialize...
165         env->spill_cost     = 8;
166         env->reload_cost    = 5;
167         obstack_init(&env->obst);
168         return env;
169 }
170
171 /* Deletes a spill environment. */
172 void be_delete_spill_env(spill_env_t *env) {
173         del_set(env->spills);
174         ir_nodeset_destroy(&env->mem_phis);
175         obstack_free(&env->obst, NULL);
176         free(env);
177 }
178
179 /*
180  *  ____  _                  ____      _                 _
181  * |  _ \| | __ _  ___ ___  |  _ \ ___| | ___   __ _  __| |___
182  * | |_) | |/ _` |/ __/ _ \ | |_) / _ \ |/ _ \ / _` |/ _` / __|
183  * |  __/| | (_| | (_|  __/ |  _ <  __/ | (_) | (_| | (_| \__ \
184  * |_|   |_|\__,_|\___\___| |_| \_\___|_|\___/ \__,_|\__,_|___/
185  *
186  */
187
188 void be_add_remat(spill_env_t *env, ir_node *to_spill, ir_node *before, ir_node *rematted_node) {
189         spill_info_t *spill_info;
190         reloader_t *reloader;
191
192         spill_info = get_spillinfo(env, to_spill);
193
194         /* add the remat information */
195         reloader                = obstack_alloc(&env->obst, sizeof(reloader[0]));
196         reloader->next          = spill_info->reloaders;
197         reloader->reloader      = before;
198         reloader->rematted_node = rematted_node;
199         reloader->allow_remat   = 1;
200
201         spill_info->reloaders  = reloader;
202
203         DBG((env->dbg, LEVEL_1, "creating spillinfo for %+F, will be rematerialized before %+F\n",
204                 to_spill, before));
205 }
206
207 void be_add_reload(spill_env_t *env, ir_node *to_spill, ir_node *before,
208                 const arch_register_class_t *reload_cls, int allow_remat)
209 {
210         spill_info_t *info;
211         reloader_t *rel;
212
213         info = get_spillinfo(env, to_spill);
214
215         if (is_Phi(to_spill)) {
216                 int i, arity;
217
218                 /* create spillinfos for the phi arguments */
219                 for (i = 0, arity = get_irn_arity(to_spill); i < arity; ++i) {
220                         ir_node *arg = get_irn_n(to_spill, i);
221                         get_spillinfo(env, arg);
222                 }
223
224 #if 1
225                 // hackery... sometimes the morgan algo spilled the value of a phi,
226                 // the belady algo decides later to spill the whole phi, then sees the
227                 // spill node and adds a reload for that spill node, problem is the
228                 // reload gets attach to that same spill (and is totally unnecessary)
229                 if (info->old_spill != NULL &&
230                         (before == info->old_spill || value_dominates(before, info->old_spill)))
231                 {
232                         printf("spilledphi hack was needed...\n");
233                         before = sched_next(info->old_spill);
234                 }
235 #endif
236         }
237
238         /* put reload into list */
239         rel                = obstack_alloc(&env->obst, sizeof(rel[0]));
240         rel->next          = info->reloaders;
241         rel->reloader      = before;
242         rel->rematted_node = NULL;
243         rel->allow_remat   = allow_remat;
244
245         info->reloaders  = rel;
246         assert(info->reload_cls == NULL || info->reload_cls == reload_cls);
247         info->reload_cls = reload_cls;
248
249         DBG((env->dbg, LEVEL_1, "creating spillinfo for %+F, will be reloaded before %+F, may%s be rematerialized\n",
250                 to_spill, before, allow_remat ? "" : " not"));
251 }
252
253 /**
254  * Returns the point at which you can insert a node that should be executed
255  * before block @p block when coming from pred @p pos.
256  */
257 static ir_node *get_block_insertion_point(ir_node *block, int pos) {
258         ir_node *predblock, *last;
259
260         /* simply add the reload to the beginning of the block if we only have 1
261          * predecessor. We don't need to check for phis as there can't be any in a
262          * block with only 1 pred. */
263         if(get_Block_n_cfgpreds(block) == 1) {
264                 assert(!is_Phi(sched_first(block)));
265                 return sched_first(block);
266         }
267
268         /* We have to reload the value in pred-block */
269         predblock = get_Block_cfgpred_block(block, pos);
270         last = sched_last(predblock);
271
272         /* we might have projs and keepanys behind the jump... */
273         while(is_Proj(last) || be_is_Keep(last)) {
274                 last = sched_prev(last);
275                 assert(!sched_is_end(last));
276         }
277
278         if(!is_cfop(last)) {
279                 last = sched_next(last);
280                 // last node must be a cfop, only exception is the start block
281                 assert(last     == get_irg_start_block(get_irn_irg(block)));
282         }
283
284         // add the reload before the (cond-)jump
285         return last;
286 }
287
288 void be_add_reload_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *block, int pos,
289                 const arch_register_class_t *reload_cls, int allow_remat)
290 {
291         ir_node *before = get_block_insertion_point(block, pos);
292         be_add_reload(env, to_spill, before, reload_cls, allow_remat);
293 }
294
295 void be_spill_phi(spill_env_t *env, ir_node *node) {
296         spill_info_t* spill;
297         int i, arity;
298
299         assert(is_Phi(node));
300
301         ir_nodeset_insert(&env->mem_phis, node);
302
303         // create spillinfos for the phi arguments
304         spill = get_spillinfo(env, node);
305         for(i = 0, arity = get_irn_arity(node); i < arity; ++i) {
306                 ir_node *arg = get_irn_n(node, i);
307                 get_spillinfo(env, arg);
308         }
309
310         // if we had a spill for the phi value before, then remove this spill from
311         // schedule, as we will remove it in the insert spill/reload phase
312         if(spill->spill != NULL && !is_Phi(spill->spill)) {
313                 assert(spill->old_spill == NULL);
314                 spill->old_spill = spill->spill;
315                 spill->spill = NULL;
316         }
317 }
318
319 /*
320  *   ____                _         ____        _ _ _
321  *  / ___|_ __ ___  __ _| |_ ___  / ___| _ __ (_) | |___
322  * | |   | '__/ _ \/ _` | __/ _ \ \___ \| '_ \| | | / __|
323  * | |___| | |  __/ (_| | ||  __/  ___) | |_) | | | \__ \
324  *  \____|_|  \___|\__,_|\__\___| |____/| .__/|_|_|_|___/
325  *                                      |_|
326  */
327
328 /**
329  * Schedules a node after an instruction. That is the place after all projs and
330  * phis that are scheduled after the instruction. This function also skips phi
331  * nodes at the beginning of a block
332  */
333 static void sched_add_after_insn(ir_node *sched_after, ir_node *node) {
334         ir_node *next = sched_next(sched_after);
335         while(is_Proj(next) || is_Phi(next)) {
336                 next = sched_next(next);
337         }
338         assert(next != NULL);
339
340         if(sched_is_end(next)) {
341                 sched_add_after(sched_last(get_nodes_block(sched_after)), node);
342         } else {
343                 sched_add_before(next, node);
344         }
345 }
346
347 /**
348  * Creates a spill.
349  *
350  * @param senv      the spill environment
351  * @param irn       the node that should be spilled
352  * @param ctx_irn   an user of the spilled node
353  *
354  * @return a be_Spill node
355  */
356 static void spill_irn(spill_env_t *env, spill_info_t *spillinfo) {
357         optimization_state_t opt;
358         ir_node              *to_spill = spillinfo->spilled_node;
359
360         DBG((env->dbg, LEVEL_1, "spilling %+F ... ", to_spill));
361
362         /* Trying to spill an already spilled value, no need for a new spill
363          * node then, we can simply connect to the same one for this reload
364          *
365          * Normally reloads get simply rematerialized instead of spilled again; this
366          * can happen annyway when the reload is the pred of a phi to spill)
367          */
368         if (be_is_Reload(to_spill)) {
369                 spillinfo->spill = get_irn_n(to_spill, be_pos_Reload_mem);
370                 DB((env->dbg, LEVEL_1, "skip reload, using existing spill %+F\n", spillinfo->spill));
371                 return;
372         }
373
374         assert(!(arch_irn_is(env->arch_env, to_spill, dont_spill)
375                                 && "Attempt to spill a node marked 'dont_spill'"));
376
377         /* some backends have virtual noreg/unknown nodes that are not scheduled */
378         if(!sched_is_scheduled(to_spill)) {
379                 spillinfo->spill = new_NoMem();
380                 return;
381         }
382
383
384         /*
385                 We switch on optimizations here to get CSE. This is needed as some
386                 backends have some extra spill phases and we want to make use of those
387                 spills instead of creating new ones.
388         */
389         save_optimization_state(&opt);
390         set_optimize(1);
391         spillinfo->spill = be_spill(env->arch_env, to_spill);
392         restore_optimization_state(&opt);
393         if (! sched_is_scheduled(spillinfo->spill)) {
394                 DB((env->dbg, LEVEL_1, "add spill %+F after %+F\n", spillinfo->spill, to_spill));
395                 sched_add_after_insn(to_spill, spillinfo->spill);
396         } else {
397                 DB((env->dbg, LEVEL_1, "re-using spill %+F after %+F\n", spillinfo->spill, to_spill));
398         }
399 }
400
401 static void spill_node(spill_env_t *env, spill_info_t *spillinfo);
402
403 /**
404  * If the first usage of a Phi result would be out of memory
405  * there is no sense in allocating a register for it.
406  * Thus we spill it and all its operands to the same spill slot.
407  * Therefore the phi/dataB becomes a phi/Memory
408  *
409  * @param senv      the spill environment
410  * @param phi       the Phi node that should be spilled
411  * @param ctx_irn   an user of the spilled node
412  */
413 static void spill_phi(spill_env_t *env, spill_info_t *spillinfo) {
414         ir_node *phi = spillinfo->spilled_node;
415         int i;
416         int arity = get_irn_arity(phi);
417         ir_node     *block    = get_nodes_block(phi);
418         ir_node     **ins;
419
420         assert(is_Phi(phi));
421
422         DBG((env->dbg, LEVEL_1, "spilling Phi %+F:\n", phi));
423         /* build a new PhiM */
424         ins = alloca(sizeof(ir_node*) * arity);
425         for(i = 0; i < arity; ++i) {
426                 ins[i] = get_irg_bad(env->irg);
427         }
428         spillinfo->spill = new_r_Phi(env->irg, block, arity, ins, mode_M);
429
430         for(i = 0; i < arity; ++i) {
431                 ir_node *arg = get_irn_n(phi, i);
432                 spill_info_t *arg_info = get_spillinfo(env, arg);
433
434                 spill_node(env, arg_info);
435
436                 set_irn_n(spillinfo->spill, i, arg_info->spill);
437         }
438         DBG((env->dbg, LEVEL_1, "... done spilling Phi %+F, created PhiM %+F\n", phi, spillinfo->spill));
439
440         // rewire reloads from old_spill to phi
441         if (spillinfo->old_spill != NULL) {
442                 const ir_edge_t *edge, *next;
443                 ir_node *old_spill = spillinfo->old_spill;
444
445                 DBG((env->dbg, LEVEL_1, "old spill found, rewiring reloads:\n"));
446
447                 foreach_out_edge_safe(old_spill, edge, next) {
448                         ir_node *reload = get_edge_src_irn(edge);
449                         int     pos     = get_edge_src_pos(edge);
450
451                         DBG((env->dbg, LEVEL_1, "\tset input %d of %+F to %+F\n", pos, reload, spillinfo->spill));
452
453                         assert(be_is_Reload(reload) || is_Phi(reload));
454                         set_irn_n(reload, pos, spillinfo->spill);
455                 }
456                 DBG((env->dbg, LEVEL_1, "\tset input of %+F to BAD\n", old_spill));
457                 set_irn_n(old_spill, be_pos_Spill_val, new_Bad());
458                 //sched_remove(old_spill);
459                 spillinfo->old_spill = NULL;
460         }
461 }
462
463 /**
464  * Spill a node.
465  *
466  * @param senv      the spill environment
467  * @param to_spill  the node that should be spilled
468  */
469 static void spill_node(spill_env_t *env, spill_info_t *spillinfo) {
470         ir_node *to_spill;
471
472         // the node should be tagged for spilling already...
473         if(spillinfo->spill != NULL)
474                 return;
475
476         to_spill = spillinfo->spilled_node;
477
478         if (is_Phi(to_spill) && ir_nodeset_contains(&env->mem_phis, to_spill)) {
479                 spill_phi(env, spillinfo);
480         } else {
481                 spill_irn(env, spillinfo);
482         }
483 }
484
485 /*
486  *
487  *  ____                      _            _       _ _
488  * |  _ \ ___ _ __ ___   __ _| |_ ___ _ __(_) __ _| (_)_______
489  * | |_) / _ \ '_ ` _ \ / _` | __/ _ \ '__| |/ _` | | |_  / _ \
490  * |  _ <  __/ | | | | | (_| | ||  __/ |  | | (_| | | |/ /  __/
491  * |_| \_\___|_| |_| |_|\__,_|\__\___|_|  |_|\__,_|_|_/___\___|
492  *
493  */
494
495 /**
496  * Tests whether value @p arg is available before node @p reloader
497  * @returns 1 if value is available, 0 otherwise
498  */
499 static int is_value_available(spill_env_t *env, ir_node *arg, ir_node *reloader) {
500         if(is_Unknown(arg) || arg == new_NoMem())
501                 return 1;
502
503         if(be_is_Spill(arg))
504                 return 1;
505
506         if(arg == get_irg_frame(env->irg))
507                 return 1;
508
509         // hack for now (happens when command should be inserted at end of block)
510         if(is_Block(reloader)) {
511                 return 0;
512         }
513
514         /*
515          * Ignore registers are always available
516          */
517         if(arch_irn_is(env->arch_env, arg, ignore)) {
518                 return 1;
519         }
520
521         /* the following test does not work while spilling,
522          * because the liveness info is not adapted yet to the effects of the
523          * additional spills/reloads.
524          */
525 #if 0
526         /* we want to remat before the insn reloader
527          * thus an arguments is alive if
528          *   - it interferes with the reloaders result
529          *   - or it is (last-) used by reloader itself
530          */
531         if (values_interfere(env->birg->lv, reloader, arg)) {
532                 return 1;
533         }
534
535         arity = get_irn_arity(reloader);
536         for (i = 0; i < arity; ++i) {
537                 ir_node *rel_arg = get_irn_n(reloader, i);
538                 if (rel_arg == arg)
539                         return 1;
540         }
541 #endif
542
543         return 0;
544 }
545
546 /**
547  * Checks whether the node can principally be rematerialized
548  */
549 static int is_remat_node(spill_env_t *env, ir_node *node) {
550         const arch_env_t *arch_env = env->arch_env;
551
552         assert(!be_is_Spill(node));
553
554         if(arch_irn_is(arch_env, node, rematerializable))
555                 return 1;
556
557         return 0;
558 }
559
560 /**
561  * Check if a node is rematerializable. This tests for the following conditions:
562  *
563  * - The node itself is rematerializable
564  * - All arguments of the node are available or also rematerialisable
565  * - The costs for the rematerialisation operation is less or equal a limit
566  *
567  * Returns the costs needed for rematerialisation or something
568  * > REMAT_COST_LIMIT if remat is not possible.
569  */
570 static int check_remat_conditions_costs(spill_env_t *env, ir_node *spilled, ir_node *reloader, int parentcosts) {
571         int i, arity;
572         int argremats;
573         int costs = 0;
574
575         if(!is_remat_node(env, spilled))
576                 return REMAT_COST_LIMIT;
577
578         if(be_is_Reload(spilled)) {
579                 costs += 2;
580         } else {
581                 costs += arch_get_op_estimated_cost(env->arch_env, spilled);
582         }
583         if(parentcosts + costs >= REMAT_COST_LIMIT) {
584                 return REMAT_COST_LIMIT;
585         }
586
587         argremats = 0;
588         for(i = 0, arity = get_irn_arity(spilled); i < arity; ++i) {
589                 ir_node *arg = get_irn_n(spilled, i);
590
591                 if(is_value_available(env, arg, reloader))
592                         continue;
593
594                 // we have to rematerialize the argument as well...
595                 if(argremats >= 1) {
596                         /* we only support rematerializing 1 argument at the moment,
597                          * so that we don't have to care about register pressure
598                          */
599                         return REMAT_COST_LIMIT;
600                 }
601                 argremats++;
602
603                 costs += check_remat_conditions_costs(env, arg, reloader, parentcosts + costs);
604                 if(parentcosts + costs >= REMAT_COST_LIMIT)
605                         return REMAT_COST_LIMIT;
606         }
607
608         return costs;
609 }
610
611 static int check_remat_conditions(spill_env_t *env, ir_node *spilled, ir_node *reloader) {
612         int costs = check_remat_conditions_costs(env, spilled, reloader, 0);
613
614         return costs < REMAT_COST_LIMIT;
615 }
616
617 /**
618  * Re-materialize a node.
619  *
620  * @param senv      the spill environment
621  * @param spilled   the node that was spilled
622  * @param reloader  a irn that requires a reload
623  */
624 static ir_node *do_remat(spill_env_t *env, ir_node *spilled, ir_node *reloader) {
625         int i, arity;
626         ir_node *res;
627         ir_node *bl;
628         ir_node **ins;
629
630         if(is_Block(reloader)) {
631                 bl = reloader;
632         } else {
633                 bl = get_nodes_block(reloader);
634         }
635
636         ins = alloca(get_irn_arity(spilled) * sizeof(ins[0]));
637         for(i = 0, arity = get_irn_arity(spilled); i < arity; ++i) {
638                 ir_node *arg = get_irn_n(spilled, i);
639
640                 if(is_value_available(env, arg, reloader)) {
641                         ins[i] = arg;
642                 } else {
643                         ins[i] = do_remat(env, arg, reloader);
644                 }
645         }
646
647         /* create a copy of the node */
648         res = new_ir_node(get_irn_dbg_info(spilled), env->irg, bl,
649                 get_irn_op(spilled),
650                 get_irn_mode(spilled),
651                 get_irn_arity(spilled),
652                 ins);
653         copy_node_attr(spilled, res);
654         new_backedge_info(res);
655         sched_reset(res);
656
657         DBG((env->dbg, LEVEL_1, "Insert remat %+F of %+F before reloader %+F\n", res, spilled, reloader));
658
659         /* insert in schedule */
660         sched_add_before(reloader, res);
661
662         return res;
663 }
664
665 int be_get_reload_costs(spill_env_t *env, ir_node *to_spill, ir_node *before) {
666         spill_info_t *spill_info;
667
668         if(be_do_remats) {
669                 // is the node rematerializable?
670                 int costs = check_remat_conditions_costs(env, to_spill, before, 0);
671                 if(costs < REMAT_COST_LIMIT)
672                         return costs;
673         }
674
675         // do we already have a spill?
676         spill_info = find_spillinfo(env, to_spill);
677         if(spill_info != NULL && spill_info->spill != NULL)
678                 return env->reload_cost;
679
680         return env->spill_cost + env->reload_cost;
681 }
682
683 int be_get_reload_costs_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *block, int pos) {
684         ir_node *before = get_block_insertion_point(block, pos);
685         return be_get_reload_costs(env, to_spill, before);
686 }
687
688 /*
689  *  ___                     _     ____      _                 _
690  * |_ _|_ __  ___  ___ _ __| |_  |  _ \ ___| | ___   __ _  __| |___
691  *  | || '_ \/ __|/ _ \ '__| __| | |_) / _ \ |/ _ \ / _` |/ _` / __|
692  *  | || | | \__ \  __/ |  | |_  |  _ <  __/ | (_) | (_| | (_| \__ \
693  * |___|_| |_|___/\___|_|   \__| |_| \_\___|_|\___/ \__,_|\__,_|___/
694  *
695  */
696
697 void be_insert_spills_reloads(spill_env_t *env) {
698         const arch_env_t *arch_env = env->arch_env;
699         int              remats    = 0;
700         int              reloads   = 0;
701         int              spills    = 0;
702         spill_info_t     *si;
703         ir_nodeset_iterator_t iter;
704         ir_node          *node;
705
706         /* create all phi-ms first, this is needed so, that phis, hanging on
707            spilled phis work correctly */
708         foreach_ir_nodeset(&env->mem_phis, node, iter) {
709                 spill_info_t *info = get_spillinfo(env, node);
710                 spill_node(env, info);
711         }
712
713         /* process each spilled node */
714         for (si = set_first(env->spills); si; si = set_next(env->spills)) {
715                 reloader_t *rld;
716                 ir_node *spilled_node = si->spilled_node;
717                 ir_mode         *mode = get_irn_mode(spilled_node);
718                 ir_node      **copies = NEW_ARR_F(ir_node*, 0);
719
720                 DBG((env->dbg, LEVEL_1, "\nhandling all reloaders of %+F:\n", spilled_node));
721
722                 /* go through all reloads for this spill */
723                 for (rld = si->reloaders; rld; rld = rld->next) {
724                         ir_node *copy; /* a reload is a "copy" of the original value */
725
726                         if (rld->rematted_node != NULL) {
727                                 copy = rld->rematted_node;
728                                 remats++;
729                                 sched_add_before(rld->reloader, copy);
730                         } else if (be_do_remats && rld->allow_remat &&
731                                         check_remat_conditions(env, spilled_node, rld->reloader)) {
732                                 copy = do_remat(env, spilled_node, rld->reloader);
733                                 remats++;
734                         } else {
735                                 /* make sure we have a spill */
736                                 if (si->spill == NULL) {
737                                         spill_node(env, si);
738                                         spills++;
739                                 }
740
741                                 /* create a reload */
742                                 copy = be_reload(arch_env, si->reload_cls, rld->reloader, mode, si->spill);
743                                 reloads++;
744                         }
745
746                         DBG((env->dbg, LEVEL_1, " %+F of %+F before %+F\n",
747                              copy, spilled_node, rld->reloader));
748                         ARR_APP1(ir_node*, copies, copy);
749                 }
750
751                 /* if we had any reloads or remats, then we need to reconstruct the
752                  * SSA form for the spilled value */
753                 if (ARR_LEN(copies) > 0) {
754                         be_ssa_construction_env_t senv;
755                         /* be_lv_t *lv = be_get_birg_liveness(env->birg); */
756
757                         be_ssa_construction_init(&senv, env->birg);
758                         be_ssa_construction_add_copy(&senv, spilled_node);
759                         be_ssa_construction_add_copies(&senv, copies, ARR_LEN(copies));
760                         be_ssa_construction_fix_users(&senv, spilled_node);
761
762 #if 0
763                         /* no need to enable this as long as we invalidate liveness
764                            after this function... */
765                         be_ssa_construction_update_liveness_phis(&senv);
766                         be_liveness_update(spilled_node);
767                         len = ARR_LEN(copies);
768                         for(i = 0; i < len; ++i) {
769                                 be_liveness_update(lv, copies[i]);
770                         }
771 #endif
772                         be_ssa_construction_destroy(&senv);
773                 }
774
775                 DEL_ARR_F(copies);
776                 si->reloaders = NULL;
777         }
778
779 #ifdef FIRM_STATISTICS
780         if (be_stat_ev_is_active()) {
781                 be_stat_ev("spill_spills", spills);
782                 be_stat_ev("spill_reloads", reloads);
783                 be_stat_ev("spill_remats", remats);
784         }
785 #endif /* FIRM_STATISTICS */
786
787         be_remove_dead_nodes_from_schedule(env->irg);
788         /* Matze: In theory be_ssa_construction should take care of the liveness...
789          * try to disable this again in the future */
790         be_invalidate_liveness(env->birg);
791 }