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