From: Christoph Mallon Date: Sat, 25 Aug 2007 16:26:56 +0000 (+0000) Subject: Remove unnecessary conversions to wider modes as operands of Cmp. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=35f4f0e35663babdd1aaf67d4a5d3d3da48428d5;p=libfirm Remove unnecessary conversions to wider modes as operands of Cmp. Convert comparisons of boolean nodes to boolean expressions. [r15604] --- diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index d29ae08fc..92a9ec605 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -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;