From bf9f697bb80c911594b4bf60872d6b80aa98c7f5 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Mon, 9 Jul 2007 15:26:11 +0000 Subject: [PATCH] add optimizations for Or,And,Eor and Shift [r14995] --- include/libfirm/firmstat.h | 3 +++ ir/ir/iropt.c | 52 ++++++++++++++++++++++++++++++++++++++ ir/stat/stat_dmp.c | 3 +++ 3 files changed, 58 insertions(+) diff --git a/include/libfirm/firmstat.h b/include/libfirm/firmstat.h index 9ce0abeab..07ef579b3 100644 --- a/include/libfirm/firmstat.h +++ b/include/libfirm/firmstat.h @@ -65,6 +65,9 @@ enum firmstat_optimizations_t { FS_OPT_NOT_CMP, /**< !(a cmp b) = a !cmp b */ FS_OPT_OR_SHFT_TO_ROT, /**< (x << c) | (x >> (bits - c)) == Rot(x, c) */ FS_OPT_REASSOC_SHIFT, /**< (x SHF c1) SHF c2 = x SHF (c1+c2) */ + FS_OPT_SHIFT_AND, /**< (a SHF c) AND (b SHF c) = (a AND b) SHF c */ + FS_OPT_SHIFT_OR, /**< (a SHF c) OR (b SHF c) = (a OR b) SHF c */ + FS_OPT_SHIFT_EOR, /**< (a SHF c) XOR (b SHF c) = (a XOR b) SHF c */ FS_OPT_CONV, /**< a Conv could be removed */ FS_OPT_CAST, /**< a Cast could be removed */ FS_OPT_MIN_MAX_EQ, /**< Min(a,a) = Max(a,a) = a */ diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index fa80f762d..c17e757f2 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -2371,8 +2371,24 @@ static ir_node *transform_node_And(ir_node *n) { ir_node *c, *oldn = n; ir_node *a = get_And_left(n); ir_node *b = get_And_right(n); + ir_op *op; HANDLE_BINOP_PHI(tarval_and, a,b,c); + + op = get_irn_op(a); + if ((op == op_Shrs || op == op_Shr || op == op_Shl) && (op == get_irn_op(b))) { + ir_node *c = get_binop_right(a); + if (c == get_binop_right(b)) { + /* (a sop c) & (b sop c) => (a & b) sop c */ + ir_node *blk = get_irn_n(n, -1); + + n = exact_copy(a); + set_irn_n(n, -1, blk); + set_binop_left(n, new_r_And(current_ir_graph, blk, get_binop_left(a), get_binop_left(b), get_irn_mode(oldn))); + + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_SHIFT_AND); + } + } return n; } /* transform_node_And */ @@ -2409,6 +2425,22 @@ static ir_node *transform_node_Eor(ir_node *n) { n = new_r_Not(current_ir_graph, get_irn_n(n, -1), a, mode_b); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT); + } else { + ir_op *op = get_irn_op(a); + + if ((op == op_Shrs || op == op_Shr || op == op_Shl) && (op == get_irn_op(b))) { + ir_node *c = get_binop_right(a); + if (c == get_binop_right(b)) { + /* (a sop c) ^ (b sop c) => (a ^ b) sop c */ + ir_node *blk = get_irn_n(n, -1); + + n = exact_copy(a); + set_irn_n(n, -1, blk); + set_binop_left(n, new_r_Eor(current_ir_graph, blk, get_binop_left(a), get_binop_left(b), get_irn_mode(oldn))); + + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_SHIFT_EOR); + } + } } return n; @@ -3153,11 +3185,31 @@ static ir_node *transform_node_Or(ir_node *n) { ir_node *c, *oldn = n; ir_node *a = get_Or_left(n); ir_node *b = get_Or_right(n); + ir_op *op; HANDLE_BINOP_PHI(tarval_or, a,b,c); n = transform_node_Or_bf_store(n); n = transform_node_Or_Rot(n); + if (n != oldn) + return n; + + a = get_Or_left(n); + b = get_Or_right(n); + op = get_irn_op(a); + if ((op == op_Shrs || op == op_Shr || op == op_Shl) && (op == get_irn_op(b))) { + ir_node *c = get_binop_right(a); + if (c == get_binop_right(b)) { + /* (a sop c) | (b sop c) => (a | b) sop c */ + ir_node *blk = get_irn_n(n, -1); + + n = exact_copy(a); + set_irn_n(n, -1, blk); + set_binop_left(n, new_r_Or(current_ir_graph, blk, get_binop_left(a), get_binop_left(b), get_irn_mode(oldn))); + + DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_SHIFT_OR); + } + } return n; } /* transform_node_Or */ diff --git a/ir/stat/stat_dmp.c b/ir/stat/stat_dmp.c index 3904fb73b..ffe98033b 100644 --- a/ir/stat/stat_dmp.c +++ b/ir/stat/stat_dmp.c @@ -83,6 +83,9 @@ static const struct { { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" }, { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" }, { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" }, + { FS_OPT_SHIFT_AND, "algebraic simplification: (a SHF c) AND (b SHF c) = (a AND b) SHF c" }, + { FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" }, + { FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" }, { FS_OPT_CONV, "algebraic simplification: Conv could be removed" }, { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" }, { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" }, -- 2.20.1