remove unnecessary (since lower_mode_b does it better) and wrong Mux optimisation...
[libfirm] / ir / ir / iropt.c
index 6b8ca05..a452d25 100644 (file)
@@ -3250,6 +3250,15 @@ static ir_node *transform_node_Proj_Div(ir_node *proj) {
 
        if (value_not_zero(b, &confirm)) {
                /* div(x, y) && y != 0 */
+               if (confirm == NULL) {
+                       /* we are sure we have a Const != 0 */
+                       new_mem = get_Div_mem(div);
+                       if (is_Pin(new_mem))
+                               new_mem = get_Pin_op(new_mem);
+                       set_Div_mem(div, new_mem);
+                       set_irn_pinned(div, op_pin_state_floats);
+               }
+
                proj_nr = get_Proj_proj(proj);
                switch (proj_nr) {
                case pn_Div_X_regular:
@@ -3291,6 +3300,15 @@ static ir_node *transform_node_Proj_Mod(ir_node *proj) {
                /* mod(x, y) && y != 0 */
                proj_nr = get_Proj_proj(proj);
 
+               if (confirm == NULL) {
+                       /* we are sure we have a Const != 0 */
+                       new_mem = get_Mod_mem(mod);
+                       if (is_Pin(new_mem))
+                               new_mem = get_Pin_op(new_mem);
+                       set_Mod_mem(mod, new_mem);
+                       set_irn_pinned(mod, op_pin_state_floats);
+               }
+
                switch (proj_nr) {
 
                case pn_Mod_X_regular:
@@ -3309,9 +3327,8 @@ static ir_node *transform_node_Proj_Mod(ir_node *proj) {
                                /* This node can only float up to the Confirm block */
                                new_mem = new_r_Pin(current_ir_graph, get_nodes_block(confirm), new_mem);
                        }
-                       set_irn_pinned(mod, op_pin_state_floats);
                        /* this is a Mod without exception, we can remove the memory edge */
-                       set_Mod_mem(mod, get_irg_no_mem(current_ir_graph));
+                       set_Mod_mem(mod, new_mem);
                        return res;
                case pn_Mod_res:
                        if (get_Mod_left(mod) == b) {
@@ -3341,6 +3358,15 @@ static ir_node *transform_node_Proj_DivMod(ir_node *proj) {
                /* DivMod(x, y) && y != 0 */
                proj_nr = get_Proj_proj(proj);
 
+               if (confirm == NULL) {
+                       /* we are sure we have a Const != 0 */
+                       new_mem = get_DivMod_mem(divmod);
+                       if (is_Pin(new_mem))
+                               new_mem = get_Pin_op(new_mem);
+                       set_DivMod_mem(divmod, new_mem);
+                       set_irn_pinned(divmod, op_pin_state_floats);
+               }
+
                switch (proj_nr) {
 
                case pn_DivMod_X_regular:
@@ -3359,9 +3385,8 @@ static ir_node *transform_node_Proj_DivMod(ir_node *proj) {
                                /* This node can only float up to the Confirm block */
                                new_mem = new_r_Pin(current_ir_graph, get_nodes_block(confirm), new_mem);
                        }
-                       set_irn_pinned(divmod, op_pin_state_floats);
                        /* this is a DivMod without exception, we can remove the memory edge */
-                       set_DivMod_mem(divmod, get_irg_no_mem(current_ir_graph));
+                       set_DivMod_mem(divmod, new_mem);
                        return res;
 
                case pn_DivMod_res_mod:
@@ -3787,13 +3812,14 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) {
                        if (is_Const(c)) {
                                tarval *tv = get_Const_tarval(c);
 
-                               if (tarval_is_long(tv) && get_tarval_long(tv) == 2) {
-                                       /* special case: (x % 2) CMP 0 ==> x & 1 CMP 0 */
+                               if (tarval_is_single_bit(tv)) {
+                                       /* special case: (x % 2^n) CMP 0 ==> x & (2^n-1) CMP 0 */
                                        ir_node *v    = get_binop_left(op);
                                        ir_node *blk  = get_irn_n(op, -1);
                                        ir_mode *mode = get_irn_mode(v);
 
-                                       left = new_rd_And(get_irn_dbg_info(op), current_ir_graph, blk, v, new_Const(mode, get_mode_one(mode)), mode);
+                                       tv = tarval_sub(tv, get_mode_one(mode));
+                                       left = new_rd_And(get_irn_dbg_info(op), current_ir_graph, blk, v, new_Const(mode, tv), mode);
                                        changed |= 1;
                                }
                        }
@@ -4399,52 +4425,6 @@ static ir_node *transform_node_Mux(ir_node *n) {
                                        }
                                }
 
-                               if (mode_is_int(mode) && mode_is_signed(mode) &&
-                                       get_mode_arithmetic(mode) == irma_twos_complement) {
-                                       ir_node *x = get_Cmp_left(cmp);
-
-                                       /* the following optimization works only with signed integer two-complement mode */
-
-                                       if (mode == get_irn_mode(x)) {
-                                               /*
-                                                * FIXME: this restriction is two rigid, as it would still
-                                                * work if mode(x) = Hs and mode == Is, but at least it removes
-                                                * all wrong cases.
-                                                */
-                                               if ((pn == pn_Cmp_Lt || pn == pn_Cmp_Le) &&
-                                                               is_Const(t) && is_Const_all_one(t) &&
-                                                               is_Const(f) && is_Const_null(f)) {
-                                                       /*
-                                                        * Mux(x:T </<= 0, 0, -1) -> Shrs(x, sizeof_bits(T) - 1)
-                                                        * Conditions:
-                                                        * T must be signed.
-                                                        */
-                                                       n = new_rd_Shrs(get_irn_dbg_info(n),
-                                                                       current_ir_graph, block, x,
-                                                                       new_r_Const_long(current_ir_graph, block, mode_Iu,
-                                                                       get_mode_size_bits(mode) - 1),
-                                                                       mode);
-                                                       DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_SHR);
-                                                       return n;
-                                               } else if ((pn == pn_Cmp_Gt || pn == pn_Cmp_Ge) &&
-                                                               is_Const(t) && is_Const_one(t) &&
-                                                               is_Const(f) && is_Const_null(f)) {
-                                                       /*
-                                                        * Mux(x:T >/>= 0, 0, 1) -> Shr(-x, sizeof_bits(T) - 1)
-                                                        * Conditions:
-                                                        * T must be signed.
-                                                        */
-                                                       n = new_rd_Shr(get_irn_dbg_info(n),
-                                                               current_ir_graph, block,
-                                                               new_r_Minus(current_ir_graph, block, x, mode),
-                                                               new_r_Const_long(current_ir_graph, block, mode_Iu,
-                                                               get_mode_size_bits(mode) - 1),
-                                                               mode);
-                                                       DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_SHR);
-                                                       return n;
-                                               }
-                                       }
-                               }
                        }
                }
        }
@@ -4461,6 +4441,42 @@ static ir_node *transform_node_Psi(ir_node *n) {
        return n;
 }  /* transform_node_Psi */
 
+/**
+ * optimize sync nodes that have other syncs as input we simply add the inputs
+ * of the other sync to our own inputs
+ */
+static ir_node *transform_node_Sync(ir_node *n) {
+       int i, arity;
+
+       arity = get_irn_arity(n);
+       for(i = 0; i < get_irn_arity(n); /*empty*/) {
+               int i2, arity2;
+               ir_node *in = get_irn_n(n, i);
+               if(!is_Sync(in)) {
+                       ++i;
+                       continue;
+               }
+
+               /* set sync input 0 instead of the sync */
+               set_irn_n(n, i, get_irn_n(in, 0));
+               /* so we check this input again for syncs */
+
+               /* append all other inputs of the sync to our sync */
+               arity2 = get_irn_arity(in);
+               for(i2 = 1; i2 < arity2; ++i2) {
+                       ir_node *in_in = get_irn_n(in, i2);
+                       add_irn_n(n, in_in);
+                       /* increase arity so we also check the new inputs for syncs */
+                       arity++;
+               }
+       }
+
+       /* rehash the sync node */
+       add_identities(current_ir_graph->value_table, n);
+
+       return n;
+}
+
 /**
  * Tries several [inplace] [optimizing] transformations and returns an
  * equivalent node.  The difference to equivalent_node() is that these
@@ -4525,6 +4541,7 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops
        CASE(End);
        CASE(Mux);
        CASE(Psi);
+       CASE(Sync);
        default:
          /* leave NULL */;
        }