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] Factor and export a const_unop, export const_binop


The following patch is to avoid needlessly recursing to generic_simplify
from fold_unary when we ask to perform constant folding.  Similar
fold_binary is currently entered to constant fold from 
gimple/generic_simplify and will do extra work in case it isn't able
to fold the constant operation.

To mitigate that (and still missing the fold_ternary case - to be done
as followup in case this gets accepted at this point) - I factor and
export a const_unop and provide an exported const_binop which also
knows to dispatch to fold_relational_const.  These API are intended
to provide pure constant folding (that is, all-constant operands,
not only a constant result).

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok at this point?
(it should fix a tiny compile-time regression)

I'll followup with a const_ternop (better name?) if ok.

Thanks,
Richard.

2014-11-19  Richard Biener  <rguenther@suse.de>

	* fold-const.h (const_unop): Declare.
	(const_binop): Likewise.
	* fold-const.c (const_binop): Export overload that expects
	a type parameter and dispatches to fold_relational_const as well.
	Check both operand kinds for guarding the transforms.
	(const_unop): New function, with constant folding from fold_unary_loc.
	(fold_unary_loc): Dispatch to const_unop for tcc_constant operand.
	Remove constant folding done there from the simplifications.
	(fold_binary_loc): Check for constants using CONSTANT_CLASS_P.
	(fold_negate_expr): Remove dead code from the REAL_CST case.
	Avoid building garbage in the COMPLEX_CST case.
	* gimple-match-head.c (gimple_resimplify1): Dispatch to
	const_unop.
	(gimple_resimplify2): Dispatch to const_binop.
	(gimple_simplify): Likewise.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c.orig	2014-11-18 15:16:04.263514898 +0100
--- gcc/fold-const.c	2014-11-19 13:22:24.866032427 +0100
*************** static bool negate_expr_p (tree);
*** 115,121 ****
  static tree negate_expr (tree);
  static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
  static tree associate_trees (location_t, tree, tree, enum tree_code, tree);
- static tree const_binop (enum tree_code, tree, tree);
  static enum comparison_code comparison_to_compcode (enum tree_code);
  static enum tree_code compcode_to_comparison (enum comparison_code);
  static int operand_equal_for_comparison_p (tree, tree, tree);
--- 115,120 ----
*************** static tree fold_negate_const (tree, tre
*** 156,161 ****
--- 155,163 ----
  static tree fold_not_const (const_tree, tree);
  static tree fold_relational_const (enum tree_code, tree, tree, tree);
  static tree fold_convert_const (enum tree_code, tree, tree);
+ static tree fold_view_convert_expr (tree, tree);
+ static bool vec_cst_ctor_to_array (tree, tree *);
+ 
  
  /* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION.
     Otherwise, return LOC.  */
*************** fold_negate_expr (location_t loc, tree t
*** 561,570 ****
  
      case REAL_CST:
        tem = fold_negate_const (t, type);
!       /* Two's complement FP formats, such as c4x, may overflow.  */
!       if (!TREE_OVERFLOW (tem) || !flag_trapping_math)
! 	return tem;
!       break;
  
      case FIXED_CST:
        tem = fold_negate_const (t, type);
--- 563,569 ----
  
      case REAL_CST:
        tem = fold_negate_const (t, type);
!       return tem;
  
      case FIXED_CST:
        tem = fold_negate_const (t, type);
*************** fold_negate_expr (location_t loc, tree t
*** 572,584 ****
  
      case COMPLEX_CST:
        {
! 	tree rpart = negate_expr (TREE_REALPART (t));
! 	tree ipart = negate_expr (TREE_IMAGPART (t));
! 
! 	if ((TREE_CODE (rpart) == REAL_CST
! 	     && TREE_CODE (ipart) == REAL_CST)
! 	    || (TREE_CODE (rpart) == INTEGER_CST
! 		&& TREE_CODE (ipart) == INTEGER_CST))
  	  return build_complex (type, rpart, ipart);
        }
        break;
--- 571,579 ----
  
      case COMPLEX_CST:
        {
! 	tree rpart = fold_negate_expr (loc, TREE_REALPART (t));
! 	tree ipart = fold_negate_expr (loc, TREE_IMAGPART (t));
! 	if (rpart && ipart)
  	  return build_complex (type, rpart, ipart);
        }
        break;
*************** const_binop (enum tree_code code, tree a
*** 1135,1144 ****
    STRIP_NOPS (arg1);
    STRIP_NOPS (arg2);
  
!   if (TREE_CODE (arg1) == INTEGER_CST)
      return int_const_binop (code, arg1, arg2);
  
!   if (TREE_CODE (arg1) == REAL_CST)
      {
        machine_mode mode;
        REAL_VALUE_TYPE d1;
--- 1130,1139 ----
    STRIP_NOPS (arg1);
    STRIP_NOPS (arg2);
  
!   if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST)
      return int_const_binop (code, arg1, arg2);
  
!   if (TREE_CODE (arg1) == REAL_CST && TREE_CODE (arg2) == REAL_CST)
      {
        machine_mode mode;
        REAL_VALUE_TYPE d1;
*************** const_binop (enum tree_code code, tree a
*** 1216,1222 ****
        return t;
      }
  
!   if (TREE_CODE (arg1) == FIXED_CST)
      {
        FIXED_VALUE_TYPE f1;
        FIXED_VALUE_TYPE f2;
--- 1211,1217 ----
        return t;
      }
  
!   if (TREE_CODE (arg1) == FIXED_CST && TREE_CODE (arg2) == FIXED_CST)
      {
        FIXED_VALUE_TYPE f1;
        FIXED_VALUE_TYPE f2;
*************** const_binop (enum tree_code code, tree a
*** 1260,1266 ****
        return t;
      }
  
!   if (TREE_CODE (arg1) == COMPLEX_CST)
      {
        tree type = TREE_TYPE (arg1);
        tree r1 = TREE_REALPART (arg1);
--- 1255,1261 ----
        return t;
      }
  
!   if (TREE_CODE (arg1) == COMPLEX_CST && TREE_CODE (arg2) == COMPLEX_CST)
      {
        tree type = TREE_TYPE (arg1);
        tree r1 = TREE_REALPART (arg1);
*************** const_binop (enum tree_code code, tree a
*** 1437,1442 ****
--- 1432,1610 ----
    return NULL_TREE;
  }
  
+ /* Overload that adds a TYPE parameter to be able to dispatch
+    to fold_relational_const.  */
+ 
+ tree
+ const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
+ {
+   if (TREE_CODE_CLASS (code) == tcc_comparison)
+     return fold_relational_const (code, type, arg1, arg2);
+   else
+     return const_binop (code, arg1, arg2);
+ }
+ 
+ /* Compute CODE ARG1 with resulting type TYPE with ARG1 being constant.
+    Return zero if computing the constants is not possible.  */
+ 
+ tree
+ const_unop (enum tree_code code, tree type, tree arg0)
+ {
+   switch (code)
+     {
+     CASE_CONVERT:
+     case FLOAT_EXPR:
+     case FIX_TRUNC_EXPR:
+     case FIXED_CONVERT_EXPR:
+       return fold_convert_const (code, type, arg0);
+ 
+     case ADDR_SPACE_CONVERT_EXPR:
+       if (integer_zerop (arg0))
+ 	return fold_convert_const (code, type, arg0);
+       break;
+ 
+     case VIEW_CONVERT_EXPR:
+       return fold_view_convert_expr (type, arg0);
+ 
+     case NEGATE_EXPR:
+       {
+ 	/* Can't call fold_negate_const directly here as that doesn't
+ 	   handle all cases and we might not be able to negate some
+ 	   constants.  */
+ 	tree tem = fold_negate_expr (UNKNOWN_LOCATION, arg0);
+ 	if (tem && CONSTANT_CLASS_P (tem))
+ 	  return tem;
+ 	break;
+       }
+ 
+     case ABS_EXPR:
+       return fold_abs_const (arg0, type);
+ 
+     case CONJ_EXPR:
+       if (TREE_CODE (arg0) == COMPLEX_CST)
+ 	{
+ 	  tree ipart = fold_negate_const (TREE_IMAGPART (arg0),
+ 					  TREE_TYPE (type));
+ 	  return build_complex (type, TREE_REALPART (arg0), ipart);
+ 	}
+       break;
+ 
+     case BIT_NOT_EXPR:
+       if (TREE_CODE (arg0) == INTEGER_CST)
+ 	return fold_not_const (arg0, type);
+       /* Perform BIT_NOT_EXPR on each element individually.  */
+       else if (TREE_CODE (arg0) == VECTOR_CST)
+ 	{
+ 	  tree *elements;
+ 	  tree elem;
+ 	  unsigned count = VECTOR_CST_NELTS (arg0), i;
+ 
+ 	  elements = XALLOCAVEC (tree, count);
+ 	  for (i = 0; i < count; i++)
+ 	    {
+ 	      elem = VECTOR_CST_ELT (arg0, i);
+ 	      elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem);
+ 	      if (elem == NULL_TREE)
+ 		break;
+ 	      elements[i] = elem;
+ 	    }
+ 	  if (i == count)
+ 	    return build_vector (type, elements);
+ 	}
+       break;
+ 
+     case TRUTH_NOT_EXPR:
+       if (TREE_CODE (arg0) == INTEGER_CST)
+ 	return constant_boolean_node (integer_zerop (arg0), type);
+       break;
+ 
+     case REALPART_EXPR:
+       if (TREE_CODE (arg0) == COMPLEX_CST)
+ 	return fold_convert (type, TREE_REALPART (arg0));
+       break;
+ 
+     case IMAGPART_EXPR:
+       if (TREE_CODE (arg0) == COMPLEX_CST)
+ 	return fold_convert (type, TREE_IMAGPART (arg0));
+       break;
+ 
+     case VEC_UNPACK_LO_EXPR:
+     case VEC_UNPACK_HI_EXPR:
+     case VEC_UNPACK_FLOAT_LO_EXPR:
+     case VEC_UNPACK_FLOAT_HI_EXPR:
+       {
+ 	unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+ 	tree *elts;
+ 	enum tree_code subcode;
+ 
+ 	gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2);
+ 	if (TREE_CODE (arg0) != VECTOR_CST)
+ 	  return NULL_TREE;
+ 
+ 	elts = XALLOCAVEC (tree, nelts * 2);
+ 	if (!vec_cst_ctor_to_array (arg0, elts))
+ 	  return NULL_TREE;
+ 
+ 	if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
+ 				   || code == VEC_UNPACK_FLOAT_LO_EXPR))
+ 	  elts += nelts;
+ 
+ 	if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
+ 	  subcode = NOP_EXPR;
+ 	else
+ 	  subcode = FLOAT_EXPR;
+ 
+ 	for (i = 0; i < nelts; i++)
+ 	  {
+ 	    elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
+ 	    if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
+ 	      return NULL_TREE;
+ 	  }
+ 
+ 	return build_vector (type, elts);
+       }
+ 
+     case REDUC_MIN_EXPR:
+     case REDUC_MAX_EXPR:
+     case REDUC_PLUS_EXPR:
+       {
+ 	unsigned int nelts, i;
+ 	tree *elts;
+ 	enum tree_code subcode;
+ 
+ 	if (TREE_CODE (arg0) != VECTOR_CST)
+ 	  return NULL_TREE;
+         nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+ 
+ 	elts = XALLOCAVEC (tree, nelts);
+ 	if (!vec_cst_ctor_to_array (arg0, elts))
+ 	  return NULL_TREE;
+ 
+ 	switch (code)
+ 	  {
+ 	  case REDUC_MIN_EXPR: subcode = MIN_EXPR; break;
+ 	  case REDUC_MAX_EXPR: subcode = MAX_EXPR; break;
+ 	  case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break;
+ 	  default: gcc_unreachable ();
+ 	  }
+ 
+ 	for (i = 1; i < nelts; i++)
+ 	  {
+ 	    elts[0] = const_binop (subcode, elts[0], elts[i]);
+ 	    if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0]))
+ 	      return NULL_TREE;
+ 	  }
+ 
+ 	return elts[0];
+       }
+ 
+     default:
+       break;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
  /* Create a sizetype INT_CST node with NUMBER sign extended.  KIND
     indicates which particular sizetype to create.  */
  
*************** build_fold_addr_expr_loc (location_t loc
*** 7504,7511 ****
    return build_fold_addr_expr_with_type_loc (loc, t, ptrtype);
  }
  
- static bool vec_cst_ctor_to_array (tree, tree *);
- 
  /* Fold a unary expression of code CODE and type TYPE with operand
     OP0.  Return the folded expression if folding is successful.
     Otherwise, return NULL_TREE.  */
--- 7672,7677 ----
*************** fold_unary_loc (location_t loc, enum tre
*** 7520,7529 ****
    gcc_assert (IS_EXPR_CODE_CLASS (kind)
  	      && TREE_CODE_LENGTH (code) == 1);
  
-   tem = generic_simplify (loc, code, type, op0);
-   if (tem)
-     return tem;
- 
    arg0 = op0;
    if (arg0)
      {
--- 7686,7691 ----
*************** fold_unary_loc (location_t loc, enum tre
*** 7549,7556 ****
--- 7711,7733 ----
  	     constant folder.  */
  	  STRIP_NOPS (arg0);
  	}
+ 
+       if (CONSTANT_CLASS_P (arg0))
+ 	{
+ 	  tree tem = const_unop (code, type, arg0);
+ 	  if (tem)
+ 	    {
+ 	      if (TREE_TYPE (tem) != type)
+ 		tem = fold_convert_loc (loc, type, tem);
+ 	      return tem;
+ 	    }
+ 	}
      }
  
+   tem = generic_simplify (loc, code, type, op0);
+   if (tem)
+     return tem;
+ 
    if (TREE_CODE_CLASS (code) == tcc_unary)
      {
        if (TREE_CODE (arg0) == COMPOUND_EXPR)
*************** fold_unary_loc (location_t loc, enum tre
*** 7787,7810 ****
  	    }
  	}
  
-       tem = fold_convert_const (code, type, arg0);
-       return tem ? tem : NULL_TREE;
- 
-     case ADDR_SPACE_CONVERT_EXPR:
-       if (integer_zerop (arg0))
- 	return fold_convert_const (code, type, arg0);
        return NULL_TREE;
  
-     case FIXED_CONVERT_EXPR:
-       tem = fold_convert_const (code, type, arg0);
-       return tem ? tem : NULL_TREE;
- 
      case VIEW_CONVERT_EXPR:
        if (TREE_CODE (op0) == MEM_REF)
  	return fold_build2_loc (loc, MEM_REF, type,
  				TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
  
!       return fold_view_convert_expr (type, op0);
  
      case NEGATE_EXPR:
        tem = fold_negate_expr (loc, arg0);
--- 7964,7977 ----
  	    }
  	}
  
        return NULL_TREE;
  
      case VIEW_CONVERT_EXPR:
        if (TREE_CODE (op0) == MEM_REF)
  	return fold_build2_loc (loc, MEM_REF, type,
  				TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
  
!       return NULL_TREE;
  
      case NEGATE_EXPR:
        tem = fold_negate_expr (loc, arg0);
*************** fold_unary_loc (location_t loc, enum tre
*** 7813,7823 ****
        return NULL_TREE;
  
      case ABS_EXPR:
-       if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
- 	return fold_abs_const (arg0, type);
        /* Convert fabs((double)float) into (double)fabsf(float).  */
!       else if (TREE_CODE (arg0) == NOP_EXPR
! 	       && TREE_CODE (type) == REAL_TYPE)
  	{
  	  tree targ0 = strip_float_extensions (arg0);
  	  if (targ0 != arg0)
--- 7980,7988 ----
        return NULL_TREE;
  
      case ABS_EXPR:
        /* Convert fabs((double)float) into (double)fabsf(float).  */
!       if (TREE_CODE (arg0) == NOP_EXPR
! 	  && TREE_CODE (type) == REAL_TYPE)
  	{
  	  tree targ0 = strip_float_extensions (arg0);
  	  if (targ0 != arg0)
*************** fold_unary_loc (location_t loc, enum tre
*** 7851,7872 ****
  	  return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart,
  			      negate_expr (ipart));
  	}
-       if (TREE_CODE (arg0) == COMPLEX_CST)
- 	{
- 	  tree itype = TREE_TYPE (type);
- 	  tree rpart = fold_convert_loc (loc, itype, TREE_REALPART (arg0));
- 	  tree ipart = fold_convert_loc (loc, itype, TREE_IMAGPART (arg0));
- 	  return build_complex (type, rpart, negate_expr (ipart));
- 	}
        if (TREE_CODE (arg0) == CONJ_EXPR)
  	return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
        return NULL_TREE;
  
      case BIT_NOT_EXPR:
-       if (TREE_CODE (arg0) == INTEGER_CST)
-         return fold_not_const (arg0, type);
        /* Convert ~ (-A) to A - 1.  */
!       else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
  	return fold_build2_loc (loc, MINUS_EXPR, type,
  			    fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)),
  			    build_int_cst (type, 1));
--- 8016,8028 ----
  	  return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart,
  			      negate_expr (ipart));
  	}
        if (TREE_CODE (arg0) == CONJ_EXPR)
  	return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
        return NULL_TREE;
  
      case BIT_NOT_EXPR:
        /* Convert ~ (-A) to A - 1.  */
!       if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
  	return fold_build2_loc (loc, MINUS_EXPR, type,
  			    fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)),
  			    build_int_cst (type, 1));
*************** fold_unary_loc (location_t loc, enum tre
*** 7894,7918 ****
  	return fold_build2_loc (loc, BIT_XOR_EXPR, type,
  			    fold_convert_loc (loc, type,
  					      TREE_OPERAND (arg0, 0)), tem);
-       /* Perform BIT_NOT_EXPR on each element individually.  */
-       else if (TREE_CODE (arg0) == VECTOR_CST)
- 	{
- 	  tree *elements;
- 	  tree elem;
- 	  unsigned count = VECTOR_CST_NELTS (arg0), i;
- 
- 	  elements = XALLOCAVEC (tree, count);
- 	  for (i = 0; i < count; i++)
- 	    {
- 	      elem = VECTOR_CST_ELT (arg0, i);
- 	      elem = fold_unary_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type), elem);
- 	      if (elem == NULL_TREE)
- 		break;
- 	      elements[i] = elem;
- 	    }
- 	  if (i == count)
- 	    return build_vector (type, elements);
- 	}
  
        return NULL_TREE;
  
--- 8050,8055 ----
*************** fold_unary_loc (location_t loc, enum tre
*** 7929,7936 ****
      case REALPART_EXPR:
        if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
  	return fold_convert_loc (loc, type, arg0);
-       if (TREE_CODE (arg0) == COMPLEX_CST)
- 	return fold_convert_loc (loc, type, TREE_REALPART (arg0));
        if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
  	{
  	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
--- 8066,8071 ----
*************** fold_unary_loc (location_t loc, enum tre
*** 7969,7976 ****
      case IMAGPART_EXPR:
        if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
  	return build_zero_cst (type);
-       if (TREE_CODE (arg0) == COMPLEX_CST)
- 	return fold_convert_loc (loc, type, TREE_IMAGPART (arg0));
        if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
  	{
  	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
--- 8104,8109 ----
*************** fold_unary_loc (location_t loc, enum tre
*** 8018,8093 ****
  	}
        return NULL_TREE;
  
-     case VEC_UNPACK_LO_EXPR:
-     case VEC_UNPACK_HI_EXPR:
-     case VEC_UNPACK_FLOAT_LO_EXPR:
-     case VEC_UNPACK_FLOAT_HI_EXPR:
-       {
- 	unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
- 	tree *elts;
- 	enum tree_code subcode;
- 
- 	gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2);
- 	if (TREE_CODE (arg0) != VECTOR_CST)
- 	  return NULL_TREE;
- 
- 	elts = XALLOCAVEC (tree, nelts * 2);
- 	if (!vec_cst_ctor_to_array (arg0, elts))
- 	  return NULL_TREE;
- 
- 	if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
- 				   || code == VEC_UNPACK_FLOAT_LO_EXPR))
- 	  elts += nelts;
- 
- 	if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
- 	  subcode = NOP_EXPR;
- 	else
- 	  subcode = FLOAT_EXPR;
- 
- 	for (i = 0; i < nelts; i++)
- 	  {
- 	    elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
- 	    if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
- 	      return NULL_TREE;
- 	  }
- 
- 	return build_vector (type, elts);
-       }
- 
-     case REDUC_MIN_EXPR:
-     case REDUC_MAX_EXPR:
-     case REDUC_PLUS_EXPR:
-       {
- 	unsigned int nelts, i;
- 	tree *elts;
- 	enum tree_code subcode;
- 
- 	if (TREE_CODE (op0) != VECTOR_CST)
- 	  return NULL_TREE;
-         nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (op0));
- 
- 	elts = XALLOCAVEC (tree, nelts);
- 	if (!vec_cst_ctor_to_array (op0, elts))
- 	  return NULL_TREE;
- 
- 	switch (code)
- 	  {
- 	  case REDUC_MIN_EXPR: subcode = MIN_EXPR; break;
- 	  case REDUC_MAX_EXPR: subcode = MAX_EXPR; break;
- 	  case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break;
- 	  default: gcc_unreachable ();
- 	  }
- 
- 	for (i = 1; i < nelts; i++)
- 	  {
- 	    elts[0] = const_binop (subcode, elts[0], elts[i]);
- 	    if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0]))
- 	      return NULL_TREE;
- 	  }
- 
- 	return elts[0];
-       }
- 
      default:
        return NULL_TREE;
      } /* switch (code) */
--- 8151,8156 ----
*************** fold_binary_loc (location_t loc,
*** 9686,9704 ****
  
    /* Note that TREE_CONSTANT isn't enough: static var addresses are
       constant but we can't do arithmetic on them.  */
!   if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
!       || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
!       || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST)
!       || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST)
!       || (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
!       || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)
!       || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == INTEGER_CST))
      {
        if (kind == tcc_binary)
  	{
  	  /* Make sure type and arg0 have the same saturating flag.  */
! 	  gcc_assert (TYPE_SATURATING (type)
! 		      == TYPE_SATURATING (TREE_TYPE (arg0)));
  	  tem = const_binop (code, arg0, arg1);
  	}
        else if (kind == tcc_comparison)
--- 9749,9761 ----
  
    /* Note that TREE_CONSTANT isn't enough: static var addresses are
       constant but we can't do arithmetic on them.  */
!   if (CONSTANT_CLASS_P (arg0) && CONSTANT_CLASS_P (arg1))
      {
        if (kind == tcc_binary)
  	{
  	  /* Make sure type and arg0 have the same saturating flag.  */
! 	  gcc_checking_assert (TYPE_SATURATING (type)
! 			       == TYPE_SATURATING (TREE_TYPE (arg0)));
  	  tem = const_binop (code, arg0, arg1);
  	}
        else if (kind == tcc_comparison)
Index: gcc/fold-const.h
===================================================================
*** gcc/fold-const.h.orig	2014-11-18 15:16:04.263514898 +0100
--- gcc/fold-const.h	2014-11-19 13:19:18.444040585 +0100
*************** extern bool merge_ranges (int *, tree *,
*** 169,173 ****
--- 169,175 ----
  			  tree, tree);
  extern tree sign_bit_p (tree, const_tree);
  extern tree exact_inverse (tree, tree);
+ extern tree const_unop (enum tree_code, tree, tree);
+ extern tree const_binop (enum tree_code, tree, tree, tree);
  
  #endif // GCC_FOLD_CONST_H
Index: gcc/gimple-match-head.c
===================================================================
*** gcc/gimple-match-head.c.orig	2014-11-18 15:16:04.263514898 +0100
--- gcc/gimple-match-head.c	2014-11-19 13:19:18.450040585 +0100
*************** gimple_resimplify1 (gimple_seq *seq,
*** 94,100 ****
      {
        tree tem = NULL_TREE;
        if (res_code->is_tree_code ())
! 	tem = fold_unary_to_constant (*res_code, type, res_ops[0]);
        else
  	{
  	  tree decl = builtin_decl_implicit (*res_code);
--- 94,100 ----
      {
        tree tem = NULL_TREE;
        if (res_code->is_tree_code ())
! 	tem = const_unop (*res_code, type, res_ops[0]);
        else
  	{
  	  tree decl = builtin_decl_implicit (*res_code);
*************** gimple_resimplify2 (gimple_seq *seq,
*** 150,157 ****
      {
        tree tem = NULL_TREE;
        if (res_code->is_tree_code ())
! 	tem = fold_binary_to_constant (*res_code, type,
! 				       res_ops[0], res_ops[1]);
        else
  	{
  	  tree decl = builtin_decl_implicit (*res_code);
--- 150,156 ----
      {
        tree tem = NULL_TREE;
        if (res_code->is_tree_code ())
! 	tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
        else
  	{
  	  tree decl = builtin_decl_implicit (*res_code);
*************** gimple_simplify (enum tree_code code, tr
*** 386,392 ****
  {
    if (constant_for_folding (op0))
      {
!       tree res = fold_unary_to_constant (code, type, op0);
        if (res != NULL_TREE
  	  && CONSTANT_CLASS_P (res))
  	return res;
--- 385,391 ----
  {
    if (constant_for_folding (op0))
      {
!       tree res = const_unop (code, type, op0);
        if (res != NULL_TREE
  	  && CONSTANT_CLASS_P (res))
  	return res;
*************** gimple_simplify (enum tree_code code, tr
*** 409,415 ****
  {
    if (constant_for_folding (op0) && constant_for_folding (op1))
      {
!       tree res = fold_binary_to_constant (code, type, op0, op1);
        if (res != NULL_TREE
  	  && CONSTANT_CLASS_P (res))
  	return res;
--- 408,414 ----
  {
    if (constant_for_folding (op0) && constant_for_folding (op1))
      {
!       tree res = const_binop (code, type, op0, op1);
        if (res != NULL_TREE
  	  && CONSTANT_CLASS_P (res))
  	return res;


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