X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Freassoc.c;h=e5ac876263f326c1bb58fe7a72e8930c440632e4;hb=1604345e0da0d5a74037dee6a4fa13bb70261ad3;hp=3dce3760f6ee3d496c3f22d2444a6dc633d99ad5;hpb=cef08727c22b118ad9d69a9cc7302f3c74caa268;p=libfirm diff --git a/ir/opt/reassoc.c b/ir/opt/reassoc.c index 3dce3760f..e5ac87626 100644 --- a/ir/opt/reassoc.c +++ b/ir/opt/reassoc.c @@ -87,8 +87,20 @@ static void get_comm_Binop_ops(ir_node *binop, ir_node **a, ir_node **c) assert(is_op_commutative(get_irn_op(binop))); switch (class_a + 2*class_b) { - case REAL_CONSTANT + 2*NO_CONSTANT: case REAL_CONSTANT + 2*REAL_CONSTANT: + /* if both are constants, one might be a + * pointer constant like NULL, return the other + */ + if (mode_is_reference(get_irn_mode(op_a))) { + *a = op_a; + *c = op_b; + } + else { + *a = op_b; + *c = op_a; + } + break; + case REAL_CONSTANT + 2*NO_CONSTANT: case REAL_CONSTANT + 2*REGION_CONST: case REGION_CONST + 2*NO_CONSTANT: *a = op_b; @@ -107,14 +119,15 @@ static void get_comm_Binop_ops(ir_node *binop, ir_node **a, ir_node **c) static int reassoc_Sub(ir_node **in) { ir_node *n = *in; - ir_node *block = get_nodes_block(n); ir_node *right = get_Sub_right(n); + ir_mode *rmode = get_irn_mode(right); + ir_node *block; - /* FIXME: Do not apply this rule for unsigned Sub's because our code - * generation is currently buggy :-) - */ - if (! mode_is_signed(get_irn_mode(n))) - return 0; + /* cannot handle SubIs(P, P) */ + if (mode_is_reference(rmode)) + return 0; + + block = get_nodes_block(n); /* handles rule R6: * convert x - c => (-c) + x @@ -124,9 +137,8 @@ static int reassoc_Sub(ir_node **in) * */ if (get_const_class(right, block) == REAL_CONSTANT) { ir_node *left = get_Sub_left(n); - ir_node *block = get_nodes_block(n); - ir_mode *mode = get_irn_mode(n); - dbg_info *dbi = get_irn_dbg_info(n); + ir_mode *mode; + dbg_info *dbi; ir_node *irn, *c; switch (get_const_class(left, block)) { @@ -144,9 +156,12 @@ static int reassoc_Sub(ir_node **in) /* already constant, nothing to do */ return 0; } + mode = get_irn_mode(n); + dbi = get_irn_dbg_info(n); - c = new_r_Const(current_ir_graph, block, mode, get_mode_null(mode)); - irn = new_rd_Sub(dbi, current_ir_graph, block, c, right, mode); + /* Beware of SubP(P, Is) */ + c = new_r_Const(current_ir_graph, block, rmode, get_mode_null(rmode)); + irn = new_rd_Sub(dbi, current_ir_graph, block, c, right, rmode); irn = new_rd_Add(dbi, current_ir_graph, block, left, irn, get_irn_mode(n)); @@ -352,8 +367,11 @@ static void do_reassociation(ir_node *n, void *env) res = 0; - /* reassociation works only for integer or reference modes */ - if (op->ops.reassociate && (mode_is_int(mode) || mode_is_reference(mode))) { + /* 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) + break; + + if (op->ops.reassociate) { res = op->ops.reassociate(&n); wenv->changes |= res;