Remove unnecessary conversions to wider modes as operands of Cmp.
authorChristoph Mallon <christoph.mallon@gmx.de>
Sat, 25 Aug 2007 16:26:56 +0000 (16:26 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sat, 25 Aug 2007 16:26:56 +0000 (16:26 +0000)
Convert comparisons of boolean nodes to boolean expressions.

[r15604]

ir/ir/iropt.c

index d29ae08..92a9ec6 100644 (file)
@@ -3025,6 +3025,57 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) {
                break;
        }
 
+       /* Remove unnecessary conversions */
+       /* TODO handle constants */
+       if (is_Conv(left) && is_Conv(right)) {
+               ir_mode* mode        = get_irn_mode(left);
+               ir_node* op_left     = get_Conv_op(left);
+               ir_node* op_right    = get_Conv_op(right);
+               ir_mode* mode_left   = get_irn_mode(op_left);
+               ir_mode* mode_right  = get_irn_mode(op_right);
+
+               ir_fprintf(stderr, "%+F(%+F(%+F), %+F(%+F))? %d\n", n, left, op_left, right, op_right, smaller_mode(mode_left, mode));
+               if (smaller_mode(mode_left, mode) && smaller_mode(mode_right, mode)) {
+                       ir_graph* irg   = current_ir_graph;
+                       ir_node*  block = get_nodes_block(n);
+                       ir_node*  new_left;
+                       ir_node*  new_right;
+
+                       if (mode_left == mode_right) {
+                               new_left  = op_left;
+                               new_right = op_right;
+                       } else if (smaller_mode(mode_left, mode_right)) {
+                               new_left  = new_r_Conv(irg, block, op_left, mode_right);
+                               new_right = op_right;
+                       } else if (smaller_mode(mode_right, mode_left)) {
+                               new_left  = op_left;
+                               new_right = new_r_Conv(irg, block, op_right, mode_left);
+                       } else {
+                               goto no_remove_conv;
+                       }
+                       ir_fprintf(stderr, "%+F(%+F(%+F), %+F(%+F)) -> %+F(%+F, %+F)\n", n, left, op_left, right, op_right, n, new_left, new_right);
+                       left  = new_left;
+                       right = new_right;
+                       set_Cmp_left( n, left);
+                       set_Cmp_right(n, right);
+no_remove_conv:;
+               }
+       }
+
+       if (get_irn_mode(left) == mode_b) {
+               ir_graph* irg   = current_ir_graph;
+               ir_node*  block = get_nodes_block(n);
+
+               switch (proj_nr) {
+                       case pn_Cmp_Le: return new_r_Or( irg, block, new_r_Not(irg, block, left, mode_b), right, mode_b);
+                       case pn_Cmp_Lt: return new_r_And(irg, block, new_r_Not(irg, block, left, mode_b), right, mode_b);
+                       case pn_Cmp_Ge: return new_r_Or( irg, block, left, new_r_Not(irg, block, right, mode_b), mode_b);
+                       case pn_Cmp_Gt: return new_r_And(irg, block, left, new_r_Not(irg, block, right, mode_b), mode_b);
+                       case pn_Cmp_Lg: return new_r_Eor(irg, block, left, right, mode_b);
+                       case pn_Cmp_Eq: return new_r_Not(irg, block, new_r_Eor(irg, block, left, right, mode_b), mode_b);
+               }
+       }
+
        if (!get_opt_reassociation())
                return proj;