- ir_node *n = *node;
- ir_node *add_sub, *c;
- ir_op *op;
-
- if (reassoc_commutative(&n))
- return 1;
-
- get_comm_Binop_ops(n, &add_sub, &c);
- op = get_irn_op(add_sub);
-
- /* handles rules R11, R12, R13, R14, R15, R16, R17, R18, R19, R20 */
- if (op == op_Add || op == op_Sub) {
- ir_mode *mode = get_irn_mode(n);
- ir_node *irn, *block, *t1, *t2, *in[2];
-
- block = get_nodes_block(n);
- t1 = get_binop_left(add_sub);
- t2 = get_binop_right(add_sub);
-
- /* 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));
-
- /* 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 expression 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 0;
-}
+ ir_node *n = *node;
+ ir_node *add_sub, *c;
+ ir_op *op;
+
+ if (reassoc_commutative(&n))
+ return 1;
+
+ get_comm_Binop_ops(n, &add_sub, &c);
+ op = get_irn_op(add_sub);
+
+ /* handles rules R11, R12, R13, R14, R15, R16, R17, R18, R19, R20 */
+ if (op == op_Add || op == op_Sub) {
+ ir_mode *mode = get_irn_mode(n);
+ ir_node *irn, *block, *t1, *t2, *in[2];
+
+ block = get_nodes_block(n);
+ t1 = get_binop_left(add_sub);
+ t2 = get_binop_right(add_sub);
+
+ /* 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);
+
+ irn = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
+
+ /* 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 expression 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 0;
+} /* reassoc_Mul */
+
+/**
+ * Reassociate Shl. We transform Shl(x, const) into Mul's if possible.
+ */
+static int reassoc_Shl(ir_node **node) {
+ ir_node *n = *node;
+ ir_node *c = get_Shl_right(n);
+ ir_node *x, *blk, *irn;
+ ir_mode *mode;
+ tarval *tv;
+
+ if (! is_Const(c))
+ return 0;
+
+ x = get_Shl_left(n);
+ mode = get_irn_mode(x);
+
+ tv = get_mode_one(mode);
+ tv = tarval_shl(tv, get_Const_tarval(c));
+
+ if (tv == tarval_bad)
+ return 0;
+
+ blk = get_nodes_block(n);
+ c = new_r_Const(current_ir_graph, blk, mode, tv);
+ irn = new_rd_Mul(get_irn_dbg_info(n), current_ir_graph, blk, x, c, mode);
+
+ if (irn != n) {
+ exchange(n, irn);
+ *node = irn;
+ return 1;
+ }
+ return 0;
+} /* reassoc_Shl */
+
+/**
+ * The walker for the reassociation.
+ */
+static void wq_walker(ir_node *n, void *env)
+{
+ walker_t *wenv = env;
+
+ set_irn_link(n, NULL);
+ if (is_no_Block(n)) {
+ ir_node *blk = get_nodes_block(n);
+
+ if (is_Block_dead(blk) || get_Block_dom_depth(blk) < 0) {
+ /* We are in a dead block, do not optimize or we may fall into an endless
+ loop. We check this here instead of requiring that all dead blocks are removed
+ which or cf_opt do not guarantee yet. */
+ return;
+ }
+ waitq_put(wenv->wq, n);
+ set_irn_link(n, wenv->wq);
+ }
+} /* wq_walker */