* 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)
{
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;
}
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 */
{ 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" },