[PATCH] Teach SCCVN about VIEW_CONVERT_EXPR simplifying, add some foldings

Richard Guenther rguenther@suse.de
Mon Mar 3 11:54:00 GMT 2008


This is a preparatory patch for teaching type-punnning to SCCVN which
I'll apply separately to make the two proposal patches smaller.  It
adds folding of VIEW_CONVERT_EXPR of same-precision integral types
and pointer types as well as teaching SCCVN to combine VIEW_CONVERT_EXPR
the same as it does for NOP_EXPR and REAL/IMAGPART_EXPR.

It also fixes two latent problems, may_be_nonaddressable_p in IVOPTS
(again) and SCCVN inserting struct copy RHS into its expression tables.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2008-02-29  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (fold_unary): Fold VIEW_CONVERT_EXPR of
	integral and pointer arguments which do not change the
	precision to NOP_EXPRs.
	* tree-ssa-loop-ivopts.c (may_be_nonaddressable_p): Adjust
	VIEW_CONVERT_EXPR case.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	2008-03-01 19:51:04.000000000 +0100
--- gcc/fold-const.c	2008-03-01 19:53:25.000000000 +0100
*************** fold_unary (enum tree_code code, tree ty
*** 8277,8289 ****
      case VIEW_CONVERT_EXPR:
        if (TREE_TYPE (op0) == type)
  	return op0;
!       if (TREE_CODE (op0) == VIEW_CONVERT_EXPR
! 	  || (TREE_CODE (op0) == NOP_EXPR
! 	      && INTEGRAL_TYPE_P (TREE_TYPE (op0))
! 	      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
! 	      && TYPE_PRECISION (TREE_TYPE (op0))
! 		 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
  	return fold_build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (op0, 0));
        return fold_view_convert_expr (type, op0);
  
      case NEGATE_EXPR:
--- 8277,8304 ----
      case VIEW_CONVERT_EXPR:
        if (TREE_TYPE (op0) == type)
  	return op0;
!       if (TREE_CODE (op0) == VIEW_CONVERT_EXPR)
  	return fold_build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (op0, 0));
+ 
+       /* For integral conversions with the same precision or pointer
+ 	 conversions use a NOP_EXPR instead.  */
+       if ((INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ 	   && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0))
+ 	   /* Do not muck with VIEW_CONVERT_EXPRs that convert from
+ 	      a sub-type to its base type as generated by the Ada FE.  */
+ 	   && !TREE_TYPE (TREE_TYPE (op0)))
+ 	  || (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (op0))))
+ 	return fold_convert (type, op0);
+ 
+       /* Strip inner integral conversions that do not change the precision.  */
+       if ((TREE_CODE (op0) == NOP_EXPR
+ 	   || TREE_CODE (op0) == CONVERT_EXPR)
+ 	  && INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ 	  && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
+ 	  && (TYPE_PRECISION (TREE_TYPE (op0))
+ 	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
+ 	return fold_build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (op0, 0));
+ 
        return fold_view_convert_expr (type, op0);
  
      case NEGATE_EXPR:
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
*** gcc/tree-ssa-loop-ivopts.c	2008-03-01 19:51:04.000000000 +0100
--- gcc/tree-ssa-loop-ivopts.c	2008-03-01 19:53:25.000000000 +0100
*************** may_be_nonaddressable_p (tree expr)
*** 1522,1529 ****
  	 and make them look addressable.  After some processing the
  	 non-addressability may be uncovered again, causing ADDR_EXPRs
  	 of inappropriate objects to be built.  */
!       if (AGGREGATE_TYPE_P (TREE_TYPE (expr))
! 	  && !AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
  	return true;
  
        /* ... fall through ... */
--- 1522,1529 ----
  	 and make them look addressable.  After some processing the
  	 non-addressability may be uncovered again, causing ADDR_EXPRs
  	 of inappropriate objects to be built.  */
!       if (is_gimple_reg (TREE_OPERAND (expr, 0))
! 	  || is_gimple_min_invariant (TREE_OPERAND (expr, 0)))
  	return true;
  
        /* ... fall through ... */


2008-02-29  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-sccvn.c (visit_reference_op_store): Do not insert
	struct copies into the expression table.
	(simplify_unary_expression): Handle VIEW_CONVERT_EXPR.
	(try_to_simplify): Likewise.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	2008-03-01 19:53:24.000000000 +0100
--- gcc/tree-ssa-sccvn.c	2008-03-01 19:53:24.000000000 +0100
*************** visit_reference_op_store (tree lhs, tree
*** 1311,1317 ****
  	  changed |= set_ssa_val_to (vdef, vdef);
  	}
  
!       vn_reference_insert (lhs, op, vdefs);
      }
    else
      {
--- 1365,1374 ----
  	  changed |= set_ssa_val_to (vdef, vdef);
  	}
  
!       /* Do not insert structure copies into the tables.  */
!       if (is_gimple_min_invariant (op)
! 	  || is_gimple_reg (op))
!         vn_reference_insert (lhs, op, vdefs);
      }
    else
      {
*************** simplify_unary_expression (tree rhs)
*** 1549,1561 ****
    else if (TREE_CODE (rhs) == NOP_EXPR
  	   || TREE_CODE (rhs) == CONVERT_EXPR
  	   || TREE_CODE (rhs) == REALPART_EXPR
! 	   || TREE_CODE (rhs) == IMAGPART_EXPR)
      {
        /* We want to do tree-combining on conversion-like expressions.
           Make sure we feed only SSA_NAMEs or constants to fold though.  */
        tree tem = valueize_expr (VN_INFO (op0)->expr);
        if (UNARY_CLASS_P (tem)
  	  || BINARY_CLASS_P (tem)
  	  || TREE_CODE (tem) == SSA_NAME
  	  || is_gimple_min_invariant (tem))
  	op0 = tem;
--- 1606,1620 ----
    else if (TREE_CODE (rhs) == NOP_EXPR
  	   || TREE_CODE (rhs) == CONVERT_EXPR
  	   || TREE_CODE (rhs) == REALPART_EXPR
! 	   || TREE_CODE (rhs) == IMAGPART_EXPR
! 	   || TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
      {
        /* We want to do tree-combining on conversion-like expressions.
           Make sure we feed only SSA_NAMEs or constants to fold though.  */
        tree tem = valueize_expr (VN_INFO (op0)->expr);
        if (UNARY_CLASS_P (tem)
  	  || BINARY_CLASS_P (tem)
+ 	  || TREE_CODE (tem) == VIEW_CONVERT_EXPR
  	  || TREE_CODE (tem) == SSA_NAME
  	  || is_gimple_min_invariant (tem))
  	op0 = tem;
*************** try_to_simplify (tree stmt, tree rhs)
*** 1607,1613 ****
  
  	  /* Fallthrough for some codes that can operate on registers.  */
  	  if (!(TREE_CODE (rhs) == REALPART_EXPR
! 	        || TREE_CODE (rhs) == IMAGPART_EXPR))
  	    break;
  	  /* We could do a little more with unary ops, if they expand
  	     into binary ops, but it's debatable whether it is worth it. */
--- 1666,1673 ----
  
  	  /* Fallthrough for some codes that can operate on registers.  */
  	  if (!(TREE_CODE (rhs) == REALPART_EXPR
! 	        || TREE_CODE (rhs) == IMAGPART_EXPR
! 		|| TREE_CODE (rhs) == VIEW_CONVERT_EXPR))
  	    break;
  	  /* We could do a little more with unary ops, if they expand
  	     into binary ops, but it's debatable whether it is worth it. */



More information about the Gcc-patches mailing list