Commit e8e8c74b by Kai Tietz Committed by Kai Tietz

fold-const.c (fold_truth_andor): Factored out truth_andor label from fold_binary as function.

2011-07-08  Kai Tietz  <ktietz@redhat.com>

        * fold-const.c (fold_truth_andor): Factored out truth_andor
        label from fold_binary as function.
        (fold_binary_loc): Replace truth_andor lable
        by function fold_truth_andor.

From-SVN: r176043
parent 6c3cb698
2011-07-08 Kai Tietz <ktietz@redhat.com>
* fold-const.c (fold_truth_andor): Factored out truth_andor
label from fold_binary as function.
(fold_binary_loc): Replace truth_andor lable
by function fold_truth_andor.
2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com> 2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com>
PR middle-end/49519 PR middle-end/49519
......
...@@ -8211,6 +8211,97 @@ fold_unary_ignore_overflow_loc (location_t loc, enum tree_code code, ...@@ -8211,6 +8211,97 @@ fold_unary_ignore_overflow_loc (location_t loc, enum tree_code code,
return res; return res;
} }
/* Fold a binary bitwise/truth expression of code CODE and type TYPE with
operands OP0 and OP1. LOC is the location of the resulting expression.
ARG0 and ARG1 are the NOP_STRIPed results of OP0 and OP1.
Return the folded expression if folding is successful. Otherwise,
return NULL_TREE. */
static tree
fold_truth_andor (location_t loc, enum tree_code code, tree type,
tree arg0, tree arg1, tree op0, tree op1)
{
tree tem;
/* We only do these simplifications if we are optimizing. */
if (!optimize)
return NULL_TREE;
/* Check for things like (A || B) && (A || C). We can convert this
to A || (B && C). Note that either operator can be any of the four
truth and/or operations and the transformation will still be
valid. Also note that we only care about order for the
ANDIF and ORIF operators. If B contains side effects, this
might change the truth-value of A. */
if (TREE_CODE (arg0) == TREE_CODE (arg1)
&& (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
|| TREE_CODE (arg0) == TRUTH_ORIF_EXPR
|| TREE_CODE (arg0) == TRUTH_AND_EXPR
|| TREE_CODE (arg0) == TRUTH_OR_EXPR)
&& ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
{
tree a00 = TREE_OPERAND (arg0, 0);
tree a01 = TREE_OPERAND (arg0, 1);
tree a10 = TREE_OPERAND (arg1, 0);
tree a11 = TREE_OPERAND (arg1, 1);
int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
|| TREE_CODE (arg0) == TRUTH_AND_EXPR)
&& (code == TRUTH_AND_EXPR
|| code == TRUTH_OR_EXPR));
if (operand_equal_p (a00, a10, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
fold_build2_loc (loc, code, type, a01, a11));
else if (commutative && operand_equal_p (a00, a11, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
fold_build2_loc (loc, code, type, a01, a10));
else if (commutative && operand_equal_p (a01, a10, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a01,
fold_build2_loc (loc, code, type, a00, a11));
/* This case if tricky because we must either have commutative
operators or else A10 must not have side-effects. */
else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
&& operand_equal_p (a01, a11, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type,
fold_build2_loc (loc, code, type, a00, a10),
a01);
}
/* See if we can build a range comparison. */
if (0 != (tem = fold_range_test (loc, code, type, op0, op1)))
return tem;
if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg0) == TRUTH_ORIF_EXPR)
|| (code == TRUTH_ORIF_EXPR && TREE_CODE (arg0) == TRUTH_ANDIF_EXPR))
{
tem = merge_truthop_with_opposite_arm (loc, arg0, arg1, true);
if (tem)
return fold_build2_loc (loc, code, type, tem, arg1);
}
if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg1) == TRUTH_ORIF_EXPR)
|| (code == TRUTH_ORIF_EXPR && TREE_CODE (arg1) == TRUTH_ANDIF_EXPR))
{
tem = merge_truthop_with_opposite_arm (loc, arg1, arg0, false);
if (tem)
return fold_build2_loc (loc, code, type, arg0, tem);
}
/* Check for the possibility of merging component references. If our
lhs is another similar operation, try to merge its rhs with our
rhs. Then try to merge our lhs and rhs. */
if (TREE_CODE (arg0) == code
&& 0 != (tem = fold_truthop (loc, code, type,
TREE_OPERAND (arg0, 1), arg1)))
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);
if ((tem = fold_truthop (loc, code, type, arg0, arg1)) != 0)
return tem;
return NULL_TREE;
}
/* Fold a binary expression of code CODE and type TYPE with operands /* Fold a binary expression of code CODE and type TYPE with operands
OP0 and OP1, containing either a MIN-MAX or a MAX-MIN combination. OP0 and OP1, containing either a MIN-MAX or a MAX-MIN combination.
Return the folded expression if folding is successful. Otherwise, Return the folded expression if folding is successful. Otherwise,
...@@ -11953,83 +12044,9 @@ fold_binary_loc (location_t loc, ...@@ -11953,83 +12044,9 @@ fold_binary_loc (location_t loc,
return fold_build2_loc (loc, code, type, arg0, tem); return fold_build2_loc (loc, code, type, arg0, tem);
} }
truth_andor: if ((tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1))
/* We only do these simplifications if we are optimizing. */ != NULL_TREE)
if (!optimize) return tem;
return NULL_TREE;
/* Check for things like (A || B) && (A || C). We can convert this
to A || (B && C). Note that either operator can be any of the four
truth and/or operations and the transformation will still be
valid. Also note that we only care about order for the
ANDIF and ORIF operators. If B contains side effects, this
might change the truth-value of A. */
if (TREE_CODE (arg0) == TREE_CODE (arg1)
&& (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
|| TREE_CODE (arg0) == TRUTH_ORIF_EXPR
|| TREE_CODE (arg0) == TRUTH_AND_EXPR
|| TREE_CODE (arg0) == TRUTH_OR_EXPR)
&& ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
{
tree a00 = TREE_OPERAND (arg0, 0);
tree a01 = TREE_OPERAND (arg0, 1);
tree a10 = TREE_OPERAND (arg1, 0);
tree a11 = TREE_OPERAND (arg1, 1);
int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
|| TREE_CODE (arg0) == TRUTH_AND_EXPR)
&& (code == TRUTH_AND_EXPR
|| code == TRUTH_OR_EXPR));
if (operand_equal_p (a00, a10, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
fold_build2_loc (loc, code, type, a01, a11));
else if (commutative && operand_equal_p (a00, a11, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
fold_build2_loc (loc, code, type, a01, a10));
else if (commutative && operand_equal_p (a01, a10, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type, a01,
fold_build2_loc (loc, code, type, a00, a11));
/* This case if tricky because we must either have commutative
operators or else A10 must not have side-effects. */
else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
&& operand_equal_p (a01, a11, 0))
return fold_build2_loc (loc, TREE_CODE (arg0), type,
fold_build2_loc (loc, code, type, a00, a10),
a01);
}
/* See if we can build a range comparison. */
if (0 != (tem = fold_range_test (loc, code, type, op0, op1)))
return tem;
if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg0) == TRUTH_ORIF_EXPR)
|| (code == TRUTH_ORIF_EXPR && TREE_CODE (arg0) == TRUTH_ANDIF_EXPR))
{
tem = merge_truthop_with_opposite_arm (loc, arg0, arg1, true);
if (tem)
return fold_build2_loc (loc, code, type, tem, arg1);
}
if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg1) == TRUTH_ORIF_EXPR)
|| (code == TRUTH_ORIF_EXPR && TREE_CODE (arg1) == TRUTH_ANDIF_EXPR))
{
tem = merge_truthop_with_opposite_arm (loc, arg1, arg0, false);
if (tem)
return fold_build2_loc (loc, code, type, arg0, tem);
}
/* Check for the possibility of merging component references. If our
lhs is another similar operation, try to merge its rhs with our
rhs. Then try to merge our lhs and rhs. */
if (TREE_CODE (arg0) == code
&& 0 != (tem = fold_truthop (loc, code, type,
TREE_OPERAND (arg0, 1), arg1)))
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);
if ((tem = fold_truthop (loc, code, type, arg0, arg1)) != 0)
return tem;
return NULL_TREE; return NULL_TREE;
...@@ -12087,7 +12104,12 @@ fold_binary_loc (location_t loc, ...@@ -12087,7 +12104,12 @@ fold_binary_loc (location_t loc,
&& operand_equal_p (n1, a0, 0))) && operand_equal_p (n1, a0, 0)))
return fold_build2_loc (loc, TRUTH_XOR_EXPR, type, l0, n1); return fold_build2_loc (loc, TRUTH_XOR_EXPR, type, l0, n1);
} }
goto truth_andor;
if ((tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1))
!= NULL_TREE)
return tem;
return NULL_TREE;
case TRUTH_XOR_EXPR: case TRUTH_XOR_EXPR:
/* If the second arg is constant zero, drop it. */ /* If the second arg is constant zero, drop it. */
......
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