Add Sub(Sub(x, y), b) -> Sub(x, Add(y,b)) Transformation
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Wed, 28 Jun 2006 15:21:40 +0000 (15:21 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Wed, 28 Jun 2006 15:21:40 +0000 (15:21 +0000)
[r7962]

ir/ir/iropt.c
ir/stat/firmstat.h
ir/stat/stat_dmp.c

index dc1e2da..000038b 100644 (file)
@@ -1881,6 +1881,7 @@ static ir_node *transform_node_Add(ir_node *n)
  * Do the AddSub optimization, then Transform
  *   Sub(0,a)          -> Minus(a)
  *   Sub(Mul(a, x), a) -> Mul(a, x-1)
+ *   Sub(Sub(x, y), b) -> Sub(x, Add(y,b))
  */
 static ir_node *transform_node_Sub(ir_node *n)
 {
@@ -1938,6 +1939,37 @@ static ir_node *transform_node_Sub(ir_node *n)
       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MUL_A_X_A);
     }
   }
+  else if (get_irn_op(a) == op_Sub) {
+    ir_node *x   = get_Sub_left(a);
+    ir_node *y   = get_Sub_right(a);
+    ir_node *blk = get_irn_n(n, -1);
+    ir_mode *m_b = get_irn_mode(b);
+    ir_mode *m_y = get_irn_mode(y);
+    ir_node *add;
+
+    /* Determine the right mode for the Add. */
+    if (m_b == m_y)
+      mode = m_b;
+    else if (mode_is_reference(m_b))
+      mode = m_b;
+    else if (mode_is_reference(m_y))
+      mode = m_y;
+    else {
+      /*
+       * Both modes are different but none is reference,
+       * happens for instance in SubP(SubP(P, Iu), Is).
+       * We have two possibilities here: Cast or ignore.
+       * Currently we ignore this case.
+       */
+      return n;
+    }
+
+    add = new_r_Add(current_ir_graph, blk, y, b, mode);
+
+    set_Sub_left(n, x);
+    set_Sub_right(n, add);
+    DBG_OPT_ALGSIM0(n, n, FS_OPT_SUB_SUB_X_Y_Z);
+  }
 
   return n;
 }
index 1974dd9..8667a3a 100644 (file)
@@ -43,6 +43,7 @@ enum firmstat_optimizations_t {
   FS_OPT_ADD_MUL_A_X_A,                     /**< a * x + a = a * (x + 1) */
   FS_OPT_SUB_0_A,                           /**< 0 - a = -a */
   FS_OPT_SUB_MUL_A_X_A,                     /**< a * x - a = a * (x - 1) */
+  FS_OPT_SUB_SUB_X_Y_Z,                     /**< (x - y) - z = x - (y + z) */
   FS_OPT_MUL_MINUS_1,                       /**< a * -1 = -a */
   FS_OPT_OR,                                /**< a | a = a | 0 = 0 | a = a */
   FS_OPT_AND,                               /**< a & 0b1...1 = 0b1...1 & a =  a & a = a */
index 9f70d5b..36bf98b 100644 (file)
@@ -57,6 +57,7 @@ static const struct {
        { FS_OPT_ADD_MUL_A_X_A,  "algebraic simplification: a * x + a = a * (x + 1)" },
        { FS_OPT_SUB_0_A,        "algebraic simplification: 0 - a = -a" },
        { FS_OPT_SUB_MUL_A_X_A,  "algebraic simplification: a * x - a = a * (x - 1)" },
+       { FS_OPT_SUB_SUB_X_Y_Z,  "algebraic simplification: (x - y) - z = x - (y + z)" },
        { FS_OPT_MUL_MINUS_1,    "algebraic simplification: a * -1 = -a" },
        { FS_OPT_OR,             "algebraic simplification: a | a = a | 0 = 0 | a = a" },
        { FS_OPT_AND,            "algebraic simplification: a & 0b1...1 = 0b1...1 & a =  a & a = a" },