-/**
- * Optimizes jump tables (CondIs or CondIu) by removing all impossible cases.
- */
-static ir_node *transform_node_Proj_Cond(ir_node *proj)
-{
- ir_node *n = get_Proj_pred(proj);
- ir_node *b = get_Cond_selector(n);
-
- if (mode_is_int(get_irn_mode(b))) {
- ir_tarval *tb = value_of(b);
-
- if (tb != tarval_bad) {
- /* we have a constant switch */
- long num = get_Proj_proj(proj);
-
- if (num != get_Cond_default_proj(n)) { /* we cannot optimize default Proj's yet */
- if (get_tarval_long(tb) == num) {
- /* Do NOT create a jump here, or we will have 2 control flow ops
- * in a block. This case is optimized away in optimize_cf(). */
- return proj;
- } else {
- ir_graph *irg = get_irn_irg(proj);
- /* this case will NEVER be taken, kill it */
- clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_CODE);
- return new_r_Bad(irg, mode_X);
- }
- }
- } else {
- long num = get_Proj_proj(proj);
- vrp_attr *b_vrp = vrp_get_info(b);
- if (num != get_Cond_default_proj(n) && b_vrp) {
- /* Try handling with vrp data. We only remove dead parts. */
- ir_tarval *tp = new_tarval_from_long(num, get_irn_mode(b));
-
- if (b_vrp->range_type == VRP_RANGE) {
- ir_relation cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
- ir_relation cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
-
- if ((cmp_result & ir_relation_greater) == cmp_result
- && (cmp_result2 & ir_relation_less) == cmp_result2) {
- ir_graph *irg = get_irn_irg(proj);
- clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_CODE);
- return new_r_Bad(irg, mode_X);
- }
- } else if (b_vrp->range_type == VRP_ANTIRANGE) {
- ir_relation cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
- ir_relation cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
-
- if ((cmp_result & ir_relation_less_equal) == cmp_result
- && (cmp_result2 & ir_relation_greater_equal) == cmp_result2) {
- ir_graph *irg = get_irn_irg(proj);
- clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_CODE);
- return new_r_Bad(irg, mode_X);
- }
- }
-
- if (!(tarval_cmp(
- tarval_and( b_vrp->bits_set, tp),
- b_vrp->bits_set
- ) == ir_relation_equal)) {
- ir_graph *irg = get_irn_irg(proj);
- clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_CODE);
- return new_r_Bad(irg, mode_X);
- }
-
- if (!(tarval_cmp(
- tarval_and(
- tarval_not(tp),
- tarval_not(b_vrp->bits_not_set)),
- tarval_not(b_vrp->bits_not_set))
- == ir_relation_equal)) {
- ir_graph *irg = get_irn_irg(proj);
- clear_irg_state(irg, IR_GRAPH_STATE_NO_UNREACHABLE_CODE);
- return new_r_Bad(irg, mode_X);
- }
- }
- }
- }
- return proj;
-}
-