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