aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-11-16 07:55:26 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1994-11-16 07:55:26 -0500
commite1f56f62a0395318f20e55e206a838785dc42229 (patch)
treefb83956bc96a10095d4f15f146f39360e32c7f68 /gcc
parent5a32d03841c8db674ef3f6fb7e223b37c4122e46 (diff)
downloadgcc-e1f56f62a0395318f20e55e206a838785dc42229.zip
gcc-e1f56f62a0395318f20e55e206a838785dc42229.tar.gz
gcc-e1f56f62a0395318f20e55e206a838785dc42229.tar.bz2
(fold): If moved conversion into COND_EXPR, leave it there if it is an integral conversion to word or narrower.
(fold): If moved conversion into COND_EXPR, leave it there if it is an integral conversion to word or narrower. (fold, case NOP_EXPR): Ignore conversion to same type as operand. (fold, case COND_EXPR): Make third operand the simplest. From-SVN: r8467
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fold-const.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 50217a0..54ac733 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3170,9 +3170,13 @@ fold (expr)
fold (build1 (code, type, TREE_OPERAND (arg0, 2)))));
/* If this was a conversion, and all we did was to move into
- inside the COND_EXPR, bring it back out. Then return so we
- don't get into an infinite recursion loop taking the conversion
- out and then back in. */
+ inside the COND_EXPR, bring it back out. But leave it if
+ it is a conversion from integer to integer and the
+ result precision is no wider than a word since such a
+ conversion is cheap and may be optimized away by combine,
+ while it couldn't if it were outside the COND_EXPR. Then return
+ so we don't get into an infinite recursion loop taking the
+ conversion out and then back in. */
if ((code == NOP_EXPR || code == CONVERT_EXPR
|| code == NON_LVALUE_EXPR)
@@ -3180,7 +3184,10 @@ fold (expr)
&& TREE_CODE (TREE_OPERAND (t, 1)) == code
&& TREE_CODE (TREE_OPERAND (t, 2)) == code
&& (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0))
- == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 2), 0))))
+ == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 2), 0)))
+ && ! (INTEGRAL_TYPE_P (TREE_TYPE (t))
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0)))
+ && TYPE_PRECISION (TREE_TYPE (t)) <= BITS_PER_WORD))
t = build1 (code, type,
build (COND_EXPR,
TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0)),
@@ -3327,6 +3334,9 @@ fold (expr)
case FIX_TRUNC_EXPR:
/* Other kinds of FIX are not handled properly by fold_convert. */
+ if (TREE_TYPE (TREE_OPERAND (t, 0)) == TREE_TYPE (t))
+ return TREE_OPERAND (t, 0);
+
/* In addition to the cases of two conversions in a row
handled below, if we are converting something to its own
type via an object of identical or wider precision, neither
@@ -4822,6 +4832,28 @@ fold (expr)
}
}
+ /* If the second operand is simpler than the third, swap them
+ since that produces better jump optimization results. */
+ if ((TREE_CONSTANT (arg1) || TREE_CODE_CLASS (TREE_CODE (arg1)) == 'd'
+ || TREE_CODE (arg1) == SAVE_EXPR)
+ && ! (TREE_CONSTANT (TREE_OPERAND (t, 2))
+ || TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 2))) == 'd'
+ || 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
+ anything. */
+ tem = invert_truthvalue (arg0);
+
+ if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
+ {
+ arg0 = TREE_OPERAND (t, 0) = tem;
+ TREE_OPERAND (t, 1) = TREE_OPERAND (t, 2);
+ TREE_OPERAND (t, 2) = arg1;
+ arg1 = TREE_OPERAND (t, 1);
+ }
+ }
+
/* Convert A ? 1 : 0 to simply A. */
if (integer_onep (TREE_OPERAND (t, 1))
&& integer_zerop (TREE_OPERAND (t, 2))
@@ -4832,7 +4864,6 @@ fold (expr)
&& type == TREE_TYPE (arg0))
return pedantic_non_lvalue (arg0);
-
/* Look for expressions of the form A & 2 ? 2 : 0. The result of this
operation is simply A & 2. */