This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]