Changed to the new infrastructure
[libfirm] / ir / be / bespillilp.c
1 /**
2  * @file   bespillilp.c
3  * @date   15.07.2005
4  * @author Sebastian Hack
5  *
6  * ILP based spilling
7  *
8  * Copyright (C) 2005 Universitaet Karlsruhe
9  * Released under the GPL
10  */
11 #include <math.h>
12
13 #include "hashptr.h"
14 #include "debug.h"
15 #include "obst.h"
16 #include "set.h"
17 #include "list.h"
18 #include "pmap.h"
19
20 #include "irprintf.h"
21 #include "irgwalk.h"
22 #include "irnode_t.h"
23 #include "ircons_t.h"
24
25 #include <lpp/lpp.h>
26 #include <lpp/lpp_net.h>
27 #include <lpp/lpp_cplex.h>
28
29 #include "be_t.h"
30 #include "belive_t.h"
31 #include "besched_t.h"
32 #include "beirgmod.h"
33 #include "bearch.h"
34 #include "benode_t.h"
35 #include "beutil.h"
36 #include "bespillilp.h"
37
38 #define BIGM 1000.0
39
40 #define MAX(a,b) ((a) > (b) ? (a) : (b))
41
42 #define DBG_LEVEL SET_LEVEL_4
43
44 #define DUMP_SOLUTION
45 #define DUMP_ILP
46 #undef  DUMP_STATS
47
48 #undef  SOLVE_LOCAL
49 #define LPP_SERVER "i44pc52"
50 #define LPP_SOLVER "cplex"
51
52 #define COST_LOAD      10
53 #define COST_STORE     50
54 #define COST_REMAT     (-9)
55
56 #define is_end_of_block_use(lr) (is_Block((lr)->user))
57
58 /**
59  * Reloads on edges.
60  */
61 typedef struct _edge_reload_t {
62         ir_node *irn;
63         ir_node *bl;
64         int pos;
65         int in_mem_var;
66         struct _edge_reload_t *next;
67 } edge_reload_t;
68
69 typedef struct _spill_stat_t {
70         int n_spills;
71         int n_reloads;
72         int n_remat;
73 } spill_stat_t;
74
75 typedef struct _spill_ilp_t {
76         const arch_register_class_t *cls;
77         const be_main_session_env_t *session;
78         firm_dbg_module_t *dbg;
79         lpp_t *lpp;
80         set *irn_use_heads;
81         set *live_ranges;
82         set *first_uses;
83         spill_env_t *senv;
84         edge_reload_t *edges;
85         struct obstack *obst;
86         int enable_store : 1;
87         int enable_remat : 1;
88 } spill_ilp_t;
89
90 typedef struct _live_range_t live_range_t;
91
92 typedef struct _irn_use_head_t {
93         struct list_head head;
94         ir_node *irn;
95         int spill_var;
96         int n_uses;
97         live_range_t *closest_use;
98 } irn_use_head_t;
99
100 struct _live_range_t {
101   struct list_head list;
102         irn_use_head_t *use_head;
103   ir_node *user;
104   ir_node *irn;
105         int pos;
106   int in_mem_var;
107   int is_remat_var;
108 };
109
110 /*
111  * Associates the first use of a live-in in a block
112  * with its live range.
113  */
114 typedef struct _first_use_t {
115         ir_node *bl;
116         ir_node *irn;       /**< A value live in at bl. */
117         live_range_t *lr;   /**< The live range for the first use of irn in bl. */
118 } first_use_t;
119
120
121
122 static int has_reg_class(const spill_ilp_t *si, const ir_node *irn)
123 {
124   return arch_irn_has_reg_class(si->session->main_env->arch_env,
125       irn, arch_pos_make_out(0), si->cls);
126 }
127
128 static int cmp_live_range(const void *a, const void *b, size_t n)
129 {
130   const live_range_t *p = a;
131   const live_range_t *q = b;
132
133   return !(p->user == q->user && p->irn == q->irn && p->pos == q->pos);
134 }
135
136 static int cmp_irn_use_head(const void *a, const void *b, size_t n)
137 {
138   const irn_use_head_t *p = a;
139   const irn_use_head_t *q = b;
140
141         return !(p->irn == q->irn);
142 }
143
144 static int cmp_first_use(const void *a, const void *b, size_t n)
145 {
146   const first_use_t *p = a;
147   const first_use_t *q = b;
148
149   return !(p->irn == q->irn && p->bl == q->bl);
150 }
151
152 static void add_first_use(spill_ilp_t *si, ir_node *bl, ir_node *irn, live_range_t *lr)
153 {
154         first_use_t templ;
155         templ.bl    = bl;
156         templ.irn   = irn;
157         templ.lr    = lr;
158
159         set_insert(si->first_uses, &templ, sizeof(templ),
160                         HASH_COMBINE(HASH_PTR(bl), HASH_PTR(irn)));
161 }
162
163 static live_range_t *get_first_use_lr(spill_ilp_t *si, ir_node *bl, ir_node *irn)
164 {
165         first_use_t *res;
166         first_use_t templ;
167         templ.bl    = bl;
168         templ.irn   = irn;
169
170         res = set_find(si->first_uses, &templ, sizeof(templ),
171                         HASH_COMBINE(HASH_PTR(bl), HASH_PTR(irn)));
172
173         return res ? res->lr : NULL;
174 }
175
176 /**
177  * Checks, if a vertain node can be recomputed at a certain position.
178  * @param si    The spill ILP environment.
179  * @param irn   The node to recompute.
180  * @param live  The nodes live at the place where @p irn shall be
181  *              recomputed.
182  * @return      1, if irn can be recomputed, 0 if not.
183  */
184 static INLINE int can_remat(const spill_ilp_t *si, const ir_node *irn, pset *live)
185 {
186         int i, n;
187   const arch_env_t *arch_env    = si->session->main_env->arch_env;
188         int remat = (arch_irn_get_flags(arch_env, irn) & arch_irn_flags_rematerializable) != 0;
189
190         for(i = 0, n = get_irn_arity(irn); i < n && remat; ++i) {
191                 ir_node *op = get_irn_n(irn, i);
192                 remat &= !has_reg_class(si, op) || pset_find_ptr(live, op);
193         }
194
195         return remat;
196 }
197
198 static live_range_t *get_live_range(spill_ilp_t *si, ir_node *irn, ir_node *user, int pos)
199 {
200   live_range_t lr, *res;
201         irn_use_head_t iuh, *head;
202         int is_new;
203   unsigned hash = HASH_COMBINE(HASH_PTR(irn), HASH_PTR(user));
204
205   lr.user    = user;
206   lr.irn     = irn;
207   lr.pos     = pos;
208   lr.in_mem_var = -1;
209         lr.is_remat_var = -1;
210
211   res = set_insert(si->live_ranges, &lr, sizeof(lr), hash);
212         is_new = res->in_mem_var == -1;
213
214   if(is_new) {
215     char buf[128];
216     ir_snprintf(buf, sizeof(buf), "m_%s%N_%N_%d",
217                                 is_Phi(irn) ? "phi_" : "", irn, user, MAX(pos, 0));
218     res->in_mem_var = lpp_add_var(si->lpp, buf, lpp_binary, pos >= 0 ? COST_LOAD : 0.0);
219   }
220
221         memset(&iuh, 0, sizeof(iuh));
222         iuh.irn = irn;
223         iuh.n_uses = -1;
224         head = set_insert(si->irn_use_heads, &iuh, sizeof(iuh), HASH_PTR(irn));
225         if(head->n_uses == -1) {
226                 head->n_uses = 0;
227                 INIT_LIST_HEAD(&head->head);
228         }
229
230         if(is_new) {
231                 list_add_tail(&res->list, &head->head);
232                 head->n_uses++;
233         }
234
235         res->use_head = head;
236
237   return res;
238 }
239
240 static ir_node *process_irn(spill_ilp_t *si, pset *live, ir_node *irn, int *demand)
241 {
242         int i, n;
243         int relevant_args = 0, results = 0;
244
245         DBG((si->dbg, LEVEL_1, "at %+F\n", irn));
246
247         while(is_Proj(irn)) {
248                 if(has_reg_class(si, irn)) {
249                         assert(pset_find_ptr(live, irn) && "node must be live");
250                         pset_remove_ptr(live, irn);
251                         results++;
252                 }
253
254                 DBG((si->dbg, LEVEL_1, "skipped proj %+F\n", irn));
255                 irn = sched_prev(irn);
256         }
257
258         DBG((si->dbg, LEVEL_1, "\tlanded at irn %+F\n", irn));
259
260         if(results > 0)
261                 assert(get_irn_mode(irn) == mode_T && "node before projs must be tuple");
262
263         if(has_reg_class(si, irn)) {
264                 assert( pset_find_ptr(live, irn) && "node must be live");
265                 pset_remove_ptr(live, irn);
266                 results = 1;
267         }
268
269         for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
270                 ir_node *op = get_irn_n(irn, i);
271                 if(has_reg_class(si, op) && !pset_find_ptr(live, op)) {
272                         relevant_args++;
273                         DBG((si->dbg, LEVEL_1, "\trelevant arg %+F\n", op));
274                 }
275         }
276
277         *demand = MAX(results, relevant_args);
278         DBG((si->dbg, LEVEL_1, "\tdemand: %d\n", *demand));
279         return irn;
280 }
281
282 static void process_block(ir_node *bl, void *data)
283 {
284         char buf[128];
285         int i, n;
286   spill_ilp_t *si  = data;
287   int step         = 0;
288   int n_regs       = arch_register_class_n_regs(si->cls);
289         int n_preds      = get_irn_arity(bl);
290   pset *live       = pset_new_ptr_default();
291   irn_live_t *li;
292   ir_node *irn;
293
294   /* as always, bring the live end nodes to life here */
295   live_foreach(bl, li) {
296     if(live_is_end(li) && has_reg_class(si, li->irn)) {
297       ir_node *irn = (ir_node *) li->irn;
298       pset_insert_ptr(live, irn);
299
300       /*
301        * The "user" of the live range to the end of a block
302        * is the block itself. This is quite arbitrary.
303        */
304       set_irn_link(irn, get_live_range(si, irn, bl, -1));
305     }
306   }
307
308         for(irn = sched_last(bl); !sched_is_begin(irn) && !is_Phi(irn); irn = sched_prev(irn)) {
309                 ir_node *l;
310                 int cst;
311                 int demand;
312                 int n_live;
313                 int must_be_in_mem;
314
315                 /* We handle phi togther with live ins after this loop (see below). */
316                 if(is_Phi(irn))
317                         break;
318
319 #if 0
320                 if(has_reg_class(si, irn))
321                         pset_remove_ptr(live, irn);
322
323                 demand = register_demand(si, live, irn);
324                 n_live = pset_count(live);
325 #endif
326
327                 irn = process_irn(si, live, irn, &demand);
328                 n_live = pset_count(live);
329
330                 /*
331                  * Determine, how many values (which are not used at the label)
332                  * must be in memory.
333                  * demand means the number of registers, the operation will consume.
334                  * So there are n_regs - demand registers available to store values
335                  * which are not used at this label. The rest must reside in memory.
336                  */
337                 must_be_in_mem = MAX(n_live + demand - n_regs, 0);
338
339                 DBG((si->dbg, LEVEL_1, "%+F: demand: %d, live: %d, in mem: %d\n",
340                                         irn, demand, n_live, must_be_in_mem));
341
342                 if(must_be_in_mem > 0) {
343
344                         /*
345                          * The constraint limiting the pressure at this label to
346                          * the number of free registers.
347                          */
348                         ir_snprintf(buf, sizeof(buf), "cp_%N_%N_%d", bl, irn, step);
349                         cst = lpp_add_cst(si->lpp, buf, lpp_greater, must_be_in_mem);
350
351                         for(l = pset_first(live); l; l = pset_next(live)) {
352                                 live_range_t *lr = get_irn_link(l);
353                                 lpp_set_factor_fast(si->lpp, cst, lr->in_mem_var, 1.0);
354                         }
355                 }
356
357                 for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
358                         ir_node *op = get_irn_n(irn, i);
359
360                         if(has_reg_class(si, op)) {
361                                 live_range_t *op_lr = get_live_range(si, op, irn, i);
362
363                                 set_irn_link(op, op_lr);
364
365                                 /*
366                                  * The operand is reloaded at its usage, so it must not occur
367                                  * in the constraint which determines which values live at the
368                                  * instruction must reside in memory.
369                                  */
370                                 if(must_be_in_mem > 0)
371                                         lpp_set_factor_fast(si->lpp, cst, op_lr->in_mem_var, 0.0);
372
373                                 /*
374                                  * Check, if the node is a rematerializable node and
375                                  * if its operands are live here.
376                                  */
377                                 if(si->enable_remat && can_remat(si, op, live)) {
378                                         int cst;
379                                         int j, n;
380                                         int n_operands = 0;
381
382                                         for(j = 0, n = get_irn_arity(op); j < n; ++j)
383                                                 n_operands += has_reg_class(si, get_irn_n(op, j));
384
385                                         /* Make the remat constraint for this operand */
386                                         ir_snprintf(buf, sizeof(buf), "ce1_%N_%N_%d", op, irn, i);
387                                         cst = lpp_add_cst(si->lpp, buf, lpp_less, n_operands);
388
389                                         /* Make the rematerialize variable for the operand */
390                                         ir_snprintf(buf, sizeof(buf), "e_%N_%N_%d", op, irn, i);
391                                         op_lr->is_remat_var = lpp_add_var(si->lpp, buf, lpp_binary, COST_REMAT);
392                                         lpp_set_factor_fast(si->lpp, cst, op_lr->is_remat_var, n_operands);
393
394                                         for(j = 0, n = get_irn_arity(op); j < n; ++j) {
395                                                 ir_node *oop = get_irn_n(op, j);
396                                                 if(has_reg_class(si, oop)) {
397                                                         live_range_t *lr = get_irn_link(oop);
398                                                         lpp_set_factor_fast(si->lpp, cst, lr->in_mem_var, 1.0);
399                                                 }
400                                         }
401
402                                         ir_snprintf(buf, sizeof(buf), "ce2_%N_%N_%d", op, irn, i);
403                                         cst = lpp_add_cst(si->lpp, buf, lpp_less, 0.0);
404                                         lpp_set_factor_fast(si->lpp, cst, op_lr->is_remat_var, 1.0);
405                                         lpp_set_factor_fast(si->lpp, cst, op_lr->in_mem_var, -1.0);
406                                 }
407                         }
408                 }
409
410                         for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
411                                 ir_node *op = get_irn_n(irn, i);
412                                 if(has_reg_class(si, op) && !is_Phi(irn))
413                                         pset_insert_ptr(live, op);
414                         }
415
416                 step++;
417         }
418
419         if(bl == get_irg_start_block(get_irn_irg(bl)))
420                 goto end;
421
422         /*
423          * Here, only the phis in the block and the values live in are in the
424          * live set.
425          *
426          * If a value is live in, it must be in a register in all predecessor
427          * blocks or in memory at the end of all predecessor blocks. Also, the
428          * closest use in the current block must then be from register or
429          * memory, respectively.
430          */
431         for(irn = pset_first(live); irn; irn = pset_next(live)) {
432                 live_range_t *lr = get_irn_link(irn);
433                 int is_phi = is_Phi(irn) && get_nodes_block(irn) == bl;
434                 int cst;
435
436                 /* Deprecated: Can be done with the first uses map */
437                 if(is_phi)
438                         lr->use_head->closest_use = lr;
439
440                 /*
441                  * Remind the liverange of the first use of a live (or phi) in the
442                  * current block.
443                  */
444                 add_first_use(si, bl, irn, lr);
445
446                 assert(has_reg_class(si, irn));
447                 assert(is_Phi(irn) || is_live_in(bl, irn));
448
449                 for(i = 0; i < n_preds; ++i) {
450                         ir_node *pred_bl     = get_Block_cfgpred_block(bl, i);
451                         ir_node *end_node    = is_phi ? get_irn_n(irn, i) : irn;
452                         live_range_t *op_lr  = get_live_range(si, end_node, pred_bl, -1);
453                         edge_reload_t *edge  = obstack_alloc(si->obst, sizeof(edge[0]));
454
455                         ir_snprintf(buf, sizeof(buf), "edge_%N_%N_%N_%N",
456                                         bl, pred_bl, end_node, op_lr->irn);
457                         edge->in_mem_var = lpp_add_var(si->lpp, buf, lpp_binary, COST_LOAD);
458                         edge->bl         = bl;
459                         edge->irn        = end_node;
460                         edge->pos        = i;
461
462
463                         ir_snprintf(buf, sizeof(buf), "cedge_%N_%N_%N_%N",
464                                         bl, pred_bl, end_node, op_lr->irn);
465                         cst = lpp_add_cst(si->lpp, buf, lpp_less, 0.0);
466                         lpp_set_factor_fast(si->lpp, cst, op_lr->in_mem_var, 1.0);
467                         lpp_set_factor_fast(si->lpp, cst, lr->in_mem_var, -1.0);
468                         lpp_set_factor_fast(si->lpp, cst, edge->in_mem_var, -1.0);
469                 }
470         }
471
472 end:
473
474   del_pset(live);
475 }
476
477 /**
478  * Add the costs for a store.
479  *
480  * If one of the uses is from memory, add additional costs for the
481  * spill.
482  *
483  * m_1 + ... + m_n - M * s <= 0
484  *
485  * @param si The ILP spilling environment.
486  */
487 static void add_store_costs(spill_ilp_t *si)
488 {
489         char buf[64];
490         irn_use_head_t *uh;
491         double costs = si->enable_store ? COST_STORE : 0.0;
492
493         for(uh = set_first(si->irn_use_heads); uh; uh = set_next(si->irn_use_heads)) {
494                 int cst;
495                 live_range_t *lr;
496
497                 ir_snprintf(buf, sizeof(buf), "cs_%N", uh->irn);
498                 cst = lpp_add_cst(si->lpp, buf, lpp_less, 0);
499
500                 ir_snprintf(buf, sizeof(buf), "s_%N", uh->irn);
501                 uh->spill_var = lpp_add_var(si->lpp, buf, lpp_binary, costs);
502                 lpp_set_factor_fast(si->lpp, cst, uh->spill_var, -BIGM);
503
504     list_for_each_entry(live_range_t, lr, &uh->head, list)
505                         lpp_set_factor_fast(si->lpp, cst, lr->in_mem_var, 1.0);
506         }
507 }
508
509 static INLINE int is_zero(double x)
510 {
511   return fabs(x) < 0.00001;
512 }
513
514 static int is_spilled(const spill_ilp_t *si, const live_range_t *lr)
515 {
516         return !is_zero(lpp_get_var_sol(si->lpp, lr->in_mem_var));
517 }
518
519 static void writeback_results(spill_ilp_t *si)
520 {
521         irn_use_head_t *uh;
522         edge_reload_t *edge;
523         pset *mem_phis = pset_new_ptr_default();
524
525         /* Put all completely spilled phis into the mem_phis set */
526         for(uh = set_first(si->irn_use_heads); uh; uh = set_next(si->irn_use_heads)) {
527                 if(is_Phi(uh->irn) && is_spilled(si, uh->closest_use))
528                         pset_insert_ptr(mem_phis, uh->irn);
529         }
530
531         /* Look at each node and examine the usages. */
532         for(uh = set_first(si->irn_use_heads); uh; uh = set_next(si->irn_use_heads)) {
533                 live_range_t *lr;
534
535                 /* Go through all live ranges of the node. */
536                 list_for_each_entry(live_range_t, lr, &uh->head, list) {
537                         if(is_spilled(si, lr) && !is_end_of_block_use(lr))
538                                 be_add_spill(si->senv, lr->irn, lr->user);
539                 }
540         }
541
542         for(edge = si->edges; edge; edge = edge->next) {
543                 if(!is_zero(edge->in_mem_var))
544                         be_add_spill_on_edge(si->senv, edge->irn, edge->bl, edge->pos);
545         }
546
547         be_insert_spills_reloads(si->senv, mem_phis, NULL);
548         del_pset(mem_phis);
549 }
550
551 void be_spill_ilp(const be_main_session_env_t *session_env,
552     const arch_register_class_t *cls)
553 {
554         char problem_name[256];
555         struct obstack obst;
556         spill_ilp_t si;
557
558         ir_snprintf(problem_name, sizeof(problem_name), "%F_%s", session_env->irg, cls->name);
559
560         obstack_init(&obst);
561         si.session         = session_env;
562         si.obst            = &obst;
563         si.dbg             = firm_dbg_register("be.ra.spillilp");
564         si.senv            = be_new_spill_env(si.dbg, session_env, cls);
565         si.cls             = cls;
566         si.lpp             = new_lpp(problem_name, lpp_minimize);
567         si.irn_use_heads   = new_set(cmp_irn_use_head, 4096);
568         si.live_ranges     = new_set(cmp_live_range, 16384);
569         si.first_uses      = new_set(cmp_first_use, 4096);
570         si.edges           = NULL;
571         si.enable_remat    = 0;
572         si.enable_store    = 0;
573
574         firm_dbg_set_mask(si.dbg, DBG_LEVEL);
575         irg_block_walk_graph(session_env->irg, process_block, NULL, &si);
576         if(si.enable_store)
577                 add_store_costs(&si);
578
579 #ifdef DUMP_ILP
580         {
581                 FILE *f;
582                 char buf[256];
583
584                 ir_snprintf(buf, sizeof(buf), "spill-%s.ilp", problem_name);
585                 if((f = fopen(buf, "wt")) != NULL) {
586                         lpp_dump_plain(si.lpp, f);
587                         fclose(f);
588                 }
589         }
590 #endif
591
592         DBG((si.dbg, LEVEL_1, "%F\n", session_env->irg));
593 #ifdef SOLVE_LOCAL
594         lpp_solve_cplex(si.lpp);
595 #else
596         lpp_solve_net(si.lpp, LPP_SERVER, LPP_SOLVER);
597 #endif
598         assert(lpp_is_sol_valid(si.lpp) && "solution of ILP must be valid");
599
600         DBG((si.dbg, LEVEL_1, "\tnodes: %d, vars: %d, csts: %d\n",
601                                 set_count(si.irn_use_heads), si.lpp->var_next, si.lpp->cst_next));
602         DBG((si.dbg, LEVEL_1, "\titerations: %d, solution time: %g\n",
603                                 si.lpp->iterations, si.lpp->sol_time));
604
605 #ifdef DUMP_SOLUTION
606         {
607                 FILE *f;
608                 char buf[256];
609
610                 ir_snprintf(buf, sizeof(buf), "spill-%s.sol", problem_name);
611                 if((f = fopen(buf, "wt")) != NULL) {
612                         int i;
613                         for(i = 0; i < si.lpp->var_next; ++i) {
614                                 lpp_name_t *name = si.lpp->vars[i];
615                                 fprintf(f, "%20s %4d %10f\n", name->name, name->nr, name->value);
616                         }
617                         fclose(f);
618                 }
619         }
620 #endif
621
622   // writeback_results(&si);
623
624 #ifdef DUMP_STATS
625         {
626                 FILE *f;
627
628                 ir_snprintf(buf, sizeof(buf), "%s-spill.stat", problem_name);
629                 if((f = fopen(buf, "wt")) != NULL) {
630                         fprintf(f, "%20s: %d\n", "nodes", set_count(si.irn_use_heads));
631                         fprintf(f, "%20s: %d\n", "vars", si.lpp->var_next);
632                         fprintf(f, "%20s: %d\n", "csts", si.lpp->cst_next);
633                         fprintf(f, "%20s: %f\n", "sol time", si.lpp->sol_time);
634                         fprintf(f, "%20s: %d\n", "spills", si->stats.n_spills);
635                         fprintf(f, "%20s: %d\n", "reloads", si->stats.n_reloads);
636                         fprintf(f, "%20s: %d\n", "remats", si->stats.n_remat);
637                         fclose(f);
638                 }
639         }
640 #endif
641
642   del_set(si.irn_use_heads);
643   del_set(si.live_ranges);
644   free_lpp(si.lpp);
645   obstack_free(&obst, NULL);
646 }