X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=03eeb57addb6c0dc35f22cb3e03915d919476c0f;hb=128d686096cf3f9945d31b6bc9d36bd96ff76955;hp=8a8716f55f6ef9ccfc399f38b0f8366ef90b4a72;hpb=dcbcc971a32a05cb37805ea6886d5f8c34b910ef;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 8a8716f55..03eeb57ad 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -3107,27 +3107,6 @@ static ir_node *transform_bitwise_distributive(ir_node *n, return n; } -int ir_is_equality_cmp_0(const ir_node *node) -{ - ir_relation relation = get_Cmp_relation(node); - ir_node *left = get_Cmp_left(node); - ir_node *right = get_Cmp_right(node); - ir_mode *mode = get_irn_mode(left); - - /* this probably makes no sense if unordered is involved */ - assert(!mode_is_float(mode)); - - if (!is_Const(right) || !is_Const_null(right)) - return false; - if (relation == ir_relation_equal) - return true; - if (mode_is_signed(mode) && relation == ir_relation_less_greater) - return true; - if (relation == ir_relation_greater) - return true; - return false; -} - /** * Create a 0 constant of given mode. */ @@ -3151,33 +3130,35 @@ static ir_node *transform_node_And(ir_node *n) vrp_attr *a_vrp, *b_vrp; if (is_Cmp(a) && is_Cmp(b)) { - ir_node *a_left = get_Cmp_left(a); - ir_node *a_right = get_Cmp_left(a); - ir_node *b_left = get_Cmp_left(b); - ir_node *b_right = get_Cmp_right(b); + ir_node *a_left = get_Cmp_left(a); + ir_node *a_right = get_Cmp_right(a); + ir_node *b_left = get_Cmp_left(b); + ir_node *b_right = get_Cmp_right(b); + ir_relation a_relation = get_Cmp_relation(a); + ir_relation b_relation = get_Cmp_relation(b); /* we can combine the relations of two compares with the same * operands */ if (a_left == b_left && b_left == b_right) { dbg_info *dbgi = get_irn_dbg_info(n); ir_node *block = get_nodes_block(n); - ir_relation a_relation = get_Cmp_relation(a); - ir_relation b_relation = get_Cmp_relation(b); ir_relation new_relation = a_relation & b_relation; return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation); } - /* Cmp(a, 0) and Cmp(b,0) can be optimized to Cmp(a|b, 0) */ - if (ir_is_equality_cmp_0(a) && ir_is_equality_cmp_0(b) - && (get_Cmp_relation(a) & ir_relation_equal) == (get_Cmp_relation(b) & ir_relation_equal)) { - dbg_info *dbgi = get_irn_dbg_info(n); - ir_node *block = get_nodes_block(n); - ir_relation relation = get_Cmp_relation(a); - ir_mode *mode = get_irn_mode(a_left); - ir_node *n_b_left = get_irn_mode(b_left) != mode ? - new_rd_Conv(dbgi, block, b_left, mode) : b_left; - ir_node *or = new_rd_Or(dbgi, block, a_left, n_b_left, mode); - ir_graph *irg = get_irn_irg(n); - ir_node *zero = create_zero_const(irg, mode); - return new_rd_Cmp(dbgi, block, or, zero, relation); + /* Cmp(a==0) and Cmp(b==0) can be optimized to Cmp(a|b==0) */ + if (is_Const(a_right) && is_Const_null(a_right) + && is_Const(b_right) && is_Const_null(b_right) + && a_relation == b_relation && a_relation == ir_relation_equal + && !mode_is_float(get_irn_mode(a_left)) + && !mode_is_float(get_irn_mode(b_left))) { + dbg_info *dbgi = get_irn_dbg_info(n); + ir_node *block = get_nodes_block(n); + ir_mode *mode = get_irn_mode(a_left); + ir_node *n_b_left = get_irn_mode(b_left) != mode ? + new_rd_Conv(dbgi, block, b_left, mode) : b_left; + ir_node *or = new_rd_Or(dbgi, block, a_left, n_b_left, mode); + ir_graph *irg = get_irn_irg(n); + ir_node *zero = create_zero_const(irg, mode); + return new_rd_Cmp(dbgi, block, or, zero, ir_relation_equal); } } @@ -4821,6 +4802,22 @@ static ir_node *transform_node_Or_Rotl(ir_node *irn_or) return n; } /* transform_node_Or_Rotl */ +static bool is_cmp_unequal_zero(const ir_node *node) +{ + ir_relation relation = get_Cmp_relation(node); + ir_node *left = get_Cmp_left(node); + ir_node *right = get_Cmp_right(node); + ir_mode *mode = get_irn_mode(left); + + if (!is_Const(right) || !is_Const_null(right)) + return false; + if (mode_is_signed(mode)) { + return relation == ir_relation_less_greater; + } else { + return relation == ir_relation_greater; + } +} + /** * Transform an Or. */ @@ -4858,6 +4855,20 @@ static ir_node *transform_node_Or(ir_node *n) ir_relation new_relation = a_relation | b_relation; return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation); } + /* Cmp(a!=0) or Cmp(b!=0) => Cmp(a|b != 0) */ + if (is_cmp_unequal_zero(a) && is_cmp_unequal_zero(b) + && !mode_is_float(get_irn_mode(a_left)) + && !mode_is_float(get_irn_mode(b_left))) { + ir_graph *irg = get_irn_irg(n); + dbg_info *dbgi = get_irn_dbg_info(n); + ir_node *block = get_nodes_block(n); + ir_mode *mode = get_irn_mode(a_left); + ir_node *n_b_left = get_irn_mode(b_left) != mode ? + new_rd_Conv(dbgi, block, b_left, mode) : b_left; + ir_node *or = new_rd_Or(dbgi, block, a_left, n_b_left, mode); + ir_node *zero = create_zero_const(irg, mode); + return new_rd_Cmp(dbgi, block, or, zero, ir_relation_less_greater); + } } mode = get_irn_mode(n); @@ -5730,9 +5741,6 @@ static ir_node *transform_node_Call(ir_node *call) } var = get_method_variadicity(mtp); set_method_variadicity(ctp, var); - if (var == variadicity_variadic) { - set_method_first_variadic_param_index(ctp, get_method_first_variadic_param_index(mtp) + 1); - } /* When we resolve a trampoline, the function must be called by a this-call */ set_method_calling_convention(ctp, get_method_calling_convention(mtp) | cc_this_call); set_method_additional_properties(ctp, get_method_additional_properties(mtp)); @@ -5929,7 +5937,7 @@ static int node_cmp_attr_Load(const ir_node *a, const ir_node *b) /* NEVER do CSE on volatile Loads */ return 1; /* do not CSE Loads with different alignment. Be conservative. */ - if (get_Load_align(a) != get_Load_align(b)) + if (get_Load_unaligned(a) != get_Load_unaligned(b)) return 1; return get_Load_mode(a) != get_Load_mode(b); @@ -5939,7 +5947,7 @@ static int node_cmp_attr_Load(const ir_node *a, const ir_node *b) static int node_cmp_attr_Store(const ir_node *a, const ir_node *b) { /* do not CSE Stores with different alignment. Be conservative. */ - if (get_Store_align(a) != get_Store_align(b)) + if (get_Store_unaligned(a) != get_Store_unaligned(b)) return 1; /* NEVER do CSE on volatile Stores */ @@ -6225,7 +6233,7 @@ ir_node *identify_remember(ir_node *n) if (nn != n) { /* n is reachable again */ - edges_node_revival(nn, get_irn_irg(nn)); + edges_node_revival(nn); } return nn; @@ -6389,7 +6397,7 @@ ir_node *optimize_node(ir_node *n) Run always for transformation induced Bads. */ n = gigo(n); if (n != oldn) { - edges_node_deleted(oldn, irg); + edges_node_deleted(oldn); /* We found an existing, better node, so we can deallocate the old node. */ irg_kill_node(irg, oldn); @@ -6420,7 +6428,7 @@ ir_node *optimize_node(ir_node *n) memcpy(oldn->in, n->in, ARR_LEN(n->in) * sizeof(n->in[0])); /* note the inplace edges module */ - edges_node_deleted(n, irg); + edges_node_deleted(n); /* evaluation was successful -- replace the node. */ irg_kill_node(irg, n); @@ -6451,7 +6459,7 @@ ir_node *optimize_node(ir_node *n) n = identify_cons(n); if (n != oldn) { - edges_node_deleted(oldn, irg); + edges_node_deleted(oldn); /* We found an existing, better node, so we can deallocate the old node. */ irg_kill_node(irg, oldn);