X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=a452d25192971c4e6da040a9c491581f34d6f1c7;hb=62f1d1d20663ad5ec9b8e7d2c2ee3d23bf014b62;hp=6b8ca056a604b613a90f8353420766e488572853;hpb=657b8782663bee965151084d39758c727423ed95;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 6b8ca056a..a452d2519 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -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 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 */; }