Added add_saturated
[libfirm] / ir / opt / reassoc.c
index a12f5e1..66174bb 100644 (file)
@@ -28,7 +28,7 @@
 # include "irloop.h"
 # include "debug.h"
 
-static firm_dbg_module_t *dbg;
+DEBUG_ONLY(static firm_dbg_module_t *dbg;)
 
 typedef struct _walker_t {
   int changes;          /* set, if a reassociation take place */
@@ -303,18 +303,32 @@ static int reassoc_Mul(ir_node **node)
     t1 = get_binop_left(add_sub);
     t2 = get_binop_right(add_sub);
 
-    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);
+    /* 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);
 
-    mode  = get_mode_from_ops(in[0], in[1]);
-    irn   = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
+      mode  = get_mode_from_ops(in[0], in[1]);
+      irn   = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
 
-    DBG((dbg, LEVEL_5, "Applied: (%n .%s. %n) %n %n => (%n %n %n) .%s. (%n %n %n)\n",
-        t1, get_op_name(op), t2, n, c, t1, n, c, get_op_name(op), t2, n, c));
-    exchange(n, irn);
-               *node = irn;
+      /* In some cases it might happen that the new irn is equal the old one, for
+       * instance in:
+       * (x - 1) * y == x * y - y
+       * will be transformed back by simpler optimization
+       * We could switch simple optimizations off, but this only happens iff y
+       * is a loop-invariant expreassion and that it is not clear if the new form
+       * is better.
+       * So, we let the old one.
+       */
+      if (irn != n) {
+        DBG((dbg, LEVEL_5, "Applied: (%n .%s. %n) %n %n => (%n %n %n) .%s. (%n %n %n)\n",
+            t1, get_op_name(op), t2, n, c, t1, n, c, get_op_name(op), t2, n, c));
+        exchange(n, irn);
+                   *node = irn;
 
-    return 1;
+        return 1;
+      }
+    }
   }
   return 0;
 }
@@ -410,5 +424,5 @@ ir_op_ops *firm_set_default_reassoc(opcode code, ir_op_ops *ops)
 /* initialize the reassociation by adding operations to some opcodes */
 void firm_init_reassociation(void)
 {
-  dbg = firm_dbg_register("firm.opt.reassoc");
+  FIRM_DBG_REGISTER(dbg, "firm.opt.reassoc");
 }