This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Reduce garbage produced by invert_truthvalue
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 14 Jun 2006 14:06:06 +0200 (CEST)
- Subject: [PATCH] Reduce garbage produced by invert_truthvalue
This splits invert_truthvalue into fold_truth_not_expr and a wrapper
around it to avoid generating garbage when we only are interested in
"simplified" negations. It also avoids one call in optimize_minmax
completely by copying one statement from invert_truthvalue.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Ok for mainline? (I didn't yet audit users of invert_truthvalue
in other files)
Thanks,
Richard.
:ADDPATCH middle-end:
2006-06-14 Richard Guenther <rguenther@suse.de>
* fold-const.c (fold_truth_not_expr): Rename from
invert_truthvalue. Give it fold_* semantics to avoid
generating garbage.
(invert_truthvalue): New function. Wrapper around
fold_truth_not_expr.
(optimize_minmax_comparison): Avoid creating garbage.
(fold_unary): Use fold_truth_not_expr for folding
TRUTH_NOT_EXPR.
(fold_ternary): Replace uses of invert_truthvalue with
fold_truth_not_expr where applicable.
* tree.h (fold_truth_not_expr): Prototype.
Index: fold-const.c
===================================================================
*** fold-const.c (revision 114610)
--- fold-const.c (working copy)
*************** omit_two_operands (tree type, tree resul
*** 3049,3063 ****
FIXME: one would think we would fold the result, but it causes
problems with the dominator optimizer. */
tree
! invert_truthvalue (tree arg)
{
tree type = TREE_TYPE (arg);
enum tree_code code = TREE_CODE (arg);
- if (code == ERROR_MARK)
- return arg;
-
/* If this is a comparison, we can simply invert it, except for
floating-point non-equality comparisons, in which case we just
enclose a TRUTH_NOT_EXPR around what we have. */
--- 3049,3061 ----
FIXME: one would think we would fold the result, but it causes
problems with the dominator optimizer. */
+
tree
! fold_truth_not_expr (tree arg)
{
tree type = TREE_TYPE (arg);
enum tree_code code = TREE_CODE (arg);
/* If this is a comparison, we can simply invert it, except for
floating-point non-equality comparisons, in which case we just
enclose a TRUTH_NOT_EXPR around what we have. */
*************** invert_truthvalue (tree arg)
*** 3069,3081 ****
&& flag_trapping_math
&& code != ORDERED_EXPR && code != UNORDERED_EXPR
&& code != NE_EXPR && code != EQ_EXPR)
! return build1 (TRUTH_NOT_EXPR, type, arg);
else
{
code = invert_tree_comparison (code,
HONOR_NANS (TYPE_MODE (op_type)));
if (code == ERROR_MARK)
! return build1 (TRUTH_NOT_EXPR, type, arg);
else
return build2 (code, type,
TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
--- 3067,3079 ----
&& flag_trapping_math
&& code != ORDERED_EXPR && code != UNORDERED_EXPR
&& code != NE_EXPR && code != EQ_EXPR)
! return NULL_TREE;
else
{
code = invert_tree_comparison (code,
HONOR_NANS (TYPE_MODE (op_type)));
if (code == ERROR_MARK)
! return NULL_TREE;
else
return build2 (code, type,
TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
*************** invert_truthvalue (tree arg)
*** 3147,3153 ****
case NOP_EXPR:
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
! break;
case CONVERT_EXPR:
case FLOAT_EXPR:
--- 3145,3151 ----
case NOP_EXPR:
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
! return build1 (TRUTH_NOT_EXPR, type, arg);
case CONVERT_EXPR:
case FLOAT_EXPR:
*************** invert_truthvalue (tree arg)
*** 3170,3177 ****
default:
break;
}
! gcc_assert (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE);
! return build1 (TRUTH_NOT_EXPR, type, arg);
}
/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
--- 3168,3197 ----
default:
break;
}
!
! return NULL_TREE;
! }
!
! /* Return a simplified tree node for the truth-negation of ARG. This
! never alters ARG itself. We assume that ARG is an operation that
! returns a truth value (0 or 1).
!
! FIXME: one would think we would fold the result, but it causes
! problems with the dominator optimizer. */
!
! tree
! invert_truthvalue (tree arg)
! {
! tree tem;
!
! if (TREE_CODE (arg) == ERROR_MARK)
! return arg;
!
! tem = fold_truth_not_expr (arg);
! if (!tem)
! tem = build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);
!
! return tem;
}
/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
*************** optimize_minmax_comparison (enum tree_co
*** 5257,5271 ****
{
case NE_EXPR: case LT_EXPR: case LE_EXPR:
{
! /* FIXME: We should be able to invert code without building a
! scratch tree node, but doing so would require us to
! duplicate a part of invert_truthvalue here. */
! tree tem = invert_truthvalue (build2 (code, type, op0, op1));
! tem = optimize_minmax_comparison (TREE_CODE (tem),
! TREE_TYPE (tem),
! TREE_OPERAND (tem, 0),
! TREE_OPERAND (tem, 1));
! return invert_truthvalue (tem);
}
case GE_EXPR:
--- 5277,5287 ----
{
case NE_EXPR: case LT_EXPR: case LE_EXPR:
{
! tree tem = optimize_minmax_comparison (invert_tree_comparison (code, false),
! type, op0, op1);
! if (tem)
! return invert_truthvalue (tem);
! return NULL_TREE;
}
case GE_EXPR:
*************** fold_unary (enum tree_code code, tree ty
*** 7615,7623 ****
and its values must be 0 or 1.
("true" is a fixed value perhaps depending on the language,
but we don't handle values other than 1 correctly yet.) */
! tem = invert_truthvalue (arg0);
! /* Avoid infinite recursion. */
! if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
return NULL_TREE;
return fold_convert (type, tem);
--- 7631,7638 ----
and its values must be 0 or 1.
("true" is a fixed value perhaps depending on the language,
but we don't handle values other than 1 correctly yet.) */
! tem = fold_truth_not_expr (arg0);
! if (!tem)
return NULL_TREE;
return fold_convert (type, tem);
*************** fold_ternary (enum tree_code code, tree
*** 11113,11120 ****
TREE_OPERAND (arg0, 1))
&& !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, op2, op1);
if (tem)
--- 11128,11135 ----
TREE_OPERAND (arg0, 1))
&& !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
{
! tem = fold_truth_not_expr (arg0);
! if (tem && COMPARISON_CLASS_P (tem))
{
tem = fold_cond_expr_with_comparison (type, tem, op2, op1);
if (tem)
*************** fold_ternary (enum tree_code code, tree
*** 11130,11138 ****
/* 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)
return fold_build3 (code, type, tem, op2, op1);
}
--- 11145,11152 ----
/* See if this can be inverted. If it can't, possibly because
it was a floating-point inequality comparison, don't do
anything. */
! tem = fold_truth_not_expr (arg0);
! if (tem)
return fold_build3 (code, type, tem, op2, op1);
}
*************** fold_ternary (enum tree_code code, tree
*** 11209,11216 ****
&& truth_value_p (TREE_CODE (arg1)))
{
/* Only perform transformation if ARG0 is easily inverted. */
! tem = invert_truthvalue (arg0);
! if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
return fold_build2 (TRUTH_ORIF_EXPR, type,
fold_convert (type, tem),
arg1);
--- 11223,11230 ----
&& truth_value_p (TREE_CODE (arg1)))
{
/* Only perform transformation if ARG0 is easily inverted. */
! tem = fold_truth_not_expr (arg0);
! if (tem)
return fold_build2 (TRUTH_ORIF_EXPR, type,
fold_convert (type, tem),
arg1);
*************** fold_ternary (enum tree_code code, tree
*** 11222,11229 ****
&& 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,
fold_convert (type, tem),
op2);
--- 11236,11243 ----
&& truth_value_p (TREE_CODE (op2)))
{
/* Only perform transformation if ARG0 is easily inverted. */
! tem = fold_truth_not_expr (arg0);
! if (tem)
return fold_build2 (TRUTH_ANDIF_EXPR, type,
fold_convert (type, tem),
op2);
Index: tree.h
===================================================================
*** tree.h (revision 114610)
--- tree.h (working copy)
*************** extern int operand_equal_p (tree, tree,
*** 4208,4213 ****
--- 4208,4214 ----
extern tree omit_one_operand (tree, tree, tree);
extern tree omit_two_operands (tree, tree, tree, tree);
extern tree invert_truthvalue (tree);
+ extern tree fold_truth_not_expr (tree);
extern tree fold_unary_to_constant (enum tree_code, tree, tree);
extern tree fold_binary_to_constant (enum tree_code, tree, tree, tree);
extern tree fold_read_from_constant_string (tree);