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]

Re: [PATCH] Remove fold () dispatch from fold_gimple_assign


On Thu, 29 Oct 2015, Richard Biener wrote:

> 
> After
> 
> Index: gcc/gimple-fold.c
> ===================================================================
> --- gcc/gimple-fold.c   (revision 229518)
> +++ gcc/gimple-fold.c   (working copy)
> @@ -398,7 +398,10 @@ fold_gimple_assign (gimple_stmt_iterator
>          /* If we couldn't fold the RHS, hand over to the generic
>             fold routines.  */
>          if (result == NULL_TREE)
> -          result = fold (rhs);
> +         {
> +           result = fold (rhs);
> +           gcc_assert (result == rhs);
> +         }
>  
>          /* Strip away useless type conversions.  Both the NON_LVALUE_EXPR
>             that may have been added by fold, and "useless" type
> 
> passed bootstrap and regtest on x86_64-unknown-linux-gnu I am now
> testing the following.

The following is what I ended up applying.

Bootstrapped & tested on x86_64-unknown-linux-gnu.

Richard.

2015-10-30  Richard Biener  <rguenther@suse.de>

	* gimple-fold.c (fold_gimple_assign): Do not dispatch to
	fold () on single RHSs.  Allow CONSTRUCTORS with trailing
	zeros to be folded to VECTOR_CSTs.
	* tree.c (build_vector_from_ctor): Handle VECTOR_CST elements.
	* fold-const.c (fold): Use build_vector_from_ctor.

Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c	(revision 229520)
--- gcc/gimple-fold.c	(working copy)
*************** fold_gimple_assign (gimple_stmt_iterator
*** 355,362 ****
  		    return val;
  		  }
  	      }
- 
  	  }
  	else if (TREE_CODE (rhs) == ADDR_EXPR)
  	  {
  	    tree ref = TREE_OPERAND (rhs, 0);
--- 355,362 ----
  		    return val;
  		  }
  	      }
  	  }
+ 
  	else if (TREE_CODE (rhs) == ADDR_EXPR)
  	  {
  	    tree ref = TREE_OPERAND (rhs, 0);
*************** fold_gimple_assign (gimple_stmt_iterator
*** 371,391 ****
  	    else if (TREE_CODE (ref) == MEM_REF
  		     && integer_zerop (TREE_OPERAND (ref, 1)))
  	      result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (ref, 0));
  	  }
  
  	else if (TREE_CODE (rhs) == CONSTRUCTOR
! 		 && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
! 		 && (CONSTRUCTOR_NELTS (rhs)
! 		     == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
  	  {
  	    /* Fold a constant vector CONSTRUCTOR to VECTOR_CST.  */
  	    unsigned i;
  	    tree val;
  
  	    FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
! 	      if (TREE_CODE (val) != INTEGER_CST
! 		  && TREE_CODE (val) != REAL_CST
! 		  && TREE_CODE (val) != FIXED_CST)
  		return NULL_TREE;
  
  	    return build_vector_from_ctor (TREE_TYPE (rhs),
--- 371,399 ----
  	    else if (TREE_CODE (ref) == MEM_REF
  		     && integer_zerop (TREE_OPERAND (ref, 1)))
  	      result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (ref, 0));
+ 
+ 	    if (result)
+ 	      {
+ 		/* Strip away useless type conversions.  Both the
+ 		   NON_LVALUE_EXPR that may have been added by fold, and
+ 		   "useless" type conversions that might now be apparent
+ 		   due to propagation.  */
+ 		STRIP_USELESS_TYPE_CONVERSION (result);
+ 
+ 		if (result != rhs && valid_gimple_rhs_p (result))
+ 		  return result;
+ 	      }
  	  }
  
  	else if (TREE_CODE (rhs) == CONSTRUCTOR
! 		 && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
  	  {
  	    /* Fold a constant vector CONSTRUCTOR to VECTOR_CST.  */
  	    unsigned i;
  	    tree val;
  
  	    FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
! 	      if (! CONSTANT_CLASS_P (val))
  		return NULL_TREE;
  
  	    return build_vector_from_ctor (TREE_TYPE (rhs),
*************** fold_gimple_assign (gimple_stmt_iterator
*** 394,414 ****
  
  	else if (DECL_P (rhs))
  	  return get_symbol_constant_value (rhs);
- 
-         /* If we couldn't fold the RHS, hand over to the generic
-            fold routines.  */
-         if (result == NULL_TREE)
-           result = fold (rhs);
- 
-         /* Strip away useless type conversions.  Both the NON_LVALUE_EXPR
-            that may have been added by fold, and "useless" type
-            conversions that might now be apparent due to propagation.  */
-         STRIP_USELESS_TYPE_CONVERSION (result);
- 
-         if (result != rhs && valid_gimple_rhs_p (result))
- 	  return result;
- 
- 	return NULL_TREE;
        }
        break;
  
--- 402,407 ----
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 229520)
--- gcc/tree.c	(working copy)
*************** tree
*** 1730,1742 ****
  build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
  {
    tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
!   unsigned HOST_WIDE_INT idx;
    tree value;
  
    FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
!     vec[idx] = value;
    for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
!     vec[idx] = build_zero_cst (TREE_TYPE (type));
  
    return build_vector (type, vec);
  }
--- 1730,1748 ----
  build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
  {
    tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
!   unsigned HOST_WIDE_INT idx, pos = 0;
    tree value;
  
    FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
!     {
!       if (TREE_CODE (value) == VECTOR_CST)
! 	for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i)
! 	  vec[pos++] = VECTOR_CST_ELT (value, i);
!       else
! 	vec[pos++] = value;
!     }
    for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
!     vec[pos++] = build_zero_cst (TREE_TYPE (type));
  
    return build_vector (type, vec);
  }
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 229520)
--- gcc/fold-const.c	(working copy)
*************** fold (tree expr)
*** 11960,11985 ****
  	if (TREE_CODE (type) != VECTOR_TYPE)
  	  return t;
  
! 	tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
! 	unsigned HOST_WIDE_INT idx, pos = 0;
! 	tree value;
! 
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, value)
! 	  {
! 	    if (!CONSTANT_CLASS_P (value))
! 	      return t;
! 	    if (TREE_CODE (value) == VECTOR_CST)
! 	      {
! 		for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i)
! 		  vec[pos++] = VECTOR_CST_ELT (value, i);
! 	      }
! 	    else
! 	      vec[pos++] = value;
! 	  }
! 	for (; pos < TYPE_VECTOR_SUBPARTS (type); ++pos)
! 	  vec[pos] = build_zero_cst (TREE_TYPE (type));
  
! 	return build_vector (type, vec);
        }
  
      case CONST_DECL:
--- 11977,11989 ----
  	if (TREE_CODE (type) != VECTOR_TYPE)
  	  return t;
  
! 	unsigned i;
! 	tree val;
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
! 	  if (! CONSTANT_CLASS_P (val))
! 	    return t;
  
! 	return build_vector_from_ctor (type, CONSTRUCTOR_ELTS (t));
        }
  
      case CONST_DECL:


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