+ live_end_at_block(pred_block, 0);
+ }
+
+ /*
+ * Else, the value is live in at this block. Mark it and call live
+ * out on the predecessors.
+ */
+ else if (def_block != use_block) {
+ int i;
+
+ mark_live_in(re.lv, use_block, irn);
+
+ for (i = get_Block_n_cfgpreds(use_block) - 1; i >= 0; --i) {
+ ir_node *pred_block = get_Block_cfgpred_block(use_block, i);
+ live_end_at_block(pred_block, 1);
+ }
+ }
+ }
+}
+
+static void lv_remove_irn_walker(ir_node *bl, void *data)
+{
+ lv_remove_walker_t *w = (lv_remove_walker_t*)data;
+ be_lv_remove(w->lv, bl, w->irn);
+}
+
+/**
+ * Walker, collect all nodes for which we want calculate liveness info
+ * on an obstack.
+ */
+static void collect_liveness_nodes(ir_node *irn, void *data)
+{
+ ir_node **nodes = (ir_node**)data;
+ if (is_liveness_node(irn))
+ nodes[get_irn_idx(irn)] = irn;
+}
+
+void be_liveness_compute_sets(be_lv_t *lv)
+{
+ ir_node **nodes;
+ int i;
+ int n;
+
+ if (lv->sets_valid)
+ return;
+
+ be_timer_push(T_LIVE);
+ ir_nodehashmap_init(&lv->map);
+ obstack_init(&lv->obst);
+
+ n = get_irg_last_idx(lv->irg);
+ nodes = NEW_ARR_F(ir_node *, n);
+ memset(nodes, 0, sizeof(nodes[0]) * n);
+
+ /* inserting the variables sorted by their ID is probably
+ * more efficient since the binary sorted set insertion
+ * will not need to move around the data. */
+ irg_walk_graph(lv->irg, NULL, collect_liveness_nodes, nodes);
+
+ re.lv = lv;
+ re.visited = bitset_malloc(n);
+
+ for (i = 0; i < n; ++i) {
+ if (nodes[i] != NULL)
+ liveness_for_node(nodes[i]);
+ }
+
+ DEL_ARR_F(nodes);
+ free(re.visited);
+ register_hook(hook_node_info, &lv->hook_info);
+
+ be_timer_pop(T_LIVE);
+
+ lv->sets_valid = true;
+}
+
+void be_liveness_compute_chk(be_lv_t *lv)
+{
+ if (lv->lvc != NULL)
+ return;
+ lv->lvc = lv_chk_new(lv->irg);
+}
+
+void be_liveness_invalidate_sets(be_lv_t *lv)
+{
+ if (!lv->sets_valid)
+ return;
+ unregister_hook(hook_node_info, &lv->hook_info);
+ obstack_free(&lv->obst, NULL);
+ ir_nodehashmap_destroy(&lv->map);
+ lv->sets_valid = false;
+}