aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2005-03-04 19:59:45 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2005-03-04 19:59:45 +0000
commit3ea2c2646ec0a5d38f8bef076db2903bda3c2402 (patch)
tree04bf0ca1f23f409f1ff6c6383484081c82ecf5a9 /gcc/fold-const.c
parentb120f3b75c5279d35d5ea1f22cd72eab8f23abf3 (diff)
downloadgcc-3ea2c2646ec0a5d38f8bef076db2903bda3c2402.zip
gcc-3ea2c2646ec0a5d38f8bef076db2903bda3c2402.tar.gz
gcc-3ea2c2646ec0a5d38f8bef076db2903bda3c2402.tar.bz2
fold-const.c (fold_ternary): Unroll the "for" loop to extract operands.
* fold-const.c (fold_ternary): Unroll the "for" loop to extract operands. From-SVN: r95895
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c106
1 files changed, 47 insertions, 59 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 517c45d..df9e8a2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -7024,41 +7024,38 @@ fold_ternary (tree expr)
const tree t = expr;
const tree type = TREE_TYPE (expr);
tree tem;
+ tree op0, op1, op2;
tree arg0 = NULL_TREE, arg1 = NULL_TREE;
enum tree_code code = TREE_CODE (t);
enum tree_code_class kind = TREE_CODE_CLASS (code);
- int i;
gcc_assert (IS_EXPR_CODE_CLASS (kind)
&& TREE_CODE_LENGTH (code) == 3);
- /* For now, we iterate only twice even though we are handling
- ternary expressions. This is because we haven't defined arg2
- yet. */
- for (i = 0; i < 2; i++)
- {
- tree op = TREE_OPERAND (t, i);
-
- if (op == 0)
- continue; /* Valid for CALL_EXPR, at least. */
+ op0 = TREE_OPERAND (t, 0);
+ op1 = TREE_OPERAND (t, 1);
+ op2 = TREE_OPERAND (t, 2);
- /* Strip any conversions that don't change the mode. This is
- safe for every expression, except for a comparison expression
- because its signedness is derived from its operands. So, in
- the latter case, only strip conversions that don't change the
- signedness.
+ /* Strip any conversions that don't change the mode. This is safe
+ for every expression, except for a comparison expression because
+ its signedness is derived from its operands. So, in the latter
+ case, only strip conversions that don't change the signedness.
- Note that this is done as an internal manipulation within the
- constant folder, in order to find the simplest representation
- of the arguments so that their form can be studied. In any
- cases, the appropriate type conversions should be put back in
- the tree that will get out of the constant folder. */
- STRIP_NOPS (op);
+ Note that this is done as an internal manipulation within the
+ constant folder, in order to find the simplest representation of
+ the arguments so that their form can be studied. In any cases,
+ the appropriate type conversions should be put back in the tree
+ that will get out of the constant folder. */
+ if (op0)
+ {
+ arg0 = op0;
+ STRIP_NOPS (arg0);
+ }
- if (i == 0)
- arg0 = op;
- else if (i == 1)
- arg1 = op;
+ if (op1)
+ {
+ arg1 = op1;
+ STRIP_NOPS (arg1);
}
switch (code)
@@ -7078,7 +7075,7 @@ fold_ternary (tree expr)
so all simple results must be passed through pedantic_non_lvalue. */
if (TREE_CODE (arg0) == INTEGER_CST)
{
- tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
+ tem = integer_zerop (arg0) ? op2 : op1;
/* Only optimize constant conditions when the selected branch
has the same type as the COND_EXPR. This avoids optimizing
away "c ? x : throw", where the throw has a void type. */
@@ -7087,7 +7084,7 @@ fold_ternary (tree expr)
return pedantic_non_lvalue (tem);
return t;
}
- if (operand_equal_p (arg1, TREE_OPERAND (t, 2), 0))
+ if (operand_equal_p (arg1, op2, 0))
return pedantic_omit_one_operand (type, arg1, arg0);
/* If we have A op B ? A : C, we may be able to convert this to a
@@ -7101,25 +7098,21 @@ fold_ternary (tree expr)
arg1, TREE_OPERAND (arg0, 1))
&& !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
{
- tem = fold_cond_expr_with_comparison (type, arg0,
- TREE_OPERAND (t, 1),
- TREE_OPERAND (t, 2));
+ tem = fold_cond_expr_with_comparison (type, arg0, op1, op2);
if (tem)
return tem;
}
if (COMPARISON_CLASS_P (arg0)
&& operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (t, 2),
+ op2,
TREE_OPERAND (arg0, 1))
- && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 2)))))
+ && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
{
tem = invert_truthvalue (arg0);
if (COMPARISON_CLASS_P (tem))
{
- tem = fold_cond_expr_with_comparison (type, tem,
- TREE_OPERAND (t, 2),
- TREE_OPERAND (t, 1));
+ tem = fold_cond_expr_with_comparison (type, tem, op2, op1);
if (tem)
return tem;
}
@@ -7127,8 +7120,7 @@ fold_ternary (tree expr)
/* 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), false))
+ if (tree_swap_operands_p (op1, op2, false))
{
/* See if this can be inverted. If it can't, possibly because
it was a floating-point inequality comparison, don't do
@@ -7136,14 +7128,13 @@ fold_ternary (tree expr)
tem = invert_truthvalue (arg0);
if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
- return fold (build3 (code, type, tem,
- TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
+ return fold (build3 (code, type, tem, op2, op1));
}
/* Convert A ? 1 : 0 to simply A. */
- if (integer_onep (TREE_OPERAND (t, 1))
- && integer_zerop (TREE_OPERAND (t, 2))
- /* If we try to convert TREE_OPERAND (t, 0) to our type, the
+ if (integer_onep (op1)
+ && integer_zerop (op2)
+ /* If we try to convert OP0 to our type, the
call to fold will try to move the conversion inside
a COND, which will recurse. In that case, the COND_EXPR
is probably the best choice, so leave it alone. */
@@ -7152,8 +7143,8 @@ fold_ternary (tree expr)
/* Convert A ? 0 : 1 to !A. This prefers the use of NOT_EXPR
over COND_EXPR in cases such as floating point comparisons. */
- if (integer_zerop (TREE_OPERAND (t, 1))
- && integer_onep (TREE_OPERAND (t, 2))
+ if (integer_zerop (op1)
+ && integer_onep (op2)
&& truth_value_p (TREE_CODE (arg0)))
return pedantic_non_lvalue (fold_convert (type,
invert_truthvalue (arg0)));
@@ -7161,7 +7152,7 @@ fold_ternary (tree expr)
/* A < 0 ? <sign bit of A> : 0 is simply (A & <sign bit of A>). */
if (TREE_CODE (arg0) == LT_EXPR
&& integer_zerop (TREE_OPERAND (arg0, 1))
- && integer_zerop (TREE_OPERAND (t, 2))
+ && integer_zerop (op2)
&& (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
return fold_convert (type, fold (build2 (BIT_AND_EXPR,
TREE_TYPE (tem), tem, arg1)));
@@ -7170,7 +7161,7 @@ fold_ternary (tree expr)
already handled above. */
if (TREE_CODE (arg0) == BIT_AND_EXPR
&& integer_onep (TREE_OPERAND (arg0, 1))
- && integer_zerop (TREE_OPERAND (t, 2))
+ && integer_zerop (op2)
&& integer_pow2p (arg1))
{
tree tem = TREE_OPERAND (arg0, 0);
@@ -7187,7 +7178,7 @@ fold_ternary (tree expr)
is probably obsolete because the first operand should be a
truth value (that's why we have the two cases above), but let's
leave it in until we can confirm this for all front-ends. */
- if (integer_zerop (TREE_OPERAND (t, 2))
+ if (integer_zerop (op2)
&& TREE_CODE (arg0) == NE_EXPR
&& integer_zerop (TREE_OPERAND (arg0, 1))
&& integer_pow2p (arg1)
@@ -7198,13 +7189,13 @@ fold_ternary (tree expr)
TREE_OPERAND (arg0, 0)));
/* Convert A ? B : 0 into A && B if A and B are truth values. */
- if (integer_zerop (TREE_OPERAND (t, 2))
+ if (integer_zerop (op2)
&& truth_value_p (TREE_CODE (arg0))
&& truth_value_p (TREE_CODE (arg1)))
return fold (build2 (TRUTH_ANDIF_EXPR, type, arg0, arg1));
/* Convert A ? B : 1 into !A || B if A and B are truth values. */
- if (integer_onep (TREE_OPERAND (t, 2))
+ if (integer_onep (op2)
&& truth_value_p (TREE_CODE (arg0))
&& truth_value_p (TREE_CODE (arg1)))
{
@@ -7217,30 +7208,27 @@ fold_ternary (tree expr)
/* Convert A ? 0 : B into !A && B if A and B are truth values. */
if (integer_zerop (arg1)
&& truth_value_p (TREE_CODE (arg0))
- && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
+ && truth_value_p (TREE_CODE (op2)))
{
/* Only perform transformation if ARG0 is easily inverted. */
tem = invert_truthvalue (arg0);
if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
- return fold (build2 (TRUTH_ANDIF_EXPR, type, tem,
- TREE_OPERAND (t, 2)));
+ return fold (build2 (TRUTH_ANDIF_EXPR, type, tem, op2));
}
/* Convert A ? 1 : B into A || B if A and B are truth values. */
if (integer_onep (arg1)
&& truth_value_p (TREE_CODE (arg0))
- && truth_value_p (TREE_CODE (TREE_OPERAND (t, 2))))
- return fold (build2 (TRUTH_ORIF_EXPR, type, arg0,
- TREE_OPERAND (t, 2)));
+ && truth_value_p (TREE_CODE (op2)))
+ return fold (build2 (TRUTH_ORIF_EXPR, type, arg0, op2));
return t;
case CALL_EXPR:
/* Check for a built-in function. */
- if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))
- == FUNCTION_DECL)
- && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
+ if (TREE_CODE (op0) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (op0, 0)) == FUNCTION_DECL
+ && DECL_BUILT_IN (TREE_OPERAND (op0, 0)))
{
tree tmp = fold_builtin (t, false);
if (tmp)