2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Reassociation
23 * @author Michael Beck
32 #include "irgraph_t.h"
36 #include "iropt_dbg.h"
39 #include "reassoc_t.h"
45 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
47 typedef struct _walker_t {
48 int changes; /**< set, if a reassociation take place */
49 waitq *wq; /**< a wait queue */
53 NO_CONSTANT = 0, /**< node is not constant */
54 REAL_CONSTANT = 1, /**< node is a Const that is suitable for constant folding */
55 REGION_CONST = 4 /**< node is a constant expression in the current context,
56 use 4 here to simplify implementation of get_comm_Binop_ops() */
60 * returns whether a node is constant ie is a constant or
61 * is loop invariant (called region constant)
63 * @param n the node to be checked for constant
64 * @param block a block that might be in a loop
66 static const_class_t get_const_class(ir_node *n, ir_node *block)
68 ir_op *op = get_irn_op(n);
73 /* although SymConst's are of course real constant, we cannot
74 fold them, so handle them like region constants */
75 if (op == op_SymConst)
79 * Beware: Bad nodes are always loop-invariant, but
80 * cannot handled in later code, so filter them here.
82 if (! is_Bad(n) && is_loop_invariant(n, block))
86 } /* get_const_class */
89 * returns the operands of a commutative bin-op, if one operand is
90 * a region constant, it is returned as the second one.
92 * Beware: Real constants must be returned with higher priority than
93 * region constants, because they might be folded.
95 static void get_comm_Binop_ops(ir_node *binop, ir_node **a, ir_node **c)
97 ir_node *op_a = get_binop_left(binop);
98 ir_node *op_b = get_binop_right(binop);
99 ir_node *block = get_nodes_block(binop);
100 int class_a = get_const_class(op_a, block);
101 int class_b = get_const_class(op_b, block);
103 assert(is_op_commutative(get_irn_op(binop)));
105 switch (class_a + 2*class_b) {
106 case REAL_CONSTANT + 2*REAL_CONSTANT:
107 /* if both are constants, one might be a
108 * pointer constant like NULL, return the other
110 if (mode_is_reference(get_irn_mode(op_a))) {
118 case REAL_CONSTANT + 2*NO_CONSTANT:
119 case REAL_CONSTANT + 2*REGION_CONST:
120 case REGION_CONST + 2*NO_CONSTANT:
129 } /* get_comm_Binop_ops */
132 * reassociate a Sub: x - c = x + (-c)
134 static int reassoc_Sub(ir_node **in)
137 ir_node *right = get_Sub_right(n);
138 ir_mode *rmode = get_irn_mode(right);
141 /* cannot handle SubIs(P, P) */
142 if (mode_is_reference(rmode))
145 block = get_nodes_block(n);
148 * convert x - c => x + (-c)
150 if (get_const_class(right, block) == REAL_CONSTANT) {
151 ir_node *left = get_Sub_left(n);
156 switch (get_const_class(left, block)) {
158 irn = optimize_in_place(n);
168 /* already constant, nothing to do */
172 if (!get_opt_overflow_unsafe_transform() && !mode_is_signed(rmode)) {
173 /* do not transform unsigned, overflow will occur */
177 mode = get_irn_mode(n);
178 dbi = get_irn_dbg_info(n);
180 /* Beware of SubP(P, Is) */
181 irn = new_rd_Minus(dbi, current_ir_graph, block, right, rmode);
182 irn = new_rd_Add(dbi, current_ir_graph, block, left, irn, mode);
184 DBG((dbg, LEVEL_5, "Applied: %n - %n => %n + (-%n)\n",
185 get_Sub_left(n), right, get_Sub_left(n), right));
198 /** Retrieve a mode from the operands. We need this, because
199 * Add and Sub are allowed to operate on (P, Is)
201 static ir_mode *get_mode_from_ops(ir_node *op1, ir_node *op2)
205 m1 = get_irn_mode(op1);
206 if (mode_is_reference(m1))
209 m2 = get_irn_mode(op2);
210 if (mode_is_reference(m2))
216 } /* get_mode_from_ops */
219 * reassociate a commutative Binop
221 * BEWARE: this rule leads to a potential loop, if
222 * two operands are region constants and the third is a
223 * constant, so avoid this situation.
225 static int reassoc_commutative(ir_node **node)
228 ir_op *op = get_irn_op(n);
229 ir_node *block = get_nodes_block(n);
232 get_comm_Binop_ops(n, &t1, &c1);
234 if (get_irn_op(t1) == op) {
236 const_class_t c_c1, c_c2, c_t2;
238 get_comm_Binop_ops(t1, &t2, &c2);
240 /* do not optimize Bad nodes, will fail later */
244 c_c1 = get_const_class(c1, block);
245 c_c2 = get_const_class(c2, block);
246 c_t2 = get_const_class(t2, block);
248 if ( ((c_c1 > NO_CONSTANT) & (c_t2 > NO_CONSTANT)) &&
249 ((((c_c1 ^ c_c2 ^ c_t2) & REGION_CONST) == 0) || ((c_c1 & c_c2 & c_t2) == REGION_CONST)) ) {
250 /* All three are constant and either all are constant expressions or two of them are:
251 * then applying this rule would lead into a cycle
253 * Note that if t2 is a constant so is c2 hence we save one test.
258 if ((c_c1 != NO_CONSTANT) /* & (c_c2 != NO_CONSTANT) */) {
259 /* handles rules R7, R8, R9, R10:
260 * convert c1 .OP. (c2 .OP. x) => x .OP. (c1 .OP. c2)
262 ir_node *irn, *in[2];
263 ir_mode *mode, *mode_c1 = get_irn_mode(c1), *mode_c2 = get_irn_mode(c2);
265 /* It might happen, that c1 and c2 have different modes, for instance Is and Iu.
268 if (mode_c1 != mode_c2) {
269 if (mode_is_int(mode_c1) && mode_is_int(mode_c2)) {
270 /* get the bigger one */
271 if (get_mode_size_bits(mode_c1) > get_mode_size_bits(mode_c2))
272 c2 = new_r_Conv(current_ir_graph, block, c2, mode_c1);
273 else if (get_mode_size_bits(mode_c1) < get_mode_size_bits(mode_c2))
274 c1 = new_r_Conv(current_ir_graph, block, c1, mode_c2);
276 /* Try to cast the real const */
277 if (c_c1 == REAL_CONSTANT)
278 c1 = new_r_Conv(current_ir_graph, block, c1, mode_c2);
280 c2 = new_r_Conv(current_ir_graph, block, c2, mode_c1);
288 mode = get_mode_from_ops(in[0], in[1]);
289 in[1] = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
292 mode = get_mode_from_ops(in[0], in[1]);
293 irn = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
295 DBG((dbg, LEVEL_5, "Applied: %n .%s. (%n .%s. %n) => %n .%s. (%n .%s. %n)\n",
296 c1, get_irn_opname(n), c2, get_irn_opname(n), t2,
297 t2, get_irn_opname(n), c1, get_irn_opname(n), c2));
299 * In some rare cases it can really happen that we get the same node back.
300 * This might be happen in dead loops, were the Phi nodes are already gone away.
311 } /* reassoc_commutative */
313 #define reassoc_Add reassoc_commutative
314 #define reassoc_And reassoc_commutative
315 #define reassoc_Or reassoc_commutative
316 #define reassoc_Eor reassoc_commutative
319 * Reassociate using commutative law for Mul and distributive law for Mul and Add/Sub:
321 static int reassoc_Mul(ir_node **node)
324 ir_node *add_sub, *c;
327 if (reassoc_commutative(&n))
330 get_comm_Binop_ops(n, &add_sub, &c);
331 op = get_irn_op(add_sub);
333 /* handles rules R11, R12, R13, R14, R15, R16, R17, R18, R19, R20 */
334 if (op == op_Add || op == op_Sub) {
335 ir_mode *mode = get_irn_mode(n);
336 ir_node *irn, *block, *t1, *t2, *in[2];
338 block = get_nodes_block(n);
339 t1 = get_binop_left(add_sub);
340 t2 = get_binop_right(add_sub);
342 /* we can only multiplication rules on integer arithmetic */
343 if (mode_is_int(get_irn_mode(t1)) && mode_is_int(get_irn_mode(t2))) {
344 in[0] = new_rd_Mul(NULL, current_ir_graph, block, c, t1, mode);
345 in[1] = new_rd_Mul(NULL, current_ir_graph, block, c, t2, mode);
347 irn = optimize_node(new_ir_node(NULL, current_ir_graph, block, op, mode, 2, in));
349 /* In some cases it might happen that the new irn is equal the old one, for
351 * (x - 1) * y == x * y - y
352 * will be transformed back by simpler optimization
353 * We could switch simple optimizations off, but this only happens iff y
354 * is a loop-invariant expression and that it is not clear if the new form
356 * So, we let the old one.
359 DBG((dbg, LEVEL_5, "Applied: (%n .%s. %n) %n %n => (%n %n %n) .%s. (%n %n %n)\n",
360 t1, get_op_name(op), t2, n, c, t1, n, c, get_op_name(op), t2, n, c));
372 * Reassociate Shl. We transform Shl(x, const) into Mul's if possible.
374 static int reassoc_Shl(ir_node **node) {
376 ir_node *c = get_Shl_right(n);
377 ir_node *x, *blk, *irn;
385 mode = get_irn_mode(x);
387 tv = get_mode_one(mode);
388 tv = tarval_shl(tv, get_Const_tarval(c));
390 if (tv == tarval_bad)
393 blk = get_nodes_block(n);
394 c = new_r_Const(current_ir_graph, blk, mode, tv);
395 irn = new_rd_Mul(get_irn_dbg_info(n), current_ir_graph, blk, x, c, mode);
406 * The walker for the reassociation.
408 static void wq_walker(ir_node *n, void *env)
410 walker_t *wenv = env;
412 set_irn_link(n, NULL);
413 if (is_no_Block(n)) {
414 ir_node *blk = get_nodes_block(n);
416 if (is_Block_dead(blk) || get_Block_dom_depth(blk) < 0) {
417 /* We are in a dead block, do not optimize or we may fall into an endless
418 loop. We check this here instead of requiring that all dead blocks are removed
419 which or cf_opt do not guarantee yet. */
422 waitq_put(wenv->wq, n);
423 set_irn_link(n, wenv->wq);
428 * The walker for the reassociation.
430 static void do_reassociation(walker_t *wenv)
436 while (! waitq_empty(wenv->wq)) {
437 n = waitq_get(wenv->wq);
438 set_irn_link(n, NULL);
440 blk = get_nodes_block(n);
441 if (is_Block_dead(blk) || get_Block_dom_depth(blk) < 0) {
442 /* We are in a dead block, do not optimize or we may fall into an endless
443 loop. We check this here instead of requiring that all dead blocks are removed
444 which or cf_opt do not guarantee yet. */
451 /* reassociation must run until a fixpoint is reached. */
454 ir_op *op = get_irn_op(n);
455 ir_mode *mode = get_irn_mode(n);
459 /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
460 if (mode_is_float(mode) && get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)
463 if (op->ops.reassociate) {
464 res = op->ops.reassociate(&n);
471 wenv->changes |= changed;
474 for (i = get_irn_arity(n) - 1; i >= 0; --i) {
475 ir_node *pred = get_irn_n(n, i);
477 if (get_irn_link(pred) != wenv->wq) {
478 waitq_put(wenv->wq, pred);
479 set_irn_link(pred, wenv->wq);
484 } /* do_reassociation */
487 * Returns the earliest were a,b are available.
488 * Note that we know that a, b both dominate
489 * the block of the previous operation, so one must dominate the other.
491 * If the earliest block is the start block, return curr_blk instead
493 static ir_node *earliest_block(ir_node *a, ir_node *b, ir_node *curr_blk) {
494 ir_node *blk_a = get_nodes_block(a);
495 ir_node *blk_b = get_nodes_block(b);
498 /* if blk_a != blk_b, one must dominate the other */
499 if (block_dominates(blk_a, blk_b))
503 if (res == get_irg_start_block(current_ir_graph))
506 } /* earliest_block */
509 * Checks whether a node is a Constant expression.
510 * The following trees are constant expressions:
512 * Const, SymConst, Const + SymConst
514 * Handling SymConsts as const might be not a good idea for all
517 static int is_constant_expr(ir_node *irn) {
520 switch (get_irn_opcode(irn)) {
525 op = get_irn_op(get_Add_left(irn));
526 if (op != op_Const && op != op_SymConst)
528 op = get_irn_op(get_Add_right(irn));
529 if (op != op_Const && op != op_SymConst)
535 } /* is_constant_expr */
538 * Apply distributive Law for Mul and Add/Sub
540 static int reverse_rule_distributive(ir_node **node) {
542 ir_node *left = get_binop_left(n);
543 ir_node *right = get_binop_right(n);
544 ir_node *x, *blk, *curr_blk;
545 ir_node *a, *b, *irn;
550 op = get_irn_op(left);
551 if (op != get_irn_op(right))
555 x = get_Shl_right(left);
557 if (x == get_Shl_right(right)) {
558 /* (a << x) +/- (b << x) ==> (a +/- b) << x */
559 a = get_Shl_left(left);
560 b = get_Shl_left(right);
563 } else if (op == op_Mul) {
564 x = get_Mul_left(left);
566 if (x == get_Mul_left(right)) {
567 /* (x * a) +/- (x * b) ==> (a +/- b) * x */
568 a = get_Mul_right(left);
569 b = get_Mul_right(right);
571 } else if (x == get_Mul_right(right)) {
572 /* (x * a) +/- (b * x) ==> (a +/- b) * x */
573 a = get_Mul_right(left);
574 b = get_Mul_left(right);
578 x = get_Mul_right(left);
580 if (x == get_Mul_right(right)) {
581 /* (a * x) +/- (b * x) ==> (a +/- b) * x */
582 a = get_Mul_left(left);
583 b = get_Mul_left(right);
585 } else if (x == get_Mul_left(right)) {
586 /* (a * x) +/- (x * b) ==> (a +/- b) * x */
587 a = get_Mul_left(left);
588 b = get_Mul_right(right);
595 curr_blk = get_nodes_block(n);
597 blk = earliest_block(a, b, curr_blk);
599 dbg = get_irn_dbg_info(n);
600 mode = get_irn_mode(n);
603 irn = new_rd_Add(dbg, current_ir_graph, blk, a, b, mode);
605 irn = new_rd_Sub(dbg, current_ir_graph, blk, a, b, mode);
607 blk = earliest_block(irn, x, curr_blk);
610 irn = new_rd_Mul(dbg, current_ir_graph, blk, irn, x, mode);
612 irn = new_rd_Shl(dbg, current_ir_graph, blk, irn, x, mode);
617 } /* reverse_rule_distributive */
620 * Move Constants towards the root.
622 static int move_consts_up(ir_node **node) {
625 ir_node *l, *r, *a, *b, *c, *blk, *irn, *in[2];
626 ir_mode *mode, *ma, *mb;
629 l = get_binop_left(n);
630 r = get_binop_right(n);
632 /* check if one is already a constant expression */
633 if (is_constant_expr(l) || is_constant_expr(r))
636 dbg = get_irn_dbg_info(n);
638 if (get_irn_op(l) == op) {
639 /* (a .op. b) .op. r */
640 a = get_binop_left(l);
641 b = get_binop_right(l);
643 if (is_constant_expr(a)) {
644 /* (C .op. b) .op. r ==> (r .op. b) .op. C */
647 blk = get_nodes_block(l);
648 dbg = dbg == get_irn_dbg_info(l) ? dbg : NULL;
650 } else if (is_constant_expr(b)) {
651 /* (a .op. C) .op. r ==> (a .op. r) .op. C */
654 blk = get_nodes_block(l);
655 dbg = dbg == get_irn_dbg_info(l) ? dbg : NULL;
658 } else if (get_irn_op(r) == op) {
659 /* l .op. (a .op. b) */
660 a = get_binop_left(r);
661 b = get_binop_right(r);
663 if (is_constant_expr(a)) {
664 /* l .op. (C .op. b) ==> (l .op. b) .op. C */
667 blk = get_nodes_block(r);
668 dbg = dbg == get_irn_dbg_info(r) ? dbg : NULL;
670 } else if (is_constant_expr(b)) {
671 /* l .op. (a .op. C) ==> (a .op. l) .op. C */
674 blk = get_nodes_block(r);
675 dbg = dbg == get_irn_dbg_info(r) ? dbg : NULL;
682 /* In some cases a and b might be both of different integer mode, and c a SymConst.
683 * in that case we could either
684 * 1.) cast into unsigned mode
686 * we implement the second here
688 ma = get_irn_mode(a);
689 mb = get_irn_mode(b);
690 if (ma != mb && mode_is_int(ma) && mode_is_int(mb))
693 /* check if (a .op. b) can be calculated in the same block is the old instruction */
694 if (! block_dominates(get_nodes_block(a), blk))
696 if (! block_dominates(get_nodes_block(b), blk))
702 mode = get_mode_from_ops(a, b);
703 in[0] = irn = optimize_node(new_ir_node(dbg, current_ir_graph, blk, op, mode, 2, in));
705 /* beware: optimize_node might have changed the opcode, check again */
706 if (is_Add(irn) || is_Sub(irn)) {
707 reverse_rule_distributive(&in[0]);
711 mode = get_mode_from_ops(in[0], in[1]);
712 irn = optimize_node(new_ir_node(dbg, current_ir_graph, blk, op, mode, 2, in));
717 } /* move_consts_up */
720 * Apply the rules in reverse order, removing code that was not collapsed
722 static void reverse_rules(ir_node *node, void *env) {
723 walker_t *wenv = env;
724 ir_mode *mode = get_irn_mode(node);
727 /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
728 if (mode_is_float(mode) && get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)
732 ir_op *op = get_irn_op(node);
735 if (is_op_commutative(op)) {
736 wenv->changes |= res = move_consts_up(&node);
738 /* beware: move_consts_up might have changed the opcode, check again */
739 if (is_Add(node) || is_Sub(node)) {
740 wenv->changes |= res = reverse_rule_distributive(&node);
746 * do the reassociation
748 void optimize_reassociation(ir_graph *irg)
751 irg_loopinfo_state state;
754 assert(get_irg_phase_state(irg) != phase_building);
755 assert(get_irg_pinned(irg) != op_pin_state_floats &&
756 "Reassociation needs pinned graph to work properly");
758 rem = current_ir_graph;
759 current_ir_graph = irg;
761 /* we use dominance to detect dead blocks */
765 * Calculate loop info, so we could identify loop-invariant
766 * code and threat it like a constant.
767 * We only need control flow loops here but can handle generic
768 * INTRA info as well.
770 state = get_irg_loopinfo_state(irg);
771 if ((state & loopinfo_inter) ||
772 (state & (loopinfo_constructed | loopinfo_valid)) != (loopinfo_constructed | loopinfo_valid))
773 construct_cf_backedges(irg);
776 env.wq = new_waitq();
778 /* disable some optimizations while reassoc is running to prevent endless loops */
779 set_reassoc_running(1);
781 /* now we have collected enough information, optimize */
782 irg_walk_graph(irg, NULL, wq_walker, &env);
783 do_reassociation(&env);
785 /* reverse those rules that do not result in collapsed constants */
786 irg_walk_graph(irg, NULL, reverse_rules, &env);
788 set_reassoc_running(0);
790 /* Handle graph state */
792 set_irg_outs_inconsistent(irg);
793 set_irg_loopinfo_inconsistent(irg);
797 current_ir_graph = rem;
798 } /* optimize_reassociation */
800 /* Sets the default reassociation operation for an ir_op_ops. */
801 ir_op_ops *firm_set_default_reassoc(ir_opcode code, ir_op_ops *ops)
803 #define CASE(a) case iro_##a: ops->reassociate = reassoc_##a; break
819 } /* firm_set_default_reassoc */
821 /* initialize the reassociation by adding operations to some opcodes */
822 void firm_init_reassociation(void)
824 FIRM_DBG_REGISTER(dbg, "firm.opt.reassoc");
825 } /* firm_init_reassociation */