From 27322c90a1e74d5a33d149f1d44954279898e56d Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Thu, 23 Aug 2007 11:49:57 +0000 Subject: [PATCH] transform Shl(x,Const) into Muls for more normalization [r15587] --- ir/opt/reassoc.c | 106 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 27 deletions(-) diff --git a/ir/opt/reassoc.c b/ir/opt/reassoc.c index 7ac649025..b99da8753 100644 --- a/ir/opt/reassoc.c +++ b/ir/opt/reassoc.c @@ -363,6 +363,40 @@ static int reassoc_Mul(ir_node **node) return 0; } /* reassoc_Mul */ +/** + * Reassociate Shl. We transform Shl(x, const) into Mul's if possible. + */ +static int reassoc_Shl(ir_node **node) { + ir_node *n = *node; + ir_node *c = get_Shl_right(n); + ir_node *x, *blk, *irn; + ir_mode *mode; + tarval *tv; + + if (! is_Const(c)) + return 0; + + x = get_Shl_left(n); + mode = get_irn_mode(x); + + tv = get_mode_one(mode); + tv = tarval_shl(tv, get_Const_tarval(c)); + + if (tv == tarval_bad) + return 0; + + blk = get_nodes_block(n); + c = new_r_Const(current_ir_graph, blk, mode, tv); + irn = new_rd_Mul(get_irn_dbg_info(n), current_ir_graph, blk, x, c, mode); + + if (irn != n) { + exchange(n, irn); + *node = irn; + return 1; + } + return 0; +} /* reassoc_Shl */ + /** * The walker for the reassociation. */ @@ -504,38 +538,51 @@ static int reverse_rule_distributive(ir_node **node) { ir_node *right = get_binop_right(n); ir_node *x, *blk, *curr_blk; ir_node *a, *b, *irn; + ir_op *op; ir_mode *mode; dbg_info *dbg; - if (! is_Mul(left) || !is_Mul(right)) + op = get_irn_op(left); + if (op != get_irn_op(right)) return 0; - x = get_Mul_left(left); - - if (x == get_Mul_left(right)) { - /* (x * a) +/- (x * b) */ - a = get_Mul_right(left); - b = get_Mul_right(right); - goto transform; - } else if (x == get_Mul_right(right)) { - /* (x * a) +/- (b * x) */ - a = get_Mul_right(left); - b = get_Mul_left(right); - goto transform; - } + if (op == op_Shl) { + x = get_Shl_right(left); + + if (x == get_Shl_right(right)) { + /* (a << x) +/- (b << x) */ + a = get_Shl_left(left); + b = get_Shl_left(right); + goto transform; + } + } else if (op == op_Mul) { + x = get_Mul_left(left); + + if (x == get_Mul_left(right)) { + /* (x * a) +/- (x * b) */ + a = get_Mul_right(left); + b = get_Mul_right(right); + goto transform; + } else if (x == get_Mul_right(right)) { + /* (x * a) +/- (b * x) */ + a = get_Mul_right(left); + b = get_Mul_left(right); + goto transform; + } - x = get_Mul_right(left); - - if (x == get_Mul_right(right)) { - /* (a * x) +/- (b * x) */ - a = get_Mul_left(left); - b = get_Mul_left(right); - goto transform; - } else if (x == get_Mul_left(right)) { - /* (a * x) +/- (x * b) */ - a = get_Mul_left(left); - b = get_Mul_right(right); - goto transform; + x = get_Mul_right(left); + + if (x == get_Mul_right(right)) { + /* (a * x) +/- (b * x) */ + a = get_Mul_left(left); + b = get_Mul_left(right); + goto transform; + } else if (x == get_Mul_left(right)) { + /* (a * x) +/- (x * b) */ + a = get_Mul_left(left); + b = get_Mul_right(right); + goto transform; + } } return 0; @@ -553,7 +600,11 @@ transform: irn = new_rd_Sub(dbg, current_ir_graph, blk, a, b, mode); blk = earliest_block(irn, x, curr_blk); - irn = new_rd_Mul(dbg, current_ir_graph, blk, irn, x, mode); + + if (op == op_Mul) + irn = new_rd_Mul(dbg, current_ir_graph, blk, irn, x, mode); + else + irn = new_rd_Shl(dbg, current_ir_graph, blk, irn, x, mode); exchange(n, irn); *node = irn; @@ -728,6 +779,7 @@ ir_op_ops *firm_set_default_reassoc(ir_opcode code, ir_op_ops *ops) CASE(And); CASE(Or); CASE(Eor); + CASE(Shl); default: /* leave NULL */; } -- 2.20.1