return false;
}
+typedef ir_tarval *(tv_fold_binop_func)(ir_tarval *a, ir_tarval *b);
+
+/**
+ * for associative operations fold:
+ * op(op(x, c0), c1) to op(x, op(c0, c1)) with constants folded.
+ * This is a "light" version of the reassociation phase
+ */
+static ir_node *fold_constant_associativity(ir_node *node,
+ tv_fold_binop_func fold)
+{
+ ir_graph *irg;
+ ir_op *op;
+ ir_node *left;
+ ir_node *right = get_binop_right(node);
+ ir_node *left_right;
+ ir_node *left_left;
+ ir_tarval *c0;
+ ir_tarval *c1;
+ ir_tarval *new_c;
+ ir_node *new_const;
+ ir_node *new_node;
+ if (!is_Const(right))
+ return node;
+
+ op = get_irn_op(node);
+ left = get_binop_left(node);
+ if (get_irn_op(left) != op)
+ return node;
+
+ left_right = get_binop_right(left);
+ if (!is_Const(left_right))
+ return node;
+
+ left_left = get_binop_left(left);
+ c0 = get_Const_tarval(left_right);
+ c1 = get_Const_tarval(right);
+ irg = get_irn_irg(node);
+ if (get_tarval_mode(c0) != get_tarval_mode(c1))
+ return node;
+ new_c = fold(c0, c1);
+ if (new_c == tarval_bad)
+ return node;
+ new_const = new_r_Const(irg, new_c);
+ new_node = exact_copy(node);
+ set_binop_left(new_node, left_left);
+ set_binop_right(new_node, new_const);
+ return new_node;
+}
+
/**
* Transform an Or.
*/
ir_node *c;
ir_mode *mode;
+ n = fold_constant_associativity(n, tarval_or);
+ if (n != oldn)
+ return n;
+
if (is_Not(a) && is_Not(b)) {
/* ~a | ~b = ~(a&b) */
ir_node *block = get_nodes_block(n);
ir_mode *mode = get_irn_mode(n);
ir_node *c;
+ n = fold_constant_associativity(n, tarval_eor);
+ if (n != oldn)
+ return n;
+
/* we can combine the relations of two compares with the same operands */
if (is_Cmp(a) && is_Cmp(b)) {
ir_node *a_left = get_Cmp_left(a);
return transform_node_Eor_(n);
}
-
-
/**
* Do the AddSub optimization, then Transform
* Constant folding on Phi
ir_node *c;
ir_node *oldn = n;
+ n = fold_constant_associativity(n, tarval_add);
+ if (n != oldn)
+ return n;
+
n = transform_node_AddSub(n);
if (n != oldn)
return n;
ir_node *a = get_Mul_left(n);
ir_node *b = get_Mul_right(n);
- if (is_Bad(a) || is_Bad(b))
+ n = fold_constant_associativity(n, tarval_mul);
+ if (n != oldn)
return n;
if (mode != get_irn_mode(a))
ir_node *b = get_And_right(n);
ir_mode *mode;
+ n = fold_constant_associativity(n, tarval_and);
+ if (n != oldn)
+ return n;
+
if (is_Cmp(a) && is_Cmp(b)) {
ir_node *a_left = get_Cmp_left(a);
ir_node *a_right = get_Cmp_right(a);