improved normalisation of not+eor nodes
authorMatthias Braun <matze@braunis.de>
Mon, 9 Aug 2010 14:53:08 +0000 (14:53 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 9 Aug 2010 14:53:08 +0000 (14:53 +0000)
[r27913]

ir/ir/iropt.c

index ce18fcc..7fe3cea 100644 (file)
@@ -3645,23 +3645,28 @@ static ir_node *transform_node_Eor(ir_node *n)
                n = new_rd_Const(get_irn_dbg_info(n), current_ir_graph,
                                 get_mode_null(mode));
                DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_A_A);
-       } else if (is_Const(b)) {
-               if (is_Not(a)) { /* ~x ^ const -> x ^ ~const */
-                       ir_node  *cnst   = new_Const(tarval_not(get_Const_tarval(b)));
-                       ir_node  *not_op = get_Not_op(a);
-                       dbg_info *dbg    = get_irn_dbg_info(n);
-                       ir_node  *block  = get_nodes_block(n);
-                       ir_mode  *mode   = get_irn_mode(n);
-                       n = new_rd_Eor(dbg, block, not_op, cnst, mode);
-                       return n;
-               } else if (is_Const_all_one(b)) { /* x ^ 1...1 -> ~1 */
-                       n = new_r_Not(get_nodes_block(n), a, mode);
-                       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
-               }
-       } else {
-               n = transform_bitwise_distributive(n, transform_node_Eor);
+               return n;
+       }
+
+       /* normalize not nodes... ~a ^ b => a ^ ~b */
+       if (is_Not(a)) {
+               dbg_info *dbg      = get_irn_dbg_info(n);
+               ir_node  *block    = get_nodes_block(n);
+               ir_node  *new_not  = new_rd_Not(dbg, block, b, mode);
+               ir_node  *new_left = get_Not_op(a);
+               n = new_rd_Eor(dbg, block, new_left, new_not, mode);
+               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
+               return n;
+       }
+
+       /* x ^ 1...1 -> ~1 */
+       if (is_Const(b) && is_Const_all_one(b)) {
+               n = new_r_Not(get_nodes_block(n), a, mode);
+               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
+               return n;
        }
 
+       n = transform_bitwise_distributive(n, transform_node_Eor);
        return n;
 }  /* transform_node_Eor */
 
@@ -3687,18 +3692,18 @@ static ir_node *transform_node_Not(ir_node *n)
                        return n;
                }
        }
+
+       /* normalize ~(a ^ b) => a ^ ~b */
        if (is_Eor(a)) {
-               ir_node *eor_b = get_Eor_right(a);
-               if (is_Const(eor_b)) { /* ~(x ^ const) -> x ^ ~const */
-                       ir_node  *cnst  = new_Const(tarval_not(get_Const_tarval(eor_b)));
-                       ir_node  *eor_a = get_Eor_left(a);
-                       dbg_info *dbg   = get_irn_dbg_info(n);
-                       ir_node  *block = get_nodes_block(n);
-                       ir_mode  *mode  = get_irn_mode(n);
-                       n = new_rd_Eor(dbg, block, eor_a, cnst, mode);
-                       return n;
-               }
+               dbg_info *dbg       = get_irn_dbg_info(n);
+               ir_node  *block     = get_nodes_block(n);
+               ir_node  *eor_right = get_Eor_right(a);
+               ir_node  *eor_left  = get_Eor_left(a);
+               eor_right = new_rd_Not(dbg, block, eor_right, mode);
+               n = new_rd_Eor(dbg, block, eor_left, eor_right, mode);
+               return n;
        }
+
        if (get_mode_arithmetic(mode) == irma_twos_complement) {
                if (is_Minus(a)) { /* ~-x -> x + -1 */
                        dbg_info *dbg   = get_irn_dbg_info(n);