+ res = blk_a;
+ if (res == get_irg_start_block(get_irn_irg(curr_blk)))
+ return curr_blk;
+ return res;
+} /* earliest_block */
+
+/**
+ * Checks whether a node is a Constant expression.
+ * The following trees are constant expressions:
+ *
+ * Const, SymConst, Const + SymConst
+ *
+ * Handling SymConsts as const might be not a good idea for all
+ * architectures ...
+ */
+static int is_constant_expr(ir_node *irn)
+{
+ switch (get_irn_opcode(irn)) {
+ case iro_Const:
+ case iro_SymConst:
+ return 1;
+
+ case iro_Add: {
+ ir_node *const l = get_Add_left(irn);
+ if (!is_Const(l) && !is_SymConst(l))
+ return 0;
+ ir_node *const r = get_Add_right(irn);
+ if (!is_Const(r) && !is_SymConst(r))
+ return 0;
+ return 1;
+ }
+
+ default:
+ return 0;
+ }
+} /* is_constant_expr */
+
+/**
+ * Apply distributive Law for Mul and Add/Sub
+ */
+static int reverse_rule_distributive(ir_node **node)
+{
+ ir_node *n = *node;
+ ir_node *left = get_binop_left(n);
+ ir_node *right = get_binop_right(n);
+ ir_node *x, *blk, *curr_blk;
+ ir_node *a, *b, *irn;
+ ir_op *op;
+ ir_mode *mode;
+ dbg_info *dbg;
+
+ op = get_irn_op(left);
+ if (op != get_irn_op(right))
+ return 0;
+
+ if (op == op_Shl) {
+ x = get_Shl_right(left);
+
+ if (x == get_Shl_right(right)) {
+ /* (a << x) +/- (b << x) ==> (a +/- b) << x */
+ a = get_Shl_left(left);
+ b = get_Shl_left(right);
+ goto transform;
+ }
+ } else if (op == op_Mul) {
+ x = get_Mul_left(left);
+
+ if (x == get_Mul_left(right)) {
+ /* (x * a) +/- (x * b) ==> (a +/- b) * x */
+ a = get_Mul_right(left);
+ b = get_Mul_right(right);
+ goto transform;
+ } else if (x == get_Mul_right(right)) {
+ /* (x * a) +/- (b * x) ==> (a +/- b) * x */
+ a = get_Mul_right(left);
+ b = get_Mul_left(right);
+ goto transform;
+ }
+
+ x = get_Mul_right(left);
+
+ if (x == get_Mul_right(right)) {
+ /* (a * x) +/- (b * x) ==> (a +/- b) * x */
+ a = get_Mul_left(left);
+ b = get_Mul_left(right);
+ goto transform;
+ } else if (x == get_Mul_left(right)) {
+ /* (a * x) +/- (x * b) ==> (a +/- b) * x */
+ a = get_Mul_left(left);
+ b = get_Mul_right(right);
+ goto transform;
+ }
+ }
+ return 0;
+
+transform:
+ curr_blk = get_nodes_block(n);