X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=0c6d0490ad907d5d3e6266247b69f04f72e16e56;hb=23ea16875f38dc0c067cce24f64b5c70f3acc496;hp=e51b85f872503da69ae09f41887e0a0c01174dfc;hpb=776440ae736bfbed96bb5e3e35f170992307909f;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index e51b85f87..0c6d0490a 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -897,6 +897,11 @@ static ir_node *equivalent_node_Add(ir_node *n) { ir_node *oldn = n; ir_node *left, *right; + ir_mode *mode = get_irn_mode(n); + + /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */ + if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)) + return n; n = equivalent_node_neutral_zero(n); if (n != oldn) @@ -910,7 +915,7 @@ static ir_node *equivalent_node_Add(ir_node *n) /* (a - x) + x */ n = get_Sub_left(left); - if (get_irn_mode(oldn) == get_irn_mode(n)) { + if (mode == get_irn_mode(n)) { DBG_OPT_ALGSIM1(oldn, left, right, n, FS_OPT_ADD_SUB); return n; } @@ -921,7 +926,7 @@ static ir_node *equivalent_node_Add(ir_node *n) /* x + (a - x) */ n = get_Sub_left(right); - if (get_irn_mode(oldn) == get_irn_mode(n)) { + if (mode == get_irn_mode(n)) { DBG_OPT_ALGSIM1(oldn, left, right, n, FS_OPT_ADD_SUB); return n; } @@ -967,40 +972,43 @@ static ir_node *equivalent_node_left_zero(ir_node *n) static ir_node *equivalent_node_Sub(ir_node *n) { ir_node *oldn = n; + ir_node *a, *b; + ir_mode *mode = get_irn_mode(n); - ir_node *a = get_Sub_left(n); - ir_node *b = get_Sub_right(n); + /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */ + if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)) + return n; + + a = get_Sub_left(n); + b = get_Sub_right(n); /* Beware: modes might be different */ if (classify_tarval(value_of(b)) == TV_CLASSIFY_NULL) { - if (get_irn_mode(n) == get_irn_mode(a)) { + if (mode == get_irn_mode(a)) { n = a; DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0); } } else if (get_irn_op(a) == op_Add) { - ir_mode *mode = get_irn_mode(n); - if (mode_wrap_around(mode)) { ir_node *left = get_Add_left(a); ir_node *right = get_Add_right(a); if (left == b) { - if (get_irn_mode(n) == get_irn_mode(right)) { + if (mode == get_irn_mode(right)) { n = right; DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB); } } else if (right == b) { - if (get_irn_mode(n) == get_irn_mode(left)) { + if (mode == get_irn_mode(left)) { n = left; DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB); } } } } - return n; } @@ -1039,7 +1047,6 @@ static ir_node *equivalent_node_idempotent_unop(ir_node *n) static ir_node *equivalent_node_Mul(ir_node *n) { ir_node *oldn = n; - ir_node *a = get_Mul_left(n); ir_node *b = get_Mul_right(n); @@ -1074,6 +1081,25 @@ static ir_node *equivalent_node_Div(ir_node *n) return n; } +/** + * Optimize a / 1.0 = a. + */ +static ir_node *equivalent_node_Quot(ir_node *n) { + ir_node *a = get_Quot_left(n); + ir_node *b = get_Quot_right(n); + + /* Div is not commutative. */ + if (classify_tarval(value_of(b)) == TV_CLASSIFY_ONE) { /* Quot(x, 1) == x */ + /* Turn Quot into a tuple (mem, bad, a) */ + ir_node *mem = get_Quot_mem(n); + turn_into_tuple(n, pn_Quot_max); + set_Tuple_pred(n, pn_Quot_M, mem); + set_Tuple_pred(n, pn_Quot_X_except, new_Bad()); /* no exception */ + set_Tuple_pred(n, pn_Quot_res, a); + } + return n; +} + /** * Optimize a / 1 = a. */ @@ -1157,6 +1183,9 @@ static ir_node *equivalent_node_Conv(ir_node *n) ir_mode *a_mode = get_irn_mode(a); if (n_mode == a_mode) { /* No Conv necessary */ + /* leave strict floating point Conv's */ + if (get_Conv_strict(n)) + return n; n = a; DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV); } else if (get_irn_op(a) == op_Conv) { /* Conv(Conv(b)) */ @@ -1627,6 +1656,7 @@ static ir_op_ops *firm_set_default_equivalent_node(opcode code, ir_op_ops *ops) CASE(Minus); CASE(Mul); CASE(Div); + CASE(Quot); CASE(DivMod); CASE(And); CASE(Conv); @@ -1902,6 +1932,11 @@ static ir_node *transform_node_Add(ir_node *n) HANDLE_BINOP_PHI(tarval_add, a,b,c); mode = get_irn_mode(n); + + /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */ + if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)) + return n; + if (mode_is_num(mode)) { if (a == b) { ir_node *block = get_irn_n(n, -1); @@ -2024,6 +2059,11 @@ static ir_node *transform_node_Sub(ir_node *n) HANDLE_BINOP_PHI(tarval_sub, a,b,c); mode = get_irn_mode(n); + + /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */ + if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic)) + return n; + if (mode_is_num(mode) && (classify_Const(a) == CNST_NULL)) { n = new_rd_Minus( get_irn_dbg_info(n), @@ -3188,8 +3228,8 @@ static ir_node *transform_node_shift(ir_node *n) static ir_node *transform_node_Shr(ir_node *n) { ir_node *c, *oldn = n; - ir_node *a = get_Shr_right(n); - ir_node *b = get_Shr_left(n); + ir_node *a = get_Shr_left(n); + ir_node *b = get_Shr_right(n); HANDLE_BINOP_PHI(tarval_shr, a, b, c); return transform_node_shift(n); @@ -3201,8 +3241,8 @@ static ir_node *transform_node_Shr(ir_node *n) static ir_node *transform_node_Shrs(ir_node *n) { ir_node *c, *oldn = n; - ir_node *a = get_Shrs_right(n); - ir_node *b = get_Shrs_left(n); + ir_node *a = get_Shrs_left(n); + ir_node *b = get_Shrs_right(n); HANDLE_BINOP_PHI(tarval_shrs, a, b, c); return transform_node_shift(n); @@ -3214,8 +3254,8 @@ static ir_node *transform_node_Shrs(ir_node *n) static ir_node *transform_node_Shl(ir_node *n) { ir_node *c, *oldn = n; - ir_node *a = get_Shl_right(n); - ir_node *b = get_Shl_left(n); + ir_node *a = get_Shl_left(n); + ir_node *b = get_Shl_right(n); HANDLE_BINOP_PHI(tarval_shl, a, b, c); return transform_node_shift(n); @@ -3461,8 +3501,7 @@ static int node_cmp_attr_Const(ir_node *a, ir_node *b) } /** Compares the attributes of two Proj nodes. */ -static int node_cmp_attr_Proj(ir_node *a, ir_node *b) -{ +static int node_cmp_attr_Proj(ir_node *a, ir_node *b) { return get_irn_proj_attr (a) != get_irn_proj_attr (b); } @@ -3495,8 +3534,7 @@ static int node_cmp_attr_SymConst(ir_node *a, ir_node *b) } /** Compares the attributes of two Call nodes. */ -static int node_cmp_attr_Call(ir_node *a, ir_node *b) -{ +static int node_cmp_attr_Call(ir_node *a, ir_node *b) { return (get_irn_call_attr(a) != get_irn_call_attr(b)); } @@ -3511,14 +3549,17 @@ static int node_cmp_attr_Sel(ir_node *a, ir_node *b) } /** Compares the attributes of two Phi nodes. */ -static int node_cmp_attr_Phi(ir_node *a, ir_node *b) -{ +static int node_cmp_attr_Phi(ir_node *a, ir_node *b) { return get_irn_phi_attr (a) != get_irn_phi_attr (b); } +/** Compares the attributes of two Conv nodes. */ +static int node_cmp_attr_Conv(ir_node *a, ir_node *b) { + return get_Conv_strict(a) != get_Conv_strict(b); +} + /** Compares the attributes of two Cast nodes. */ -static int node_cmp_attr_Cast(ir_node *a, ir_node *b) -{ +static int node_cmp_attr_Cast(ir_node *a, ir_node *b) { return get_Cast_type(a) != get_Cast_type(b); } @@ -3573,6 +3614,7 @@ static ir_op_ops *firm_set_default_node_cmp_attr(opcode code, ir_op_ops *ops) CASE(Call); CASE(Sel); CASE(Phi); + CASE(Conv); CASE(Cast); CASE(Load); CASE(Store); @@ -3642,7 +3684,7 @@ unsigned ir_node_hash(ir_node *node) h = 9*h + HASH_PTR(get_irn_mode(node)); } else if (node->op == op_SymConst) { /* special value for const, as they only differ in their symbol. */ - h = HASH_PTR(node->attr.i.sym.type_p); + h = HASH_PTR(node->attr.symc.sym.type_p); h = 9*h + HASH_PTR(get_irn_mode(node)); } else {