Ignore generated files.
[libfirm] / ir / opt / reassoc.c
index 5bcdbb9..5927a37 100644 (file)
@@ -23,9 +23,7 @@
  * @author  Michael Beck
  * @version $Id$
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include "iropt_t.h"
 #include "irnode_t.h"
 #include "irgwalk.h"
 #include "irouts.h"
 #include "reassoc_t.h"
+#include "opt_init.h"
 #include "irhooks.h"
 #include "irloop.h"
 #include "pdeq.h"
 #include "debug.h"
+#include "irpass.h"
 
 //#define NEW_REASSOC
 
@@ -173,8 +173,8 @@ static int reassoc_Sub(ir_node **in)
                dbi  = get_irn_dbg_info(n);
 
                /* Beware of SubP(P, Is) */
-               irn = new_rd_Minus(dbi, current_ir_graph, block, right, rmode);
-               irn = new_rd_Add(dbi, current_ir_graph, block, left, irn, mode);
+               irn = new_rd_Minus(dbi, block, right, rmode);
+               irn = new_rd_Add(dbi, block, left, irn, mode);
 
                DBG((dbg, LEVEL_5, "Applied: %n - %n => %n + (-%n)\n",
                        get_Sub_left(n), right, get_Sub_left(n), right));
@@ -222,7 +222,7 @@ static ir_mode *get_mode_from_ops(ir_node *op1, ir_node *op2)
 static int reassoc_commutative(ir_node **node)
 {
        ir_node *n     = *node;
-       ir_op *op      = get_irn_op(n);
+       ir_op   *op    = get_irn_op(n);
        ir_node *block = get_nodes_block(n);
        ir_node *t1, *c1;
 
@@ -268,15 +268,15 @@ static int reassoc_commutative(ir_node **node)
                                if (mode_is_int(mode_c1) && mode_is_int(mode_c2)) {
                                        /* get the bigger one */
                                        if (get_mode_size_bits(mode_c1) > get_mode_size_bits(mode_c2))
-                                               c2 = new_r_Conv(current_ir_graph, block, c2, mode_c1);
+                                               c2 = new_r_Conv(block, c2, mode_c1);
                                        else if (get_mode_size_bits(mode_c1) < get_mode_size_bits(mode_c2))
-                                               c1 = new_r_Conv(current_ir_graph, block, c1, mode_c2);
+                                               c1 = new_r_Conv(block, c1, mode_c2);
                                        else {
                                                /* Try to cast the real const */
                                                if (c_c1 == REAL_CONSTANT)
-                                                       c1 = new_r_Conv(current_ir_graph, block, c1, mode_c2);
+                                                       c1 = new_r_Conv(block, c1, mode_c2);
                                                else
-                                                       c2 = new_r_Conv(current_ir_graph, block, c2, mode_c1);
+                                                       c2 = new_r_Conv(block, c2, mode_c1);
                                        }
                                }
                        }
@@ -306,6 +306,55 @@ static int reassoc_commutative(ir_node **node)
                        }
                }
        }
+       if (get_irn_op(c1) == op) {
+               ir_node *t = c1;
+               c1 = t1;
+               t1 = t;
+       }
+       if (get_irn_op(t1) == op) {
+               ir_node *l = get_binop_left(t1);
+               ir_node *r = get_binop_right(t1);
+               const_class_t c_r;
+
+               if (r == c1) {
+                       ir_node *t = r;
+                       r = l;
+                       l = t;
+               }
+               c_r = get_const_class(r, block);
+               if (c_r != NO_CONSTANT) {
+                       /*
+                        * Beware: don't do the following op if a constant was
+                        * placed below, else we will fall into a loop.
+                        */
+                       return 0;
+               }
+
+               if (l == c1) {
+                       /* convert x .OP. (x .OP. y) => y .OP. (x .OP. x) */
+                       ir_mode *mode_res = get_irn_mode(n);
+                       ir_mode *mode_c1  = get_irn_mode(c1);
+                       ir_node *irn, *in[2];
+
+                       in[0] = c1;
+                       in[1] = c1;
+
+                       in[1] = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode_c1, 2, in));
+                       in[0] = r;
+
+                       irn   = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode_res, 2, in));
+
+                       DBG((dbg, LEVEL_5, "Applied: %n .%s. (%n .%s. %n) => %n .%s. (%n .%s. %n)\n",
+                               c1, get_irn_opname(n), l, get_irn_opname(n), r,
+                               r, get_irn_opname(n), c1, get_irn_opname(n), c1));
+
+                       if (n != irn) {
+                               exchange(n, irn);
+                               *node = irn;
+                               return 1;
+                       }
+               }
+       }
        return 0;
 }  /* reassoc_commutative */
 
@@ -469,8 +518,8 @@ static int reassoc_Mul(ir_node **node)
 
                /* we can only multiplication rules on integer arithmetic */
                if (mode_is_int(get_irn_mode(t1)) && mode_is_int(get_irn_mode(t2))) {
-                       in[0] = new_rd_Mul(NULL, current_ir_graph, block, c, t1, mode);
-                       in[1] = new_rd_Mul(NULL, current_ir_graph, block, c, t2, mode);
+                       in[0] = new_rd_Mul(NULL, block, c, t1, mode);
+                       in[1] = new_rd_Mul(NULL, block, c, t2, mode);
 
                        irn   = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
 
@@ -519,8 +568,8 @@ static int reassoc_Shl(ir_node **node) {
                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);
+       c   = new_Const(tv);
+       irn = new_rd_Mul(get_irn_dbg_info(n), blk, x, c, mode);
 
        if (irn != n) {
                exchange(n, irn);
@@ -727,16 +776,16 @@ transform:
        mode = get_irn_mode(n);
 
        if (is_Add(n))
-               irn = new_rd_Add(dbg, current_ir_graph, blk, a, b, mode);
+               irn = new_rd_Add(dbg, blk, a, b, mode);
        else
-               irn = new_rd_Sub(dbg, current_ir_graph, blk, a, b, mode);
+               irn = new_rd_Sub(dbg, blk, a, b, mode);
 
        blk  = earliest_block(irn, x, curr_blk);
 
        if (op == op_Mul)
-               irn = new_rd_Mul(dbg, current_ir_graph, blk, irn, x, mode);
+               irn = new_rd_Mul(dbg, blk, irn, x, mode);
        else
-               irn = new_rd_Shl(dbg, current_ir_graph, blk, irn, x, mode);
+               irn = new_rd_Shl(dbg, blk, irn, x, mode);
 
        exchange(n, irn);
        *node = irn;
@@ -782,7 +831,8 @@ static int move_consts_up(ir_node **node) {
                        dbg = dbg == get_irn_dbg_info(l) ? dbg : NULL;
                        goto transform;
                }
-       } else if (get_irn_op(r) == op) {
+       }
+       if (get_irn_op(r) == op) {
                /* l .op. (a .op. b) */
                a = get_binop_left(r);
                b = get_binop_right(r);
@@ -934,6 +984,11 @@ int optimize_reassociation(ir_graph *irg)
        return env.changes;
 }  /* optimize_reassociation */
 
+/* create a pass for the reassociation */
+ir_graph_pass_t *optimize_reassociation_pass(const char *name) {
+       return def_graph_pass_ret(name ? name : "reassoc", optimize_reassociation);
+}  /* optimize_reassociation_pass */
+
 /* Sets the default reassociation operation for an ir_op_ops. */
 ir_op_ops *firm_set_default_reassoc(ir_opcode code, ir_op_ops *ops)
 {