belive: move dumper to bedump, checker to beverify
[libfirm] / ir / be / belive.c
1 /*
2  * Copyright (C) 1995-2008 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       Interblock liveness analysis.
23  * @author      Sebastian Hack
24  * @date        06.12.2004
25  */
26 #include "config.h"
27
28 /* statev is expensive here, only enable when needed */
29 #define DISABLE_STATEV
30
31 #include "iredges_t.h"
32 #include "irgwalk.h"
33 #include "irprintf_t.h"
34 #include "irdump_t.h"
35 #include "irnodeset.h"
36
37 #include "dfs_t.h"
38 #include "absgraph.h"
39 #include "statev.h"
40
41 #include "beutil.h"
42 #include "belive_t.h"
43 #include "beirg.h"
44 #include "besched.h"
45 #include "bemodule.h"
46 #include "bedump.h"
47
48 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
49
50 #define LV_STD_SIZE             64
51
52 /* if defined, use binary search for already live nodes, else linear */
53 #define LV_USE_BINARY_SEARCH
54 #undef  LV_INTESIVE_CHECKS
55
56 void be_live_chk_compare(be_lv_t *lv, lv_chk_t *lvc);
57
58 /**
59  * Filter out some nodes for which we never need liveness.
60  *
61  * @param irn  the node t check
62  * @return 0 if no liveness info is needed, 1 else
63  */
64 static inline int is_liveness_node(const ir_node *irn)
65 {
66         switch (get_irn_opcode(irn)) {
67         case iro_Block:
68         case iro_Bad:
69         case iro_End:
70         case iro_Anchor:
71         case iro_NoMem:
72                 return 0;
73         default:
74                 return 1;
75         }
76 }
77
78 int (be_is_live_in)(const be_lv_t *lv, const ir_node *block, const ir_node *irn)
79 {
80         return _be_is_live_xxx(lv, block, irn, be_lv_state_in);
81 }
82
83 int (be_is_live_out)(const be_lv_t *lv, const ir_node *block, const ir_node *irn)
84 {
85         return _be_is_live_xxx(lv, block, irn, be_lv_state_out);
86 }
87
88 int (be_is_live_end)(const be_lv_t *lv, const ir_node *block, const ir_node *irn)
89 {
90         return _be_is_live_xxx(lv, block, irn, be_lv_state_end);
91 }
92
93
94 #ifdef LV_USE_BINARY_SEARCH
95 static inline unsigned _be_liveness_bsearch(be_lv_info_t *arr, unsigned idx)
96 {
97         be_lv_info_t *payload = arr + 1;
98
99         unsigned n   = arr[0].head.n_members;
100         unsigned res = 0;
101         int lo       = 0;
102         int hi       = n;
103
104         if (n == 0)
105                 return 0;
106
107         do {
108                 int md          = lo + ((hi - lo) >> 1);
109                 unsigned md_idx = payload[md].node.idx;
110
111                 if (idx > md_idx)
112                         lo = md + 1;
113                 else if (idx < md_idx)
114                         hi = md;
115                 else {
116                         res = md;
117                         assert(payload[res].node.idx == idx);
118                         break;
119                 }
120
121                 res = lo;
122         } while (lo < hi);
123
124 #ifdef LV_INTESIVE_CHECKS
125         {
126                 unsigned i;
127                 for (i = res; i < n; ++i)
128                         assert(payload[i].node.idx >= idx);
129
130                 for (i = 0; i < res; ++i)
131                         assert(payload[i].node.idx < idx);
132         }
133 #endif
134
135         return res;
136 }
137
138 #else
139
140 /**
141  * This function searches linearly for the node in the array.
142  */
143 static inline unsigned _be_liveness_bsearch(be_lv_info_t *arr, unsigned idx)
144 {
145         unsigned n  = arr[0].head.n_members;
146         unsigned i;
147
148         for (i = 0; i < n; ++i) {
149                 if (arr[i + 1].node.idx == idx)
150                         return i;
151         }
152
153         return i;
154 }
155 #endif
156
157 be_lv_info_node_t *be_lv_get(const be_lv_t *li, const ir_node *bl,
158                              const ir_node *irn)
159 {
160         be_lv_info_t *irn_live;
161         be_lv_info_node_t *res = NULL;
162
163         stat_ev_tim_push();
164         irn_live = (be_lv_info_t*)ir_nodehashmap_get(&li->map, bl);
165         if (irn_live != NULL) {
166                 unsigned idx = get_irn_idx(irn);
167
168                 /* Get the position of the index in the array. */
169                 int pos = _be_liveness_bsearch(irn_live, idx);
170
171                 /* Get the record in question. 1 must be added, since the first record contains information about the array and must be skipped. */
172                 be_lv_info_node_t *rec = &irn_live[pos + 1].node;
173
174                 /* Check, if the irn is in deed in the array. */
175                 if (rec->idx == idx)
176                         res = rec;
177         }
178         stat_ev_tim_pop("be_lv_get");
179
180         return res;
181 }
182
183 static be_lv_info_node_t *be_lv_get_or_set(be_lv_t *li, ir_node *bl,
184                                            ir_node *irn)
185 {
186         be_lv_info_t *irn_live = (be_lv_info_t*)ir_nodehashmap_get(&li->map, bl);
187         if (irn_live == NULL) {
188                 irn_live = OALLOCNZ(&li->obst, be_lv_info_t, LV_STD_SIZE);
189                 irn_live[0].head.n_size = LV_STD_SIZE-1;
190                 ir_nodehashmap_insert(&li->map, bl, irn_live);
191         }
192
193         unsigned idx = get_irn_idx(irn);
194
195         /* Get the position of the index in the array. */
196         unsigned pos = _be_liveness_bsearch(irn_live, idx);
197
198         /* Get the record in question. 1 must be added, since the first record contains information about the array and must be skipped. */
199         be_lv_info_node_t *res = &irn_live[pos + 1].node;
200
201         /* Check, if the irn is in deed in the array. */
202         if (res->idx != idx) {
203                 be_lv_info_t *payload;
204                 unsigned n_members = irn_live[0].head.n_members;
205                 unsigned n_size    = irn_live[0].head.n_size;
206                 unsigned i;
207
208                 if (n_members + 1 >= n_size) {
209                         /* double the array size. Remember that the first entry is
210                          * metadata about the array and not a real array element */
211                         unsigned old_size_bytes  = (n_size + 1) * sizeof(irn_live[0]);
212                         unsigned new_size        = (2 * n_size) + 1;
213                         size_t   new_size_bytes  = new_size * sizeof(irn_live[0]);
214                         be_lv_info_t *nw = OALLOCN(&li->obst, be_lv_info_t, new_size);
215                         memcpy(nw, irn_live, old_size_bytes);
216                         memset(((char*) nw) + old_size_bytes, 0,
217                                new_size_bytes - old_size_bytes);
218                         nw[0].head.n_size = new_size - 1;
219                         irn_live = nw;
220                         ir_nodehashmap_insert(&li->map, bl, nw);
221                 }
222
223                 payload = &irn_live[1];
224                 for (i = n_members; i > pos; --i) {
225                         payload[i] = payload[i - 1];
226                 }
227
228                 ++irn_live[0].head.n_members;
229
230                 res = &payload[pos].node;
231                 res->idx    = idx;
232                 res->flags  = 0;
233         }
234
235 #ifdef LV_INTESIVE_CHECKS
236         {
237                 unsigned i;
238                 unsigned n = irn_live[0].head.n_members;
239                 unsigned last = 0;
240                 be_lv_info_t *payload = &irn_live[1];
241
242                 for (i = 0; i < n; ++i) {
243                         assert(payload[i].node.idx >= last);
244                         last = payload[i].node.idx;
245                 }
246         }
247 #endif
248
249         return res;
250 }
251
252 /**
253  * Removes a node from the list of live variables of a block.
254  * @return 1 if the node was live at that block, 0 if not.
255  */
256 static int be_lv_remove(be_lv_t *li, const ir_node *bl,
257                         const ir_node *irn)
258 {
259         be_lv_info_t *irn_live = (be_lv_info_t*)ir_nodehashmap_get(&li->map, bl);
260
261         if (irn_live != NULL) {
262                 unsigned n   = irn_live[0].head.n_members;
263                 unsigned idx = get_irn_idx(irn);
264                 unsigned pos = _be_liveness_bsearch(irn_live, idx);
265                 be_lv_info_t *payload  = irn_live + 1;
266                 be_lv_info_node_t *res = &payload[pos].node;
267
268                 /* The node is in deed in the block's array. Let's remove it. */
269                 if (res->idx == idx) {
270                         unsigned i;
271
272                         for (i = pos + 1; i < n; ++i)
273                                 payload[i - 1] = payload[i];
274
275                         payload[n - 1].node.idx   = 0;
276                         payload[n - 1].node.flags = 0;
277
278                         --irn_live[0].head.n_members;
279                         DBG((dbg, LEVEL_3, "\tdeleting %+F from %+F at pos %d\n", irn, bl, pos));
280                         return 1;
281                 }
282         }
283
284         return 0;
285 }
286
287 static void register_node(be_lv_t *lv, const ir_node *irn)
288 {
289         unsigned idx = get_irn_idx(irn);
290         if (idx >= bitset_size(lv->nodes)) {
291                 bitset_t *nw = bitset_malloc(2 * idx);
292                 bitset_copy_into(nw, lv->nodes);
293                 bitset_free(lv->nodes);
294                 lv->nodes = nw;
295         }
296
297         bitset_set(lv->nodes, idx);
298 }
299
300 /**
301  * Mark a node as live-in in a block.
302  */
303 static inline void mark_live_in(be_lv_t *lv, ir_node *block, ir_node *irn)
304 {
305         be_lv_info_node_t *n = be_lv_get_or_set(lv, block, irn);
306         DBG((dbg, LEVEL_2, "marking %+F live in at %+F\n", irn, block));
307         n->flags |= be_lv_state_in;
308         register_node(lv, irn);
309 }
310
311 /**
312  * Mark a node as live-out in a block.
313  */
314 static inline void mark_live_out(be_lv_t *lv, ir_node *block, ir_node *irn)
315 {
316         be_lv_info_node_t *n = be_lv_get_or_set(lv, block, irn);
317         DBG((dbg, LEVEL_2, "marking %+F live out at %+F\n", irn, block));
318         n->flags |= be_lv_state_out | be_lv_state_end;
319         register_node(lv, irn);
320 }
321
322 /**
323  * Mark a node as live-end in a block.
324  */
325 static inline void mark_live_end(be_lv_t *lv, ir_node *block, ir_node *irn)
326 {
327         be_lv_info_node_t *n = be_lv_get_or_set(lv, block, irn);
328         DBG((dbg, LEVEL_2, "marking %+F live end at %+F\n", irn, block));
329         n->flags |= be_lv_state_end;
330         register_node(lv, irn);
331 }
332
333 static struct {
334         be_lv_t  *lv;         /**< The liveness object. */
335         ir_node  *def;        /**< The node (value). */
336         ir_node  *def_block;  /**< The block of def. */
337         bitset_t *visited;    /**< A set were all visited blocks are recorded. */
338 } re;
339
340 /**
341  * Mark a node (value) live out at a certain block. Do this also
342  * transitively, i.e. if the block is not the block of the value's
343  * definition, all predecessors are also marked live.
344  * @param block The block to mark the value live out of.
345  * @param is_true_out Is the node real out there or only live at the end
346  * of the block.
347  */
348 static void live_end_at_block(ir_node *block, int is_true_out)
349 {
350         be_lv_t *lv  = re.lv;
351         ir_node *def = re.def;
352         bitset_t *visited;
353
354         mark_live_end(lv, block, def);
355         if (is_true_out)
356                 mark_live_out(lv, block, def);
357
358         visited = re.visited;
359         if (!bitset_is_set(visited, get_irn_idx(block))) {
360                 bitset_set(visited, get_irn_idx(block));
361
362                 /*
363                  * If this block is not the definition block, we have to go up
364                  * further.
365                  */
366                 if (re.def_block != block) {
367                         int i;
368
369                         mark_live_in(lv, block, def);
370
371                         for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i)
372                                 live_end_at_block(get_Block_cfgpred_block(block, i), 1);
373                 }
374         }
375 }
376
377 typedef struct lv_remove_walker_t {
378         be_lv_t       *lv;
379         const ir_node *irn;
380 } lv_remove_walker_t;
381
382
383 /**
384  * Liveness analysis for a value.
385  * Compute the set of all blocks a value is live in.
386  * @param irn     The node (value).
387  */
388 static void liveness_for_node(ir_node *irn)
389 {
390         const ir_edge_t *edge;
391         ir_node *def_block;
392
393         bitset_clear_all(re.visited);
394         def_block = get_nodes_block(irn);
395
396         re.def       = irn;
397         re.def_block = def_block;
398
399         /* Go over all uses of the value */
400         foreach_out_edge(irn, edge) {
401                 ir_node *use = edge->src;
402                 ir_node *use_block;
403
404                 DBG((dbg, LEVEL_4, "%+F: use at %+F, pos %d in %+F\n", irn, use, edge->pos, get_block(use)));
405                 assert(get_irn_n(use, edge->pos) == irn);
406
407                 /*
408                  * If the usage is no data node, skip this use, since it does not
409                  * affect the liveness of the node.
410                  */
411                 if (!is_liveness_node(use))
412                         continue;
413
414                 /* Get the block where the usage is in. */
415                 use_block = get_nodes_block(use);
416
417                 /*
418                  * If the use is a phi function, determine the corresponding block
419                  * through which the value reaches the phi function and mark the
420                  * value as live out of that block.
421                  */
422                 if (is_Phi(use)) {
423                         ir_node *pred_block = get_Block_cfgpred_block(use_block, edge->pos);
424                         live_end_at_block(pred_block, 0);
425                 }
426
427                 /*
428                  * Else, the value is live in at this block. Mark it and call live
429                  * out on the predecessors.
430                  */
431                 else if (def_block != use_block) {
432                         int i;
433
434                         mark_live_in(re.lv, use_block, irn);
435
436                         for (i = get_Block_n_cfgpreds(use_block) - 1; i >= 0; --i) {
437                                 ir_node *pred_block = get_Block_cfgpred_block(use_block, i);
438                                 live_end_at_block(pred_block, 1);
439                         }
440                 }
441         }
442 }
443
444 static void lv_remove_irn_walker(ir_node *bl, void *data)
445 {
446         lv_remove_walker_t *w = (lv_remove_walker_t*)data;
447         be_lv_remove(w->lv, bl, w->irn);
448 }
449
450 /**
451  * Walker, collect all nodes for which we want calculate liveness info
452  * on an obstack.
453  */
454 static void collect_liveness_nodes(ir_node *irn, void *data)
455 {
456         ir_node **nodes = (ir_node**)data;
457         if (is_liveness_node(irn))
458                 nodes[get_irn_idx(irn)] = irn;
459 }
460
461 static void compute_liveness(be_lv_t *lv)
462 {
463         ir_node **nodes;
464         int i, n;
465
466         stat_ev_tim_push();
467         n = get_irg_last_idx(lv->irg);
468         nodes = NEW_ARR_F(ir_node *, n);
469         memset(nodes, 0, sizeof(nodes[0]) * n);
470
471         /*
472          * inserting the variables sorted by their ID is probably
473          * more efficient since the binary sorted set insertion
474          * will not need to move around the data.
475          */
476         irg_walk_graph(lv->irg, NULL, collect_liveness_nodes, nodes);
477
478         re.lv      = lv;
479         re.visited = bitset_malloc(n);
480
481         for (i = 0; i < n; ++i) {
482                 if (nodes[i] != NULL)
483                         liveness_for_node(nodes[i]);
484         }
485
486         DEL_ARR_F(nodes);
487         free(re.visited);
488         register_hook(hook_node_info, &lv->hook_info);
489         stat_ev_tim_pop("be_lv_sets_cons");
490 }
491
492 void be_liveness_assure_sets(be_lv_t *lv)
493 {
494         if (!lv->nodes) {
495                 be_timer_push(T_LIVE);
496
497                 lv->nodes = bitset_malloc(2 * get_irg_last_idx(lv->irg));
498                 ir_nodehashmap_init(&lv->map);
499                 obstack_init(&lv->obst);
500                 compute_liveness(lv);
501                 /* be_live_chk_compare(lv, lv->lvc); */
502
503                 be_timer_pop(T_LIVE);
504         }
505 }
506
507 void be_liveness_assure_chk(be_lv_t *lv)
508 {
509 #ifndef USE_LIVE_CHK
510         be_timer_push(t_verify);
511         be_liveness_assure_sets(lv);
512         be_timer_pop(t_verify);
513 #else
514         (void) lv;
515 #endif
516 }
517
518 void be_liveness_invalidate(be_lv_t *lv)
519 {
520         if (lv && lv->nodes) {
521                 unregister_hook(hook_node_info, &lv->hook_info);
522                 obstack_free(&lv->obst, NULL);
523                 ir_nodehashmap_destroy(&lv->map);
524                 bitset_free(lv->nodes);
525                 lv->nodes = NULL;
526         }
527 }
528
529 /* Compute the inter block liveness for a graph. */
530 be_lv_t *be_liveness(ir_graph *irg)
531 {
532         be_lv_t *lv = XMALLOCZ(be_lv_t);
533
534         lv->irg  = irg;
535 #ifdef USE_LIVE_CHK
536         lv->dfs  = dfs_new(&absgraph_irg_cfg_succ, irg);
537         lv->lvc  = lv_chk_new(lv->irg, lv->dfs);
538 #endif
539         lv->hook_info.context = lv;
540         lv->hook_info.hook._hook_node_info = be_dump_liveness_block;
541
542         return lv;
543 }
544
545 void be_liveness_recompute(be_lv_t *lv)
546 {
547         unsigned last_idx;
548
549         be_timer_push(T_LIVE);
550         last_idx = get_irg_last_idx(lv->irg);
551         if (last_idx >= bitset_size(lv->nodes)) {
552                 bitset_free(lv->nodes);
553                 lv->nodes = bitset_malloc(last_idx * 2);
554         } else
555                 bitset_clear_all(lv->nodes);
556
557         ir_nodehashmap_destroy(&lv->map);
558         obstack_free(&lv->obst, NULL);
559
560         ir_nodehashmap_init(&lv->map);
561         obstack_init(&lv->obst);
562         compute_liveness(lv);
563
564         be_timer_pop(T_LIVE);
565 }
566
567
568 void be_liveness_free(be_lv_t *lv)
569 {
570         be_liveness_invalidate(lv);
571 #ifdef USE_LIVE_CHK
572         lv_chk_free(lv->lvc);
573         dfs_free(lv->dfs);
574 #endif
575         xfree(lv);
576 }
577
578 void be_liveness_remove(be_lv_t *lv, const ir_node *irn)
579 {
580         if (lv->nodes) {
581                 unsigned idx = get_irn_idx(irn);
582                 lv_remove_walker_t w;
583
584                 /*
585                  * Removes a single irn from the liveness information.
586                  * Since an irn can only be live at blocks dominated by the block of its
587                  * definition, we only have to process that dominance subtree.
588                  */
589                 w.lv  = lv;
590                 w.irn = irn;
591                 dom_tree_walk(get_nodes_block(irn), lv_remove_irn_walker, NULL, &w);
592                 if (idx < bitset_size(lv->nodes))
593                         bitset_clear(lv->nodes, idx);
594         }
595 }
596
597 void be_liveness_introduce(be_lv_t *lv, ir_node *irn)
598 {
599         /* Don't compute liveness information for non-data nodes. */
600         if (lv->nodes && is_liveness_node(irn)) {
601                 re.lv      = lv;
602                 re.visited = bitset_malloc(get_irg_last_idx(lv->irg));
603                 liveness_for_node(irn);
604                 bitset_free(re.visited);
605         }
606 }
607
608 void be_liveness_update(be_lv_t *lv, ir_node *irn)
609 {
610         be_liveness_remove(lv, irn);
611         be_liveness_introduce(lv, irn);
612 }
613
614 void be_liveness_transfer(const arch_register_class_t *cls,
615                           ir_node *node, ir_nodeset_t *nodeset)
616 {
617         int i, arity;
618
619         /* You should better break out of your loop when hitting the first phi
620          * function. */
621         assert(!is_Phi(node) && "liveness_transfer produces invalid results for phi nodes");
622
623         if (get_irn_mode(node) == mode_T) {
624                 const ir_edge_t *edge;
625
626                 foreach_out_edge(node, edge) {
627                         ir_node *proj = get_edge_src_irn(edge);
628
629                         if (arch_irn_consider_in_reg_alloc(cls, proj)) {
630                                 ir_nodeset_remove(nodeset, proj);
631                         }
632                 }
633         } else if (arch_irn_consider_in_reg_alloc(cls, node)) {
634                 ir_nodeset_remove(nodeset, node);
635         }
636
637         arity = get_irn_arity(node);
638         for (i = 0; i < arity; ++i) {
639                 ir_node *op = get_irn_n(node, i);
640
641                 if (arch_irn_consider_in_reg_alloc(cls, op))
642                         ir_nodeset_insert(nodeset, op);
643         }
644 }
645
646
647
648 void be_liveness_end_of_block(const be_lv_t *lv,
649                               const arch_register_class_t *cls,
650                               const ir_node *block, ir_nodeset_t *live)
651 {
652         int i;
653
654         assert(lv->nodes && "live sets must be computed");
655         be_lv_foreach(lv, block, be_lv_state_end, i) {
656                 ir_node *node = be_lv_get_irn(lv, block, i);
657                 if (!arch_irn_consider_in_reg_alloc(cls, node))
658                         continue;
659
660                 ir_nodeset_insert(live, node);
661         }
662 }
663
664
665
666 void be_liveness_nodes_live_at(const be_lv_t *lv,
667                                const arch_register_class_t *cls,
668                                const ir_node *pos, ir_nodeset_t *live)
669 {
670         const ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
671         ir_node *irn;
672
673         be_liveness_end_of_block(lv, cls, bl, live);
674         sched_foreach_reverse(bl, irn) {
675                 /*
676                  * If we encounter the node we want to insert the Perm after,
677                  * exit immediately, so that this node is still live
678                  */
679                 if (irn == pos)
680                         return;
681
682                 be_liveness_transfer(cls, irn, live);
683         }
684 }
685
686 static void collect_node(ir_node *irn, void *data)
687 {
688         struct obstack *obst = (struct obstack*)data;
689         obstack_ptr_grow(obst, irn);
690 }
691
692 void be_live_chk_compare(be_lv_t *lv, lv_chk_t *lvc)
693 {
694         ir_graph *irg    = lv->irg;
695
696         struct obstack obst;
697         ir_node **nodes;
698         ir_node **blocks;
699         int i, j;
700
701         obstack_init(&obst);
702
703         irg_block_walk_graph(irg, collect_node, NULL, &obst);
704         obstack_ptr_grow(&obst, NULL);
705         blocks = (ir_node**)obstack_finish(&obst);
706
707         irg_walk_graph(irg, collect_node, NULL, &obst);
708         obstack_ptr_grow(&obst, NULL);
709         nodes = (ir_node**)obstack_finish(&obst);
710
711         stat_ev_ctx_push("be_lv_chk_compare");
712         for (j = 0; nodes[j]; ++j) {
713                 ir_node *irn = nodes[j];
714                 if (is_Block(irn))
715                         continue;
716
717                 for (i = 0; blocks[i]; ++i) {
718                         ir_node *bl = blocks[i];
719                         int lvr_in  = be_is_live_in (lv, bl, irn);
720                         int lvr_out = be_is_live_out(lv, bl, irn);
721                         int lvr_end = be_is_live_end(lv, bl, irn);
722
723                         int lvc_in  = lv_chk_bl_in (lvc, bl, irn);
724                         int lvc_out = lv_chk_bl_out(lvc, bl, irn);
725                         int lvc_end = lv_chk_bl_end(lvc, bl, irn);
726
727                         if (lvr_in - lvc_in != 0)
728                                 ir_fprintf(stderr, "live in  info for %+F at %+F differs: nml: %d, chk: %d\n", irn, bl, lvr_in, lvc_in);
729
730                         if (lvr_end - lvc_end != 0)
731                                 ir_fprintf(stderr, "live end info for %+F at %+F differs: nml: %d, chk: %d\n", irn, bl, lvr_end, lvc_end);
732
733                         if (lvr_out - lvc_out != 0)
734                                 ir_fprintf(stderr, "live out info for %+F at %+F differs: nml: %d, chk: %d\n", irn, bl, lvr_out, lvc_out);
735                 }
736         }
737         stat_ev_ctx_pop("be_lv_chk_compare");
738
739         obstack_free(&obst, NULL);
740 }
741
742 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_live)
743 void be_init_live(void)
744 {
745         FIRM_DBG_REGISTER(dbg, "firm.be.liveness");
746 }