From: Michael Beck Date: Thu, 13 Sep 2007 00:02:45 +0000 (+0000) Subject: better handling of Mul nodes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=c865e5f800a404ed1e700d1f9c8c036d32297106;p=libfirm better handling of Mul nodes [r15767] --- diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 7d2574705..a526a412b 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -191,19 +191,25 @@ static tarval *computed_value_Minus(ir_node *n) { static tarval *computed_value_Mul(ir_node *n) { ir_node *a = get_Mul_left(n); ir_node *b = get_Mul_right(n); + ir_mode *mode; tarval *ta = value_of(a); tarval *tb = value_of(b); - if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) { + mode = get_irn_mode(n); + if (mode != get_irn_mode(a)) { + /* n * n = 2n bit multiplication */ + ta = tarval_convert_to(ta, mode); + tb = tarval_convert_to(tb, mode); + } + + if (ta != tarval_bad && tb != tarval_bad) { return tarval_mul(ta, tb); } else { - /* a*0 = 0 or 0*b = 0: - calls computed_value recursive and returns the 0 with proper - mode. */ - if ((ta != tarval_bad) && (ta == get_mode_null(get_tarval_mode(ta)))) + /* a*0 = 0 or 0*b = 0 */ + if (ta == get_mode_null(mode)) return ta; - if ((tb != tarval_bad) && (tb == get_mode_null(get_tarval_mode(tb)))) + if (tb == get_mode_null(mode)) return tb; } return tarval_bad; @@ -1008,15 +1014,19 @@ static ir_node *equivalent_node_idempotent_unop(ir_node *n) { static ir_node *equivalent_node_Mul(ir_node *n) { ir_node *oldn = n; ir_node *a = get_Mul_left(n); - ir_node *b = get_Mul_right(n); - /* Mul is commutative and has again an other neutral element. */ - if (classify_tarval(value_of(a)) == TV_CLASSIFY_ONE) { - n = b; - DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1); - } else if (classify_tarval(value_of(b)) == TV_CLASSIFY_ONE) { - n = a; - DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1); + /* we can handle here only the n * n = n bit cases */ + if (get_irn_mode(n) == get_irn_mode(a)) { + ir_node *b = get_Mul_right(n); + + /* Mul is commutative and has again an other neutral element. */ + if (classify_tarval(value_of(a)) == TV_CLASSIFY_ONE) { + n = b; + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1); + } else if (classify_tarval(value_of(b)) == TV_CLASSIFY_ONE) { + n = a; + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1); + } } return n; } /* equivalent_node_Mul */ @@ -1873,18 +1883,17 @@ static ir_node *transform_node_AddSub(ir_node *n) { return c; \ } -#define HANDLE_UNOP_PHI(op,a,c) \ - c = NULL; \ - if (is_const_Phi(a)) { \ - /* check for Op(Phi) */ \ - c = apply_unop_on_phi(a, op); \ - } \ - if (c) { \ - DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI); \ - return c; \ +#define HANDLE_UNOP_PHI(op,a,c) \ + c = NULL; \ + if (is_const_Phi(a)) { \ + /* check for Op(Phi) */ \ + c = apply_unop_on_phi(a, op); \ + if (c) { \ + DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI); \ + return c; \ + } \ } - /** * Do the AddSub optimization, then Transform * Constant folding on Phi @@ -2234,6 +2243,47 @@ restart: return n; } /* transform_node_Sub */ +/** + * Several transformation done on n*n=2n bits mul. + * These transformations must be done here because new nodes may be produced. + */ +static ir_node *transform_node_Mul2n(ir_node *n, ir_mode *mode) { + ir_node *oldn = n; + ir_node *a = get_Mul_left(n); + ir_node *b = get_Mul_right(n); + tarval *ta = value_of(a); + tarval *tb = value_of(b); + ir_mode *smode = get_irn_mode(a); + + if (ta == get_mode_one(smode)) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, b, mode); + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1); + return n; + } + else if (ta == get_mode_minus_one(smode)) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, b, smode); + n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, n, mode); + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1); + return n; + } + if (tb == get_mode_one(smode)) { + ir_node *blk = get_irn_n(a, -1); + n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, a, mode); + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1); + return n; + } + else if (tb == get_mode_minus_one(smode)) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, a, smode); + n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, n, mode); + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1); + return n; + } + return n; +} + /** * Transform Mul(a,-1) into -a. * Do constant evaluation of Phi nodes. @@ -2241,13 +2291,15 @@ restart: */ static ir_node *transform_node_Mul(ir_node *n) { ir_node *c, *oldn = n; + ir_mode *mode = get_irn_mode(n); ir_node *a = get_Mul_left(n); ir_node *b = get_Mul_right(n); - ir_mode *mode; + + if (mode != get_irn_mode(a)) + return transform_node_Mul2n(n, mode); HANDLE_BINOP_PHI(tarval_mul, a,b,c); - mode = get_irn_mode(n); if (mode_is_signed(mode)) { ir_node *r = NULL;