Commit 3ea2c264 by Kazu Hirata Committed by Kazu Hirata

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
parent b120f3b7
2005-03-04 Kazu Hirata <kazu@cs.umass.edu>
* fold-const.c (fold_ternary): Unroll the "for" loop to
extract operands.
2005-03-04 Andrew Haley <aph@redhat.com>
* unwind-dw2-fde-glibc.c (struct
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment