Set optimisations moved to transform_node_Mux
authorMatthias Braun <matze@braunis.de>
Sat, 5 Nov 2011 11:13:00 +0000 (12:13 +0100)
committerMatthias Braun <matze@braunis.de>
Mon, 7 Nov 2011 10:00:46 +0000 (11:00 +0100)
they were in lower_mode_b but just generically apply to all Mux(c, 0, 1)

ir/ir/iropt.c
ir/lower/lower_mode_b.c

index 2ca74a4..b945b6e 100644 (file)
@@ -4685,7 +4685,7 @@ is_bittest: {
                                        } else {
                                                dbg_info *dbgi  = get_irn_dbg_info(n);
                                                ir_node  *block = get_nodes_block(n);
-                                               ir_node  *notn  =  new_rd_Not(dbgi, block, cond, mode_b);
+                                               ir_node  *notn  = new_rd_Not(dbgi, block, cond, mode_b);
                                                return notn;
                                        }
                                }
@@ -5890,6 +5890,89 @@ bool ir_is_optimizable_mux(const ir_node *sel, const ir_node *mux_false,
        return false;
 }
 
+/**
+ * Optimize a Mux(c, 0, 1) node (sometimes called a "set" instruction)
+ */
+static ir_node *transform_Mux_set(ir_node *n)
+{
+       ir_node    *cond = get_Mux_sel(n);
+       ir_mode    *dest_mode;
+       ir_mode    *mode;
+       ir_node    *left;
+       ir_node    *right;
+       ir_relation relation;
+       bool        need_not;
+       dbg_info   *dbgi;
+       ir_node    *block;
+       ir_graph   *irg;
+       ir_node    *a;
+       ir_node    *b;
+       unsigned    bits;
+       ir_tarval  *tv;
+       ir_node    *shift_cnt;
+       ir_node    *res;
+
+       if (!is_Cmp(cond))
+               return n;
+       left = get_Cmp_left(cond);
+       mode = get_irn_mode(left);
+       if (!mode_is_int(mode) && !mode_is_reference(mode))
+               return n;
+       dest_mode = get_irn_mode(n);
+       right     = get_Cmp_right(cond);
+       relation  = get_Cmp_relation(cond) & ~ir_relation_unordered;
+       if (get_mode_size_bits(mode) >= get_mode_size_bits(dest_mode)
+           && (!mode_is_signed(mode) || !is_Const(right) || !is_Const_null(right)))
+           return n;
+
+       need_not = false;
+       switch (relation) {
+       case ir_relation_less:
+               /* a < b  ->  (a - b) >> 31 */
+               a = left;
+               b = right;
+               break;
+       case ir_relation_less_equal:
+               /* a <= b  -> ~(a - b) >> 31 */
+               a        = right;
+               b        = left;
+               need_not = true;
+               break;
+       case ir_relation_greater:
+               /* a > b   -> (b - a) >> 31 */
+               a = right;
+               b = left;
+               break;
+       case ir_relation_greater_equal:
+               /* a >= b   -> ~(a - b) >> 31 */
+               a        = left;
+               b        = right;
+               need_not = true;
+               break;
+       default:
+               return n;
+       }
+
+       dbgi      = get_irn_dbg_info(n);
+       block     = get_nodes_block(n);
+       irg       = get_irn_irg(block);
+       bits      = get_mode_size_bits(dest_mode);
+       tv        = new_tarval_from_long(bits-1, mode_Iu);
+       shift_cnt = new_rd_Const(dbgi, irg, tv);
+
+       if (mode != dest_mode) {
+               a = new_rd_Conv(dbgi, block, a, dest_mode);
+               b = new_rd_Conv(dbgi, block, b, dest_mode);
+       }
+
+       res = new_rd_Sub(dbgi, block, a, b, dest_mode);
+       if (need_not) {
+               res = new_rd_Not(dbgi, block, res, dest_mode);
+       }
+       res = new_rd_Shr(dbgi, block, res, shift_cnt, dest_mode);
+       return res;
+}
+
 /**
  * Optimize a Mux into some simpler cases.
  */
@@ -5941,6 +6024,12 @@ static ir_node *transform_node_Mux(ir_node *n)
                n = new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode);
        }
 
+       if (is_Const(f) && is_Const_null(f) && is_Const(t) && is_Const_one(t)) {
+               n = transform_Mux_set(n);
+               if (n != oldn)
+                       return n;
+       }
+
        /* the following optimisations create new mode_b nodes, so only do them
         * before mode_b lowering */
        if (!is_irg_state(irg, IR_GRAPH_STATE_MODEB_LOWERED)) {
index 5030aba..12b3cd2 100644 (file)
@@ -195,65 +195,9 @@ static ir_node *lower_node(ir_node *node)
                break;
        }
 
-       case iro_Cmp: {
-               ir_node    *left     = get_Cmp_left(node);
-               ir_node    *right    = get_Cmp_right(node);
-               ir_mode    *cmp_mode = get_irn_mode(left);
-               ir_relation relation = get_Cmp_relation(node);
-
-               if ((mode_is_int(cmp_mode) || mode_is_reference(cmp_mode)) &&
-                       (get_mode_size_bits(cmp_mode) < get_mode_size_bits(mode) ||
-                       (mode_is_signed(cmp_mode) && is_Const(right) && is_Const_null(right) && relation != ir_relation_greater))) {
-                       int         need_not = 0;
-                       ir_node    *a        = NULL;
-                       ir_node    *b        = NULL;
-                       int         bits;
-                       ir_tarval  *tv;
-                       ir_node    *shift_cnt;
-
-                       if (relation == ir_relation_less) {
-                               /* a < b  ->  (a - b) >> 31 */
-                               a = left;
-                               b = right;
-                       } else if (relation == ir_relation_less_equal) {
-                               /* a <= b  -> ~(a - b) >> 31 */
-                               a        = right;
-                               b        = left;
-                               need_not = 1;
-                       } else if (relation == ir_relation_greater) {
-                               /* a > b   -> (b - a) >> 31 */
-                               a = right;
-                               b = left;
-                       } else if (relation == ir_relation_greater_equal) {
-                               /* a >= b   -> ~(a - b) >> 31 */
-                               a        = left;
-                               b        = right;
-                               need_not = 1;
-                       } else {
-                               goto synth_zero_one;
-                       }
-
-                       bits      = get_mode_size_bits(mode);
-                       tv        = new_tarval_from_long(bits-1, mode_Iu);
-                       shift_cnt = new_rd_Const(dbgi, irg, tv);
-
-                       if (cmp_mode != mode) {
-                               a = new_rd_Conv(dbgi, block, a, mode);
-                               b = new_rd_Conv(dbgi, block, b, mode);
-                       }
-
-                       res = new_rd_Sub(dbgi, block, a, b, mode);
-                       if (need_not) {
-                               res = new_rd_Not(dbgi, block, res, mode);
-                       }
-                       res = new_rd_Shr(dbgi, block, res, shift_cnt, mode);
-               } else {
-                       /* synthesize the 0/1 value */
-synth_zero_one:
-                       res = create_cond_set(node, mode);
-               }
+       case iro_Cmp:
+               res = create_cond_set(node, mode);
                break;
-       }
 
        case iro_Const: {
                ir_tarval *tv = get_Const_tarval(node);