X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=94c3bfdaa64e25f71f590f50e161926530381cff;hb=fc5f7e1fbd10124c19b2583d74ab9472bfb95ebf;hp=25b3cdfd75c1f746bcb71a47afdc58925ca93156;hpb=ed2a1ba5119fccd61657200395c3dc557e965159;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 25b3cdfd7..94c3bfdaa 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -1908,7 +1908,7 @@ static ir_node *transform_node_Add(ir_node *n) { if (mode_is_num(mode)) { /* the following code leads to endless recursion when Mul are replaced by a simple instruction chain */ - if (!get_opt_arch_dep_running() && a == b && mode_is_int(mode)) { + if (!is_arch_dep_running() && a == b && mode_is_int(mode)) { ir_node *block = get_irn_n(n, -1); n = new_rd_Mul( @@ -1943,7 +1943,7 @@ static ir_node *transform_node_Add(ir_node *n) { DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B); return n; } - if (! get_opt_reassociation()) { + if (! is_reassoc_running()) { /* do NOT execute this code if reassociation is enabled, it does the inverse! */ if (is_Mul(a)) { ir_node *ma = get_Mul_left(a); @@ -2247,7 +2247,7 @@ restart: } } /* do NOT execute this code if reassociation is enabled, it does the inverse! */ - if (get_opt_reassociation() && is_Mul(a)) { + if (!is_reassoc_running() && is_Mul(a)) { ir_node *ma = get_Mul_left(a); ir_node *mb = get_Mul_right(a); @@ -2283,21 +2283,22 @@ restart: return n; } } - if (is_Sub(a)) { - ir_node *x = get_Sub_left(a); - ir_node *y = get_Sub_right(a); - ir_node *blk = get_irn_n(n, -1); - ir_mode *m_b = get_irn_mode(b); - ir_mode *m_y = get_irn_mode(y); + if (is_Sub(a)) { /* (x - y) - b -> x - (y + b) */ + ir_node *x = get_Sub_left(a); + ir_node *y = get_Sub_right(a); + ir_node *blk = get_irn_n(n, -1); + ir_mode *m_b = get_irn_mode(b); + ir_mode *m_y = get_irn_mode(y); + ir_mode *add_mode; ir_node *add; /* Determine the right mode for the Add. */ if (m_b == m_y) - mode = m_b; + add_mode = m_b; else if (mode_is_reference(m_b)) - mode = m_b; + add_mode = m_b; else if (mode_is_reference(m_y)) - mode = m_y; + add_mode = m_y; else { /* * Both modes are different but none is reference, @@ -2308,7 +2309,7 @@ restart: return n; } - add = new_r_Add(current_ir_graph, blk, y, b, mode); + add = new_r_Add(current_ir_graph, blk, y, b, add_mode); n = new_rd_Sub(get_irn_dbg_info(n), current_ir_graph, blk, x, add, mode); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_SUB_X_Y_Z); @@ -3023,7 +3024,7 @@ static ir_node *transform_node_Eor(ir_node *n) { HANDLE_BINOP_PHI(tarval_eor, a,b,c); /* we can evaluate 2 Projs of the same Cmp */ - if(get_irn_mode(n) == mode_b && is_Proj(a) && is_Proj(b)) { + if (mode == mode_b && is_Proj(a) && is_Proj(b)) { ir_node *pred_a = get_Proj_pred(a); ir_node *pred_b = get_Proj_pred(b); if(pred_a == pred_b) { @@ -3053,9 +3054,20 @@ static ir_node *transform_node_Eor(ir_node *n) { mode_b, get_negated_pnc(get_Proj_proj(a), mode)); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT_BOOL); - } else if (is_Const(b) && is_Const_all_one(b)) { /* x ^ 1...1 -> ~1 */ - n = new_r_Not(current_ir_graph, get_nodes_block(n), a, mode); - DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT); + } else if (is_Const(b)) { + if (is_Not(a)) { /* ~x ^ const -> x ^ ~const */ + ir_node *cnst = new_Const(mode, tarval_not(get_Const_tarval(b))); + ir_node *not_op = get_Not_op(a); + dbg_info *dbg = get_irn_dbg_info(n); + ir_graph *irg = current_ir_graph; + ir_node *block = get_nodes_block(n); + ir_mode *mode = get_irn_mode(n); + n = new_rd_Eor(dbg, irg, block, not_op, cnst, mode); + return n; + } else if (is_Const_all_one(b)) { /* x ^ 1...1 -> ~1 */ + n = new_r_Not(current_ir_graph, get_nodes_block(n), a, mode); + DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT); + } } else { n = transform_bitwise_distributive(n, transform_node_Eor); } @@ -3081,7 +3093,20 @@ static ir_node *transform_node_Not(ir_node *n) { n = new_r_Proj(current_ir_graph, get_irn_n(n, -1), get_Proj_pred(a), mode_b, get_negated_pnc(get_Proj_proj(a), mode_b)); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_CMP); - return n; + return n; + } + if (is_Eor(a)) { + ir_node *eor_b = get_Eor_right(a); + if (is_Const(eor_b)) { /* ~(x ^ const) -> x ^ ~const */ + ir_node *cnst = new_Const(mode, tarval_not(get_Const_tarval(eor_b))); + ir_node *eor_a = get_Eor_left(a); + dbg_info *dbg = get_irn_dbg_info(n); + ir_graph *irg = current_ir_graph; + ir_node *block = get_nodes_block(n); + ir_mode *mode = get_irn_mode(n); + n = new_rd_Eor(dbg, irg, block, eor_a, cnst, mode); + return n; + } } if (get_mode_arithmetic(mode) == irma_twos_complement) { if (is_Minus(a)) { /* ~-x -> x + -1 */ @@ -3175,6 +3200,20 @@ static ir_node *transform_node_Minus(ir_node *n) { return n; } + if (is_Mul(a)) { /* -(a * const) -> a * -const */ + ir_node *mul_l = get_Mul_left(a); + ir_node *mul_r = get_Mul_right(a); + if (is_Const(mul_r)) { + tarval *tv = tarval_neg(get_Const_tarval(mul_r)); + ir_node *cnst = new_Const(mode, tv); + dbg_info *dbg = get_irn_dbg_info(a); + ir_graph *irg = current_ir_graph; + ir_node *block = get_nodes_block(a); + n = new_rd_Mul(dbg, irg, block, mul_l, cnst, mode); + return n; + } + } + return n; } /* transform_node_Minus */ @@ -3639,7 +3678,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) { /* a-b == 0 ==> a == b, a-b != 0 ==> a != b */ if (tarval_is_null(tv) && is_Sub(left)) { - right =get_Sub_right(left); + right = get_Sub_right(left); left = get_Sub_left(left); tv = value_of(right); @@ -3735,12 +3774,36 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) { } /* tarval != bad */ } + if (changed & 2) /* need a new Const */ + right = new_Const(mode, tv); + + if ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) && is_Const(right) && is_Const_null(right) && is_Proj(left)) { + ir_node *op = get_Proj_pred(left); + + if ((is_Mod(op) && get_Proj_proj(left) == pn_Mod_res) || + (is_DivMod(op) && get_Proj_proj(left) == pn_DivMod_res_mod)) { + ir_node *c = get_binop_right(op); + + if (is_Const(c)) { + tarval *tv = get_Const_tarval(c); + + 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); + + 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; + } + } + } + } + if (changed) { ir_node *block = get_irn_n(n, -1); /* Beware of get_nodes_Block() */ - if (changed & 2) /* need a new Const */ - right = new_Const(mode, tv); - /* create a new compare */ n = new_rd_Cmp(get_irn_dbg_info(n), current_ir_graph, block, left, right);