+ def_bl = get_nodes_block(var);
+ if (def_bl == bl || !block_dominates(def_bl, bl)) {
+ goto end;
+ }
+
+ else {
+ bitset_t *uses = bitset_alloca(lv->n_blocks);
+ bitset_t *tmp = bitset_alloca(lv->n_blocks);
+ int min_dom = get_Block_dom_tree_pre_num(def_bl) + 1;
+ int max_dom = get_Block_dom_max_subtree_pre_num(def_bl);
+ bl_info_t *bli = get_block_info(lv, bl);
+ int i;
+
+ DBG((lv->dbg, LEVEL_2, "lv check of %+F, def=%+F,%d != q=%+F,%d\n",
+ var, def_bl, min_dom - 1, bl, bli->id));
+
+ foreach_out_edge (var, edge) {
+ ir_node *user = get_edge_src_irn(edge);
+ ir_node *use_bl;
+ bl_info_t *bi;
+
+ if (!is_liveness_node(user))
+ continue;
+
+ stat_ev_cnt_inc(uses);
+ use_bl = get_nodes_block(user);
+ if (is_Phi(user)) {
+ int pos = get_edge_src_pos(edge);
+ use_bl = get_Block_cfgpred_block(use_bl, pos);
+ }
+
+ if (use_bl == bl) {
+ res = lv_chk_state_in;
+ DBG((lv->dbg, LEVEL_2, "\tuse directly in block %+F by %+F\n", use_bl, user));
+ goto end;
+ }
+
+ bi = get_block_info(lv, use_bl);
+ bitset_set(uses, bi->id);
+ }
+
+ DBG((lv->dbg, LEVEL_2, "\tuses: %B\n", uses));
+
+ {
+
+ bitset_copy(tmp, bli->be_tgt_reach);
+ bitset_set(tmp, bli->id);
+
+ DBG((lv->dbg, LEVEL_2, "\tbe tgt reach: %B, dom span: [%d, %d]\n", tmp, min_dom, max_dom));
+ for (i = bitset_next_set(tmp, min_dom); i >= 0 && i <= max_dom; i = bitset_next_set(tmp, i + 1)) {
+ bl_info_t *ti = lv->map[i];
+ DBG((lv->dbg, LEVEL_2, "\tlooking from %d: seeing %B\n", ti->id, ti->red_reachable));
+ if (bitset_intersect(ti->red_reachable, uses)) {
+ res = lv_chk_state_in;
+ goto end;
+ }
+
+ bitset_andnot(tmp, ti->red_reachable);
+ }
+ }
+ }
+
+end:
+ return res;
+}
+
+unsigned lv_chk_bl_end_mask(const lv_chk_t *lv, const ir_node *bl, const ir_node *var)
+{
+ stat_ev_cnt_decl(uses);
+
+ ir_node *def_bl;
+ const ir_edge_t *edge;
+
+ int res = 0;
+
+ assert(is_Block(bl) && "can only check for liveness in a block");
+
+ if (!is_liveness_node(var))
+ return 0;
+
+ def_bl = get_nodes_block(var);
+ if (!block_dominates(def_bl, bl)) {
+ goto end;
+ }
+
+ else {
+ bitset_t *uses = bitset_alloca(lv->n_blocks);
+ bitset_t *tmp = bitset_alloca(lv->n_blocks);
+ int min_dom = get_Block_dom_tree_pre_num(def_bl) + 1;
+ int max_dom = get_Block_dom_max_subtree_pre_num(def_bl);
+ bl_info_t *bli = get_block_info(lv, bl);
+ int i;
+
+ DBG((lv->dbg, LEVEL_2, "lv end check of %+F, def=%+F,%d != q=%+F,%d\n",
+ var, def_bl, min_dom - 1, bl, bli->id));
+
+ foreach_out_edge (var, edge) {
+ ir_node *user = get_edge_src_irn(edge);
+ ir_node *use_bl;
+ bl_info_t *bi;
+
+ if (!is_liveness_node(user))
+ continue;
+
+ stat_ev_cnt_inc(uses);
+ use_bl = get_nodes_block(user);
+ if (is_Phi(user)) {
+ int pos = get_edge_src_pos(edge);
+ use_bl = get_Block_cfgpred_block(use_bl, pos);
+
+ if (bl == use_bl)
+ res |= lv_chk_state_end;
+ }
+
+ bi = get_block_info(lv, use_bl);
+ if (use_bl != bl || bitset_is_set(lv->back_edge_tgt, bi->id))
+ bitset_set(uses, bi->id);
+ }
+
+ DBG((lv->dbg, LEVEL_2, "\tuses: %B\n", uses));
+
+ bitset_copy(tmp, bli->be_tgt_reach);
+ bitset_set(tmp, bli->id);
+
+ DBG((lv->dbg, LEVEL_2, "\tbe tgt reach + current: %B, dom span: [%d, %d]\n", tmp, min_dom, max_dom));
+ for (i = bitset_next_set(tmp, min_dom); i >= 0 && i <= max_dom; i = bitset_next_set(tmp, i + 1)) {
+ bl_info_t *ti = lv->map[i];
+ DBG((lv->dbg, LEVEL_2, "\tlooking from %d: seeing %B\n", ti->id, ti->red_reachable));
+ if (bitset_intersect(ti->red_reachable, uses)) {
+ res = lv_chk_state_out | lv_chk_state_end;
+ goto end;
+ }
+
+ bitset_andnot(tmp, ti->red_reachable);
+ }
+ }
+
+end:
+ return res;
+}
+
+/**
+ * Check a nodes liveness situation of a block.
+ * This routine considers both cases, the live in and end/out case.
+ *
+ * @param lv The liveness check environment.
+ * @param bl The block under investigation.
+ * @param var The node to check for.
+ * @return A bitmask of lv_chk_state_XXX fields.
+ */
+unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var)
+{
+ stat_ev_cnt_decl(uses);
+ stat_ev_cnt_decl(iter);
+
+ int res = 0;
+ ir_node *def_bl;
+
+ assert(is_Block(bl) && "can only check for liveness in a block");
+
+ /* If the variable ist no liveness related var, bail out. */
+ if (!is_liveness_node(var))