From: Richard Kenner Date: Sat, 26 Jun 1993 15:05:12 +0000 (-0400) Subject: (fold_truthop): Treat a BIT_AND_EXPR with a constant of one as if it were surrounded... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=96d4cf0aced6b394b62fbdb765d7e484123e3e61;p=platform%2Fupstream%2Fgcc.git (fold_truthop): Treat a BIT_AND_EXPR with a constant of one as if it were surrounded with an NE_EXPR. (fold_truthop): Treat a BIT_AND_EXPR with a constant of one as if it were surrounded with an NE_EXPR. (fold): Don't move operation into conditional if it is BIT_{AND,OR}_EXPR with the constant 1; change it to TRUTH_*_EXPR instead. When moving things inside conditions, move comparisons as well as binary operations. Don't make a SAVE_EXPR when moving things inside conditionals unless the value would really have been used twice. From-SVN: r4746 --- diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6570ac2..4db203c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2696,7 +2696,9 @@ fold_truthop (code, truth_type, lhs, rhs) int volatilep; /* Start by getting the comparison codes and seeing if this looks like - a range test. Fail if anything is volatile. */ + a range test. Fail if anything is volatile. If one operand is a + BIT_AND_EXPR with the constant one, treat it as if it were surrounded + with a NE_EXPR. */ if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs)) @@ -2705,6 +2707,12 @@ fold_truthop (code, truth_type, lhs, rhs) lcode = TREE_CODE (lhs); rcode = TREE_CODE (rhs); + if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1))) + lcode = NE_EXPR, lhs = build (NE_EXPR, truth_type, lhs, integer_zero_node); + + if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1))) + rcode = NE_EXPR, rhs = build (NE_EXPR, truth_type, rhs, integer_zero_node); + if (TREE_CODE_CLASS (lcode) != '<' || TREE_CODE_CLASS (rcode) != '<') return 0; @@ -3102,7 +3110,26 @@ fold (expr) operation inside the compound or conditional to see if any folding can then be done. Convert comparison to conditional for this purpose. The also optimizes non-constant cases that used to be done in - expand_expr. */ + expand_expr. + + Before we do that, see if this is a BIT_AND_EXPR or a BIT_OR_EXPR, + one of the operands is a comparison and the other is either a comparison + or a BIT_AND_EXPR with the constant 1. In that case, the code below + would make the expression more complex. Change it to a + TRUTH_{AND,OR}_EXPR. */ + + if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR) + && ((TREE_CODE_CLASS (TREE_CODE (arg0)) == '<' + && (TREE_CODE_CLASS (TREE_CODE (arg1)) == '<' + || (TREE_CODE (arg1) == BIT_AND_EXPR + && integer_onep (TREE_OPERAND (arg1, 1))))) + || (TREE_CODE_CLASS (TREE_CODE (arg1)) == '<' + && (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<' + || (TREE_CODE (arg0) == BIT_AND_EXPR + && integer_onep (TREE_OPERAND (arg0, 1))))))) + return fold (build (code == BIT_AND_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR, + type, arg0, arg1)); + if (TREE_CODE_CLASS (code) == '1') { if (TREE_CODE (arg0) == COMPOUND_EXPR) @@ -3139,11 +3166,13 @@ fold (expr) fold (build1 (code, type, integer_one_node)), fold (build1 (code, type, integer_zero_node)))); } - else if (TREE_CODE_CLASS (code) == '2') + else if (TREE_CODE_CLASS (code) == '2' + || TREE_CODE_CLASS (code) == '<') { if (TREE_CODE (arg1) == COMPOUND_EXPR) return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0), - fold (build (code, type, arg0, TREE_OPERAND (arg1, 1)))); + fold (build (code, type, + arg0, TREE_OPERAND (arg1, 1)))); else if (TREE_CODE (arg1) == COND_EXPR || TREE_CODE_CLASS (TREE_CODE (arg1)) == '<') { @@ -3162,8 +3191,27 @@ fold (expr) false_value = integer_zero_node; } - if (TREE_CODE (arg0) != VAR_DECL && TREE_CODE (arg0) != PARM_DECL) - arg0 = save_expr (arg0); + /* If ARG0 is complex we want to make sure we only evaluate + it once. Though this is only required if it is volatile, it + might be more efficient even if it is not. However, if we + succeed in folding one part to a constant, we do not need + to make this SAVE_EXPR. Since we do this optimization + primarily to see if we do end up with constant and this + SAVE_EXPR interfers with later optimizations, suppressing + it when we can is important. */ + + if ((TREE_CODE (arg0) != VAR_DECL && TREE_CODE (arg0) != PARM_DECL) + || TREE_SIDE_EFFECTS (arg0)) + { + tree lhs = fold (build (code, type, arg0, true_value)); + tree rhs = fold (build (code, type, arg0, false_value)); + + if (TREE_CONSTANT (lhs) || TREE_CONSTANT (rhs)) + return fold (build (COND_EXPR, type, test, lhs, rhs)); + + arg0 = save_expr (arg0); + } + test = fold (build (COND_EXPR, type, test, fold (build (code, type, arg0, true_value)), fold (build (code, type, arg0, false_value)))); @@ -3195,8 +3243,18 @@ fold (expr) false_value = integer_zero_node; } - if (TREE_CODE (arg1) != VAR_DECL && TREE_CODE (arg1) != PARM_DECL) - arg1 = save_expr (arg1); + if ((TREE_CODE (arg1) != VAR_DECL && TREE_CODE (arg1) != PARM_DECL) + || TREE_SIDE_EFFECTS (arg1)) + { + tree lhs = fold (build (code, type, true_value, arg1)); + tree rhs = fold (build (code, type, false_value, arg1)); + + if (TREE_CONSTANT (lhs) || TREE_CONSTANT (rhs)) + return fold (build (COND_EXPR, type, test, lhs, rhs)); + + arg1 = save_expr (arg1); + } + test = fold (build (COND_EXPR, type, test, fold (build (code, type, true_value, arg1)), fold (build (code, type, false_value, arg1))));