[PATCH] Make tree-ssa's set_rhs tests inclusive (not exclusive)

Roger Sayle roger@eyesopen.com
Sat Nov 4 15:05:00 GMT 2006


As promised/threatened back back in September in for the PR29059 review
http://gcc.gnu.org/ml/gcc-patches/2006-09/msg00638.html the following
patch restructures the validity checks in tree-ssa-propagate.c's
set_rhs.  Previously, we were testing for tree codes that shouldn't
appear in a gimple RHS.  Instead we now check for the things that can
legitimately appear, and reject everything else.

With this change, and a minor tweak to tree-ssa-ccp.c we can remove
most of the in_gimple_form tests from fold-const.c and builtins.c.
Previously, the tree-ssa was able to handle non-gimple returned by
fold and friends, but this checking depended on the fragile tests
in set_rhs.  Making these stronger, should make everything play
nicer, and avoid potential bugs if fold changes subtley in future.

The following patch has been tested on x86_64-unknown-linux-gnu with
a full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new regressions.

I'm posting this as an RFA to confirm that Jeff and/or Diego (or
others) are happy with this clean-up.  Ok for mainline?



2006-11-04  Roger Sayle  <roger@eyesopen.com>

	* tree-ssa-propagate.c (set_rhs): Restructure validity tests as a
	test for inclusion rather than as a test for exclusion.
	* tree-ssa-ccp.c (fold_stmt_r) <COND_EXPR>: Use set_rhs to modify
	the condition after calling fold_binary.
	* fold-const.c (fold_inf_compare): Remove in_gimple_form check.
	(fold_binary) <LT_EXPR, GT_EXPR, LE_EXPR, GE_EXPR>: Likewise.
	* builtins.c (fold_builtin_isascii): Likewise.
	(fold_builtin_isdigit): Likewise.


Index: tree-ssa-propagate.c
===================================================================
*** tree-ssa-propagate.c	(revision 118355)
--- tree-ssa-propagate.c	(working copy)
*************** set_rhs (tree *stmt_p, tree expr)
*** 571,596 ****
    ssa_op_iter iter;

    /* Verify the constant folded result is valid gimple.  */
!   if (TREE_CODE_CLASS (code) == tcc_binary)
      {
        if (!is_gimple_val (TREE_OPERAND (expr, 0))
  	  || !is_gimple_val (TREE_OPERAND (expr, 1)))
  	return false;
!     }
!   else if (TREE_CODE_CLASS (code) == tcc_unary)
!     {
        if (!is_gimple_val (TREE_OPERAND (expr, 0)))
  	return false;
      }
-   else if (code == ADDR_EXPR)
-     {
-       if (TREE_CODE (TREE_OPERAND (expr, 0)) == ARRAY_REF
- 	  && !is_gimple_val (TREE_OPERAND (TREE_OPERAND (expr, 0), 1)))
- 	return false;
-     }
-   else if (code == COMPOUND_EXPR
- 	   || code == MODIFY_EXPR)
-     return false;

    if (EXPR_HAS_LOCATION (stmt)
        && EXPR_P (expr)
--- 571,644 ----
    ssa_op_iter iter;

    /* Verify the constant folded result is valid gimple.  */
!   switch (TREE_CODE_CLASS (code))
      {
+     case tcc_declaration:
+       if (!is_gimple_variable(expr))
+ 	return false;
+       break;
+
+     case tcc_constant:
+       break;
+
+     case tcc_binary:
+     case tcc_comparison:
        if (!is_gimple_val (TREE_OPERAND (expr, 0))
  	  || !is_gimple_val (TREE_OPERAND (expr, 1)))
  	return false;
!       break;
!
!     case tcc_unary:
        if (!is_gimple_val (TREE_OPERAND (expr, 0)))
  	return false;
+       break;
+
+     case tcc_expression:
+       switch (code)
+ 	{
+ 	case ADDR_EXPR:
+           if (TREE_CODE (TREE_OPERAND (expr, 0)) == ARRAY_REF
+ 	      && !is_gimple_val (TREE_OPERAND (TREE_OPERAND (expr, 0), 1)))
+ 	    return false;
+ 	  break;
+
+ 	case TRUTH_NOT_EXPR:
+ 	  if (!is_gimple_val (TREE_OPERAND (expr, 0)))
+ 	    return false;
+ 	  break;
+
+ 	case TRUTH_AND_EXPR:
+ 	case TRUTH_XOR_EXPR:
+ 	case TRUTH_OR_EXPR:
+ 	  if (!is_gimple_val (TREE_OPERAND (expr, 0))
+ 	      || !is_gimple_val (TREE_OPERAND (expr, 1)))
+ 	    return false;
+ 	  break;
+
+ 	case CALL_EXPR:
+ 	case EXC_PTR_EXPR:
+ 	case FILTER_EXPR:
+ 	  break;
+
+ 	default:
+ 	  return false;
+ 	}
+       break;
+
+     case tcc_exceptional:
+       switch (code)
+ 	{
+ 	case SSA_NAME:
+ 	  break;
+
+ 	default:
+ 	  return false;
+ 	}
+       break;
+
+     default:
+       return false;
      }

    if (EXPR_HAS_LOCATION (stmt)
        && EXPR_P (expr)
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c	(revision 118355)
--- tree-ssa-ccp.c	(working copy)
*************** fold_stmt_r (tree *expr_p, int *walk_sub
*** 2048,2059 ****
          {
  	  tree op0 = TREE_OPERAND (expr, 0);
            tree tem = fold_binary (TREE_CODE (op0), TREE_TYPE (op0),
! 				  TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
! 	  if (tem && is_gimple_condexpr (tem))
! 	    TREE_OPERAND (expr, 0) = tem;
! 	  t = expr;
!           break;
          }

      default:
        return NULL_TREE;
--- 2048,2062 ----
          {
  	  tree op0 = TREE_OPERAND (expr, 0);
            tree tem = fold_binary (TREE_CODE (op0), TREE_TYPE (op0),
! 				  TREE_OPERAND (op0, 0),
! 				  TREE_OPERAND (op0, 1));
! 	  if (tem && set_rhs (expr_p, tem))
! 	    {
! 	      t = *expr_p;
! 	      break;
! 	    }
          }
+       return NULL_TREE;

      default:
        return NULL_TREE;
Index: fold-const.c
===================================================================
*** fold-const.c	(revision 118355)
--- fold-const.c	(working copy)
*************** fold_inf_compare (enum tree_code code, t
*** 6059,6069 ****
  	return fold_build2 (neg ? GE_EXPR : LE_EXPR, type,
  			    arg0, build_real (TREE_TYPE (arg0), max));

-       /* The transformation below creates non-gimple code and thus is
- 	 not appropriate if we are in gimple form.  */
-       if (in_gimple_form)
- 	return NULL_TREE;
-
        temp = fold_build2 (neg ? LT_EXPR : GT_EXPR, type,
  			  arg0, build_real (TREE_TYPE (arg0), max));
        return fold_build1 (TRUTH_NOT_EXPR, type, temp);
--- 6059,6064 ----
*************** fold_binary (enum tree_code code, tree t
*** 11043,11050 ****
  		  break;
  		}

! 	    else if (!in_gimple_form
! 		     && TREE_INT_CST_HIGH (arg1) == signed_max_hi
  		     && TREE_INT_CST_LOW (arg1) == signed_max_lo
  		     && TYPE_UNSIGNED (TREE_TYPE (arg1))
  		     /* signed_type does not work on pointer types.  */
--- 11038,11044 ----
  		  break;
  		}

! 	    else if (TREE_INT_CST_HIGH (arg1) == signed_max_hi
  		     && TREE_INT_CST_LOW (arg1) == signed_max_lo
  		     && TYPE_UNSIGNED (TREE_TYPE (arg1))
  		     /* signed_type does not work on pointer types.  */
Index: builtins.c
===================================================================
*** builtins.c	(revision 118355)
--- builtins.c	(working copy)
*************** fold_builtin_isascii (tree arglist)
*** 8664,8676 ****
        arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
  		    build_int_cst (NULL_TREE,
  				   ~ (unsigned HOST_WIDE_INT) 0x7f));
!       arg = fold_build2 (EQ_EXPR, integer_type_node,
! 			 arg, integer_zero_node);
!
!       if (in_gimple_form && !TREE_CONSTANT (arg))
! 	return NULL_TREE;
!       else
! 	return arg;
      }
  }

--- 8664,8671 ----
        arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
  		    build_int_cst (NULL_TREE,
  				   ~ (unsigned HOST_WIDE_INT) 0x7f));
!       return fold_build2 (EQ_EXPR, integer_type_node,
! 			  arg, integer_zero_node);
      }
  }

*************** fold_builtin_isdigit (tree arglist)
*** 8713,8724 ****
        arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
        arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
  		    build_int_cst (unsigned_type_node, target_digit0));
!       arg = fold_build2 (LE_EXPR, integer_type_node, arg,
! 			 build_int_cst (unsigned_type_node, 9));
!       if (in_gimple_form && !TREE_CONSTANT (arg))
! 	return NULL_TREE;
!       else
! 	return arg;
      }
  }

--- 8708,8715 ----
        arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
        arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
  		    build_int_cst (unsigned_type_node, target_digit0));
!       return fold_build2 (LE_EXPR, integer_type_node, arg,
! 			  build_int_cst (unsigned_type_node, 9));
      }
  }



Roger
--



More information about the Gcc-patches mailing list