From 498dcd223be5ec2f021e75a4cf9ce948cc87c994 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Wed, 15 Jun 2005 12:27:50 +0000 Subject: [PATCH] typos fixed added transform_node_Abs() handling Confirm nodes renamed get_inverse_pnc() [r6020] --- ir/ir/iropt.c | 140 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 13 deletions(-) diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index baecd40f3..0f9c6411e 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -768,7 +768,7 @@ static ir_node *equivalent_node_Jmp(ir_node *n) static ir_node *equivalent_node_Cond(ir_node *n) { /* We do not evaluate Cond here as we replace it by a new node, a Jmp. - See cases for iro_Cond and iro_Proj in transform_node. */ + See cases for iro_Cond and iro_Proj in transform_node(). */ return n; } @@ -836,13 +836,13 @@ static ir_node *equivalent_node_left_zero(ir_node *n) #define equivalent_node_Rot equivalent_node_left_zero /** - * Er, a "symmetic unop", ie op(op(n)) = n. + * Optimize an "idempotent unary op", ie op(op(n)) = n. * * @fixme -(-a) == a, but might overflow two times. * We handle it anyway here but the better way would be a * flag. This would be needed for Pascal for instance. */ -static ir_node *equivalent_node_symmetric_unop(ir_node *n) +static ir_node *equivalent_node_idempotent_unop(ir_node *n) { ir_node *oldn = n; ir_node *pred = get_unop_op(n); @@ -856,11 +856,11 @@ static ir_node *equivalent_node_symmetric_unop(ir_node *n) } /* Not(Not(x)) == x */ -#define equivalent_node_Not equivalent_node_symmetric_unop +#define equivalent_node_Not equivalent_node_idempotent_unop /* --x == x */ /* ??? Is this possible or can --x raise an out of bounds exception if min =! max? */ -#define equivalent_node_Minus equivalent_node_symmetric_unop +#define equivalent_node_Minus equivalent_node_idempotent_unop /** * Optimize a * 1 = 1 * a = a. @@ -972,7 +972,7 @@ static ir_node *equivalent_node_And(ir_node *n) } /** - * Try to remove useless conv's: + * Try to remove useless Conv's: */ static ir_node *equivalent_node_Conv(ir_node *n) { @@ -1523,7 +1523,7 @@ static ir_node *transform_node_Div(ir_node *n) DBG_OPT_CSTEVAL(n, value); } - else /* Try architecture dependand optimization */ + else /* Try architecture dependend optimization */ value = arch_dep_replace_div_by_const(n); if (value != n) { @@ -1553,7 +1553,7 @@ static ir_node *transform_node_Mod(ir_node *n) DBG_OPT_CSTEVAL(n, value); } - else /* Try architecture dependand optimization */ + else /* Try architecture dependend optimization */ value = arch_dep_replace_mod_by_const(n); if (value != n) { @@ -1607,7 +1607,7 @@ static ir_node *transform_node_DivMod(ir_node *n) DBG_OPT_CSTEVAL(n, a); DBG_OPT_CSTEVAL(n, b); } - else { /* Try architecture dependand optimization */ + else { /* Try architecture dependend optimization */ arch_dep_replace_divmod_by_const(&a, &b, n); evaluated = a != NULL; } @@ -1630,6 +1630,119 @@ static ir_node *transform_node_DivMod(ir_node *n) return n; } + +/** + * Optimize Abs(x) => x if x is Confirmed >= 0 + * Optimize Abs(x) => -x if x is Confirmed <= 0 + */ +static ir_node *transform_node_Abs(ir_node *n) +{ + ir_node *oldn = n; + ir_node *a = get_Abs_op(n); + tarval *tv, *c; + ir_mode *mode; + pn_Cmp cmp, ncmp; + int do_minus = 0; + + if (get_irn_op(a) != op_Confirm) + return n; + + tv = value_of(get_Confirm_bound(n)); + if (tv == tarval_bad) + return n; + + mode = get_irn_mode(n); + + /* + * We can handle only >=, >, <, <= cases. + * We could handle == too, but this should not happen. + * + * Note that for integer modes we have a slightly better + * optimization possibilities, so we handle this + * different. + */ + cmp = get_Confirm_cmp(n); + + switch (cmp) { + case pn_Cmp_Lt: + /* + * must be x < c <= 1 to be useful if integer mode and -0 = 0 + * x < c <= 0 to be useful else + */ + case pn_Cmp_Le: + /* + * must be x <= c < 1 to be useful if integer mode and -0 = 0 + * x <= c < 0 to be useful else + */ + c = mode_is_int(mode) && mode_honor_signed_zeros(mode) ? + get_mode_one(mode) : get_mode_null(mode); + + ncmp = tarval_cmp(tv, c) ^ pn_Cmp_Eq; + if (cmp != ncmp) + return n; + + /* yep, we can replace by -x */ + do_minus = 1; + break; + + case pn_Cmp_Ge: + /* + * must be x >= c > -1 to be useful if integer mode + * x >= c >= 0 to be useful else + */ + case pn_Cmp_Gt: + /* + * must be x > c >= -1 to be useful if integer mode + * x > c >= 0 to be useful else + */ + if (mode_is_int(mode)) { + c = get_mode_minus_one(mode); + + ncmp = tarval_cmp(tv, c) ^ pn_Cmp_Eq; + if (cmp != ncmp) + return n; + } + else { + c = get_mode_minus_one(mode); + + ncmp = tarval_cmp(tv, c); + + if (ncmp != pn_Cmp_Eq && ncmp != pn_Cmp_Gt) + return n; + } + + /* yep, we can replace by x */ + do_minus = 0; + break; + + default: + return n; + } + + /* + * Ok, when we get here, we can replace the Abs + * by either x or -x. In the second case we eve could + * add a new Confirm. + * + * Note that -x would create a new node, so we could + * not run it in the equivalent_node() context. + */ + if (do_minus) { + ir_node *c; + + n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, + get_nodes_block(n), a, mode); + + c = new_Const(mode, tarval_neg(tv)); + n = new_r_Confirm(current_ir_graph, get_nodes_block(n), n, c, get_inversed_pnc(cmp)); + } + else { + n = a; + } + + return n; +} + /** * transform a Cond node */ @@ -1931,7 +2044,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) left = right; right = c; - proj_nr = get_swapped_pnc(proj_nr); + proj_nr = get_inversed_pnc(proj_nr); changed |= 1; } else if (left > right) { @@ -1940,7 +2053,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) left = right; right = t; - proj_nr = get_swapped_pnc(proj_nr); + proj_nr = get_inversed_pnc(proj_nr); changed |= 1; } @@ -1969,7 +2082,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) left = get_Minus_op(left); tv = tarval_sub(get_mode_null(mode), tv); - proj_nr = get_swapped_pnc(proj_nr); + proj_nr = get_inversed_pnc(proj_nr); changed |= 2; } @@ -2598,6 +2711,7 @@ static ir_op *firm_set_default_transform_node(ir_op *op) CASE(Div); CASE(Mod); CASE(DivMod); + CASE(Abs); CASE(Cond); CASE(Eor); CASE(Not); @@ -3055,7 +3169,7 @@ optimize_node (ir_node *n) /** common subexpression elimination **/ /* Checks whether n is already available. */ /* The block input is used to distinguish different subexpressions. Right - now all nodes are op_pin_state_pinned to blocks, i.e., the cse only finds common + now all nodes are op_pin_state_pinned to blocks, i.e., the CSE only finds common subexpressions within a block. */ if (get_opt_cse()) n = identify_cons (current_ir_graph->value_table, n); -- 2.20.1