Commit 35e66bd1 by Richard Kenner

(twoval_comparison_p): Add new arg, SAVE_P; all callers changed.

(fold, case EQ_EXPR): If SAVE_P is true after call to twoval_comparison_p
call save_expr on the expression we make.

From-SVN: r5194
parent 6bf1675f
...@@ -61,7 +61,7 @@ static tree fold_convert PROTO((tree, tree)); ...@@ -61,7 +61,7 @@ static tree fold_convert PROTO((tree, tree));
static enum tree_code invert_tree_comparison PROTO((enum tree_code)); static enum tree_code invert_tree_comparison PROTO((enum tree_code));
static enum tree_code swap_tree_comparison PROTO((enum tree_code)); static enum tree_code swap_tree_comparison PROTO((enum tree_code));
static int operand_equal_for_comparison_p PROTO((tree, tree, tree)); static int operand_equal_for_comparison_p PROTO((tree, tree, tree));
static int twoval_comparison_p PROTO((tree, tree *, tree *)); static int twoval_comparison_p PROTO((tree, tree *, tree *, int *));
static tree eval_subst PROTO((tree, tree, tree, tree, tree)); static tree eval_subst PROTO((tree, tree, tree, tree, tree));
static tree omit_one_operand PROTO((tree, tree, tree)); static tree omit_one_operand PROTO((tree, tree, tree));
static tree distribute_bit_expr PROTO((enum tree_code, tree, tree, tree)); static tree distribute_bit_expr PROTO((enum tree_code, tree, tree, tree));
...@@ -1900,46 +1900,59 @@ operand_equal_for_comparison_p (arg0, arg1, other) ...@@ -1900,46 +1900,59 @@ operand_equal_for_comparison_p (arg0, arg1, other)
two different values, which will be stored in *CVAL1 and *CVAL2; if two different values, which will be stored in *CVAL1 and *CVAL2; if
they are non-zero it means that some operands have already been found. they are non-zero it means that some operands have already been found.
No variables may be used anywhere else in the expression except in the No variables may be used anywhere else in the expression except in the
comparisons. comparisons. If SAVE_P is true it means we removed a SAVE_EXPR around
the expression and save_expr needs to be called with CVAL1 and CVAL2.
If this is true, return 1. Otherwise, return zero. */ If this is true, return 1. Otherwise, return zero. */
static int static int
twoval_comparison_p (arg, cval1, cval2) twoval_comparison_p (arg, cval1, cval2, save_p)
tree arg; tree arg;
tree *cval1, *cval2; tree *cval1, *cval2;
int *save_p;
{ {
enum tree_code code = TREE_CODE (arg); enum tree_code code = TREE_CODE (arg);
char class = TREE_CODE_CLASS (code); char class = TREE_CODE_CLASS (code);
/* We can handle some of the 'e' cases here. */ /* We can handle some of the 'e' cases here. */
if (class == 'e' if (class == 'e' && code == TRUTH_NOT_EXPR)
&& (code == TRUTH_NOT_EXPR
|| (code == SAVE_EXPR && SAVE_EXPR_RTL (arg) == 0)))
class = '1'; class = '1';
else if (class == 'e' else if (class == 'e'
&& (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR
|| code == COMPOUND_EXPR)) || code == COMPOUND_EXPR))
class = '2'; class = '2';
else if (class == 'e' && code == SAVE_EXPR && SAVE_EXPR_RTL (arg) == 0)
{
/* If we've already found a CVAL1 or CVAL2, this expression is
two complex to handle. */
if (*cval1 || *cval2)
return 0;
class = '1';
*save_p = 1;
}
switch (class) switch (class)
{ {
case '1': case '1':
return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2); return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p);
case '2': case '2':
return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2) return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p)
&& twoval_comparison_p (TREE_OPERAND (arg, 1), cval1, cval2)); && twoval_comparison_p (TREE_OPERAND (arg, 1),
cval1, cval2, save_p));
case 'c': case 'c':
return 1; return 1;
case 'e': case 'e':
if (code == COND_EXPR) if (code == COND_EXPR)
return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2) return (twoval_comparison_p (TREE_OPERAND (arg, 0),
&& twoval_comparison_p (TREE_OPERAND (arg, 1), cval1, cval2) cval1, cval2, save_p)
&& twoval_comparison_p (TREE_OPERAND (arg, 1),
cval1, cval2, save_p)
&& twoval_comparison_p (TREE_OPERAND (arg, 2), && twoval_comparison_p (TREE_OPERAND (arg, 2),
cval1, cval2)); cval1, cval2, save_p));
return 0; return 0;
case '<': case '<':
...@@ -4346,8 +4359,9 @@ fold (expr) ...@@ -4346,8 +4359,9 @@ fold (expr)
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST) if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
{ {
tree cval1 = 0, cval2 = 0; tree cval1 = 0, cval2 = 0;
int save_p = 0;
if (twoval_comparison_p (arg0, &cval1, &cval2) if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p)
/* Don't handle degenerate cases here; they should already /* Don't handle degenerate cases here; they should already
have been handled anyway. */ have been handled anyway. */
&& cval1 != 0 && cval2 != 0 && cval1 != 0 && cval2 != 0
...@@ -4419,7 +4433,11 @@ fold (expr) ...@@ -4419,7 +4433,11 @@ fold (expr)
return omit_one_operand (type, integer_one_node, arg0); return omit_one_operand (type, integer_one_node, arg0);
} }
return fold (build (code, type, cval1, cval2)); t = build (code, type, cval1, cval2);
if (save_p)
return save_expr (t);
else
return fold (t);
} }
} }
} }
......
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