X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=ca58b2ef4eeb06915ab19343d0987be77cbe1dc5;hb=a08e6f04aa3669cff094f94a9484c7c2bb1314d0;hp=aaa7afa855ba3179de1ec523d71e79e22328cc77;hpb=1de3ff1c7f4478924c6348f774608e60b962d055;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index aaa7afa85..ca58b2ef4 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -352,7 +352,7 @@ static ir_tarval *computed_value_Not(const ir_node *n) } /* computed_value_Not */ /** - * Tests wether a shift shifts more bits than available in the mode + * Tests whether a shift shifts more bits than available in the mode */ static bool is_oversize_shift(const ir_node *n) { @@ -957,7 +957,7 @@ static ir_node *equivalent_node_Sub(ir_node *n) /** - * Optimize an "self-inverse unary op", ie op(op(n)) = n. + * Optimize an "self-inverse unary op", i.e. op(op(n)) = n. * * @todo * -(-a) == a, but might overflow two times. @@ -2665,7 +2665,7 @@ make_tuple: /* skip a potential Pin */ mem = skip_Pin(mem); - turn_into_tuple(n, pn_Div_max); + turn_into_tuple(n, pn_Div_max+1); set_Tuple_pred(n, pn_Div_M, mem); set_Tuple_pred(n, pn_Div_X_regular, new_r_Jmp(blk)); set_Tuple_pred(n, pn_Div_X_except, new_r_Bad(irg, mode_X)); @@ -2757,7 +2757,7 @@ make_tuple: /* skip a potential Pin */ mem = skip_Pin(mem); - turn_into_tuple(n, pn_Mod_max); + turn_into_tuple(n, pn_Mod_max+1); set_Tuple_pred(n, pn_Mod_M, mem); set_Tuple_pred(n, pn_Mod_X_regular, new_r_Jmp(blk)); set_Tuple_pred(n, pn_Mod_X_except, new_r_Bad(irg, mode_X)); @@ -2791,7 +2791,7 @@ static ir_node *transform_node_Cond(ir_node *n) Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */ ir_node *blk = get_nodes_block(n); jmp = new_r_Jmp(blk); - turn_into_tuple(n, pn_Cond_max); + turn_into_tuple(n, pn_Cond_max+1); if (ta == tarval_b_true) { set_Tuple_pred(n, pn_Cond_false, new_r_Bad(irg, mode_X)); set_Tuple_pred(n, pn_Cond_true, jmp); @@ -3864,6 +3864,7 @@ static ir_node *transform_node_Cmp(ir_node *n) ir_graph *irg = get_irn_irg(n); left = op_left; right = new_r_Const(irg, new_tv); + mode = get_irn_mode(left); changed = true; DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV); } @@ -5146,7 +5147,7 @@ typedef ir_node*(*new_shift_func)(dbg_info *dbgi, ir_node *block, * then we can use that to minimize the value of Add(x, const) or * Sub(Const, x). In particular this often avoids 1 instruction in some * backends for the Shift(x, Sub(Const, y)) case because it can be replaced - * by Shift(x, Minus(y)) which doesnt't need an explicit Const constructed. + * by Shift(x, Minus(y)) which does not need an explicit Const constructed. */ static ir_node *transform_node_shift_modulo(ir_node *n, new_shift_func new_shift) @@ -5383,7 +5384,7 @@ static ir_node *transform_node_End(ir_node *n) /* no need to keep Bad */ if (is_Bad(ka)) continue; - /* dont keep unreachable code */ + /* do not keep unreachable code */ block = is_Block(ka) ? ka : get_nodes_block(ka); if (is_block_unreachable(block)) continue; @@ -5502,9 +5503,6 @@ static ir_node *transform_node_Mux(ir_node *n) ir_node *f = get_Mux_false(n); ir_graph *irg = get_irn_irg(n); - if (is_irg_state(irg, IR_GRAPH_STATE_KEEP_MUX)) - return n; - /* implement integer abs: abs(x) = x^(x >>s 31) - (x >>s 31) */ if (get_mode_arithmetic(mode) == irma_twos_complement) { int abs = ir_mux_is_abs(sel, t, f); @@ -5526,6 +5524,9 @@ static ir_node *transform_node_Mux(ir_node *n) } } + if (is_irg_state(irg, IR_GRAPH_STATE_KEEP_MUX)) + return n; + if (is_Mux(t)) { ir_node* block = get_nodes_block(n); ir_node* c0 = sel; @@ -5832,7 +5833,7 @@ static ir_node *transform_node_Load(ir_node *n) ir_node *bad = new_r_Bad(irg, mode_X); ir_mode *mode = get_Load_mode(n); ir_node *res = new_r_Proj(pred_load, mode, pn_Load_res); - ir_node *in[pn_Load_max] = { mem, jmp, bad, res }; + ir_node *in[pn_Load_max+1] = { mem, res, jmp, bad }; ir_node *tuple = new_r_Tuple(block, ARRAY_SIZE(in), in); return tuple; } @@ -5852,7 +5853,7 @@ static ir_node *transform_node_Load(ir_node *n) ir_graph *irg = get_irn_irg(n); ir_node *bad = new_r_Bad(irg, mode_X); ir_node *res = value; - ir_node *in[pn_Load_max] = { mem, jmp, bad, res }; + ir_node *in[pn_Load_max+1] = { mem, res, jmp, bad }; ir_node *tuple = new_r_Tuple(block, ARRAY_SIZE(in), in); return tuple; } @@ -6315,10 +6316,23 @@ int identities_cmp(const void *elt, const void *key) /* for pinned nodes, the block inputs must be equal */ if (get_irn_n(a, -1) != get_irn_n(b, -1)) return 1; - } else if (! get_opt_global_cse()) { - /* for block-local CSE both nodes must be in the same Block */ - if (get_nodes_block(a) != get_nodes_block(b)) - return 1; + } else { + ir_node *block_a = get_nodes_block(a); + ir_node *block_b = get_nodes_block(b); + if (! get_opt_global_cse()) { + /* for block-local CSE both nodes must be in the same Block */ + if (block_a != block_b) + return 1; + } else { + /* The optimistic approach would be to do nothing here. + * However doing GCSE optimistically produces a lot of partially dead code which appears + * to be worse in practice than the missed opportunities. + * So we use a very conservative variant here and only CSE if 1 value dominates the + * other. */ + if (!block_dominates(block_a, block_b) + && !block_dominates(block_b, block_a)) + return 1; + } } /* compare a->in[0..ins] with b->in[0..ins] */