? gcc/revert.patch ? gcc/txt00018.txt ? gcc/cp/parse.c ? gcc/cp/parse.h Index: gcc/fold-const.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v retrieving revision 1.305 diff -u -r1.305 fold-const.c --- gcc/fold-const.c 18 Sep 2003 15:05:53 -0000 1.305 +++ gcc/fold-const.c 20 Sep 2003 07:54:28 -0000 @@ -108,7 +108,6 @@ static tree fold_mathfn_compare (enum built_in_function, enum tree_code, tree, tree, tree); static tree fold_inf_compare (enum tree_code, tree, tree, tree); -static bool tree_swap_operands_p (tree, tree); /* The following constants represent a bit based encoding of GCC's comparison operators. This encoding simplifies transformations @@ -4977,49 +4976,6 @@ return NULL_TREE; } -/* Test whether it is preferable two swap two operands, ARG0 and - ARG1, for example because ARG0 is an integer constant and ARG1 - isn't. */ - -static bool -tree_swap_operands_p (tree arg0, tree arg1) -{ - STRIP_SIGN_NOPS (arg0); - STRIP_SIGN_NOPS (arg1); - - if (TREE_CODE (arg1) == INTEGER_CST) - return 0; - if (TREE_CODE (arg0) == INTEGER_CST) - return 1; - - if (TREE_CODE (arg1) == REAL_CST) - return 0; - if (TREE_CODE (arg0) == REAL_CST) - return 1; - - if (TREE_CODE (arg1) == COMPLEX_CST) - return 0; - if (TREE_CODE (arg0) == COMPLEX_CST) - return 1; - - if (TREE_CONSTANT (arg1)) - return 0; - if (TREE_CONSTANT (arg0)) - return 1; - - if (DECL_P (arg1)) - return 0; - if (DECL_P (arg0)) - return 1; - - if (TREE_CODE (arg1) == SAVE_EXPR) - return 0; - if (TREE_CODE (arg0) == SAVE_EXPR) - return 1; - - return 0; -} - /* Perform constant folding and related simplification of EXPR. The related simplifications include x*1 => x, x*0 => 0, etc., and application of the associative law. @@ -5079,7 +5035,8 @@ subop = arg0; if (subop != 0 && TREE_CODE (subop) != INTEGER_CST - && TREE_CODE (subop) != REAL_CST) + && TREE_CODE (subop) != REAL_CST + ) /* Note that TREE_CONSTANT isn't enough: static var addresses are constant but we can't do arithmetic on them. */ @@ -5131,8 +5088,16 @@ if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR || code == BIT_AND_EXPR) - && tree_swap_operands_p (arg0, arg1)) - return fold (build (code, type, arg1, arg0)); + && ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) != INTEGER_CST) + || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) != REAL_CST))) + { + tem = arg0; arg0 = arg1; arg1 = tem; + + if (t == orig_t) + t = copy_node (t); + TREE_OPERAND (t, 0) = arg0; + TREE_OPERAND (t, 1) = arg1; + } /* Now WINS is set as described above, ARG0 is the first operand of EXPR, @@ -6680,10 +6645,18 @@ RROTATE_EXPR by a new constant. */ if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST) { - tree tem = build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0); - tem = convert (TREE_TYPE (arg1), tem); - tem = const_binop (MINUS_EXPR, tem, arg1, 0); - return fold (build (RROTATE_EXPR, type, arg0, tem)); + if (t == orig_t) + t = copy_node (t); + TREE_SET_CODE (t, RROTATE_EXPR); + code = RROTATE_EXPR; + TREE_OPERAND (t, 1) = arg1 + = const_binop + (MINUS_EXPR, + convert (TREE_TYPE (arg1), + build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0)), + arg1, 0); + if (tree_int_cst_sgn (arg1) < 0) + return t; } /* If we have a rotate of a bit operation with the rotate count and @@ -6880,8 +6853,20 @@ case LE_EXPR: case GE_EXPR: /* If one arg is a real or integer constant, put it last. */ - if (tree_swap_operands_p (arg0, arg1)) - return fold (build (swap_tree_comparison (code), type, arg1, arg0)); + if ((TREE_CODE (arg0) == INTEGER_CST + && TREE_CODE (arg1) != INTEGER_CST) + || (TREE_CODE (arg0) == REAL_CST + && TREE_CODE (arg0) != REAL_CST)) + { + if (t == orig_t) + t = copy_node (t); + TREE_OPERAND (t, 0) = arg1; + TREE_OPERAND (t, 1) = arg0; + arg0 = TREE_OPERAND (t, 0); + arg1 = TREE_OPERAND (t, 1); + code = swap_tree_comparison (code); + TREE_SET_CODE (t, code); + } if (FLOAT_TYPE_P (TREE_TYPE (arg0))) { @@ -7138,12 +7123,16 @@ switch (code) { case GE_EXPR: + code = GT_EXPR; arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0); - return fold (build (GT_EXPR, type, arg0, arg1)); + t = build (code, type, TREE_OPERAND (t, 0), arg1); + break; case LT_EXPR: + code = LE_EXPR; arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0); - return fold (build (LE_EXPR, type, arg0, arg1)); + t = build (code, type, TREE_OPERAND (t, 0), arg1); + break; default: break; @@ -7186,17 +7175,24 @@ convert (type, integer_zero_node), arg0); case GE_EXPR: - return fold (build (EQ_EXPR, type, arg0, arg1)); - + code = EQ_EXPR; + if (t == orig_t) + t = copy_node (t); + TREE_SET_CODE (t, EQ_EXPR); + break; case LE_EXPR: return omit_one_operand (type, convert (type, integer_one_node), arg0); case LT_EXPR: - return fold (build (NE_EXPR, type, arg0, arg1)); + code = NE_EXPR; + if (t == orig_t) + t = copy_node (t); + TREE_SET_CODE (t, NE_EXPR); + break; /* The GE_EXPR and LT_EXPR cases above are not normally - reached because of previous transformations. */ + reached because of previous transformations. */ default: break; @@ -7206,11 +7202,15 @@ switch (code) { case GT_EXPR: + code = EQ_EXPR; arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0); - return fold (build (EQ_EXPR, type, arg0, arg1)); + t = build (code, type, TREE_OPERAND (t, 0), arg1); + break; case LE_EXPR: + code = NE_EXPR; arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0); - return fold (build (NE_EXPR, type, arg0, arg1)); + t = build (code, type, TREE_OPERAND (t, 0), arg1); + break; default: break; } @@ -7223,14 +7223,22 @@ convert (type, integer_zero_node), arg0); case LE_EXPR: - return fold (build (EQ_EXPR, type, arg0, arg1)); + code = EQ_EXPR; + if (t == orig_t) + t = copy_node (t); + TREE_SET_CODE (t, EQ_EXPR); + break; case GE_EXPR: return omit_one_operand (type, convert (type, integer_one_node), arg0); case GT_EXPR: - return fold (build (NE_EXPR, type, arg0, arg1)); + code = NE_EXPR; + if (t == orig_t) + t = copy_node (t); + TREE_SET_CODE (t, NE_EXPR); + break; default: break; @@ -7240,11 +7248,15 @@ switch (code) { case GE_EXPR: + code = NE_EXPR; arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0); - return fold (build (NE_EXPR, type, arg0, arg1)); + t = build (code, type, TREE_OPERAND (t, 0), arg1); + break; case LT_EXPR: + code = EQ_EXPR; arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0); - return fold (build (EQ_EXPR, type, arg0, arg1)); + t = build (code, type, TREE_OPERAND (t, 0), arg1); + break; default: break; } @@ -7477,17 +7489,16 @@ switch (code) { case EQ_EXPR: - if (! FLOAT_TYPE_P (TREE_TYPE (arg0)) - || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) - return constant_boolean_node (1, type); - break; - case GE_EXPR: case LE_EXPR: if (! FLOAT_TYPE_P (TREE_TYPE (arg0)) || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))) return constant_boolean_node (1, type); - return fold (build (EQ_EXPR, type, arg0, arg1)); + code = EQ_EXPR; + if (t == orig_t) + t = copy_node (t); + TREE_SET_CODE (t, code); + break; case NE_EXPR: /* For NE, we can only do this simplification if integer @@ -7768,6 +7779,34 @@ else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0)) return pedantic_omit_one_operand (type, arg1, arg0); + /* If the second operand is zero, invert the comparison and swap + the second and third operands. Likewise if the second operand + is constant and the third is not or if the third operand is + equivalent to the first operand of the comparison. */ + + if (integer_zerop (arg1) + || (TREE_CONSTANT (arg1) && ! TREE_CONSTANT (TREE_OPERAND (t, 2))) + || (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<' + && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), + TREE_OPERAND (t, 2), + TREE_OPERAND (arg0, 1)))) + { + /* See if this can be inverted. If it can't, possibly because + it was a floating-point inequality comparison, don't do + anything. */ + tem = invert_truthvalue (arg0); + + if (TREE_CODE (tem) != TRUTH_NOT_EXPR) + { + t = build (code, type, tem, + TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)); + arg0 = tem; + /* arg1 should be the first argument of the new T. */ + arg1 = TREE_OPERAND (t, 1); + STRIP_NOPS (arg1); + } + } + /* If we have A op B ? A : C, we may be able to convert this to a simpler expression, depending on the operation and the values of B and C. Signed zeros prevent all of these transformations, @@ -7943,8 +7982,9 @@ case EQ_EXPR: /* We can replace A with C1 in this case. */ arg1 = convert (type, TREE_OPERAND (arg0, 1)); - return fold (build (code, type, TREE_OPERAND (t, 0), arg1, - TREE_OPERAND (t, 2))); + t = build (code, type, TREE_OPERAND (t, 0), arg1, + TREE_OPERAND (t, 2)); + break; case LT_EXPR: /* If C1 is C2 + 1, this is min(A, C2). */ @@ -7994,7 +8034,11 @@ /* If the second operand is simpler than the third, swap them since that produces better jump optimization results. */ - if (tree_swap_operands_p (TREE_OPERAND (t, 1), TREE_OPERAND (t, 2))) + if ((TREE_CONSTANT (arg1) || DECL_P (arg1) + || TREE_CODE (arg1) == SAVE_EXPR) + && ! (TREE_CONSTANT (TREE_OPERAND (t, 2)) + || DECL_P (TREE_OPERAND (t, 2)) + || TREE_CODE (TREE_OPERAND (t, 2)) == SAVE_EXPR)) { /* See if this can be inverted. If it can't, possibly because it was a floating-point inequality comparison, don't do @@ -8002,8 +8046,14 @@ tem = invert_truthvalue (arg0); if (TREE_CODE (tem) != TRUTH_NOT_EXPR) - return fold (build (code, type, tem, - TREE_OPERAND (t, 2), TREE_OPERAND (t, 1))); + { + t = build (code, type, tem, + TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)); + arg0 = tem; + /* arg1 should be the first argument of the new T. */ + arg1 = TREE_OPERAND (t, 1); + STRIP_NOPS (arg1); + } } /* Convert A ? 1 : 0 to simply A. */