diff gcc/tree-chrec.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/tree-chrec.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/tree-chrec.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 /* Chains of recurrences.
-   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   Copyright (C) 2003-2018 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <pop@cri.ensmp.fr>
 
 This file is part of GCC.
@@ -41,53 +41,6 @@
 
 /* Extended folder for chrecs.  */
 
-/* Determines whether CST is not a constant evolution.  */
-
-static inline bool
-is_not_constant_evolution (const_tree cst)
-{
-  return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
-}
-
-/* Fold CODE for a polynomial function and a constant.  */
-
-static inline tree
-chrec_fold_poly_cst (enum tree_code code,
-		     tree type,
-		     tree poly,
-		     tree cst)
-{
-  gcc_assert (poly);
-  gcc_assert (cst);
-  gcc_assert (TREE_CODE (poly) == POLYNOMIAL_CHREC);
-  gcc_checking_assert (!is_not_constant_evolution (cst));
-  gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly)));
-
-  switch (code)
-    {
-    case PLUS_EXPR:
-      return build_polynomial_chrec
-	(CHREC_VARIABLE (poly),
-	 chrec_fold_plus (type, CHREC_LEFT (poly), cst),
-	 CHREC_RIGHT (poly));
-
-    case MINUS_EXPR:
-      return build_polynomial_chrec
-	(CHREC_VARIABLE (poly),
-	 chrec_fold_minus (type, CHREC_LEFT (poly), cst),
-	 CHREC_RIGHT (poly));
-
-    case MULT_EXPR:
-      return build_polynomial_chrec
-	(CHREC_VARIABLE (poly),
-	 chrec_fold_multiply (type, CHREC_LEFT (poly), cst),
-	 chrec_fold_multiply (type, CHREC_RIGHT (poly), cst));
-
-    default:
-      return chrec_dont_know;
-    }
-}
-
 /* Fold the addition of two polynomial functions.  */
 
 static inline tree
@@ -295,8 +248,23 @@
 	  return chrec_fold_plus_poly_poly (code, type, op0, op1);
 
 	CASE_CONVERT:
-	  if (tree_contains_chrecs (op1, NULL))
-	    return chrec_dont_know;
+	  {
+	    /* We can strip sign-conversions to signed by performing the
+	       operation in unsigned.  */
+	    tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
+	    if (INTEGRAL_TYPE_P (type)
+		&& INTEGRAL_TYPE_P (optype)
+		&& tree_nop_conversion_p (type, optype)
+		&& TYPE_UNSIGNED (optype))
+	      return chrec_convert (type,
+				    chrec_fold_plus_1 (code, optype,
+						       chrec_convert (optype,
+								      op0, NULL),
+						       TREE_OPERAND (op1, 0)),
+				    NULL);
+	    if (tree_contains_chrecs (op1, NULL))
+	      return chrec_dont_know;
+	  }
 	  /* FALLTHRU */
 
 	default:
@@ -313,8 +281,23 @@
 	}
 
     CASE_CONVERT:
-      if (tree_contains_chrecs (op0, NULL))
-	return chrec_dont_know;
+      {
+	/* We can strip sign-conversions to signed by performing the
+	   operation in unsigned.  */
+	tree optype = TREE_TYPE (TREE_OPERAND (op0, 0));
+	if (INTEGRAL_TYPE_P (type)
+	    && INTEGRAL_TYPE_P (optype)
+	    && tree_nop_conversion_p (type, optype)
+	    && TYPE_UNSIGNED (optype))
+	  return chrec_convert (type,
+				chrec_fold_plus_1 (code, optype,
+						   TREE_OPERAND (op0, 0),
+						   chrec_convert (optype,
+								  op1, NULL)),
+				NULL);
+	if (tree_contains_chrecs (op0, NULL))
+	  return chrec_dont_know;
+      }
       /* FALLTHRU */
 
     default:
@@ -498,7 +481,7 @@
 static tree
 tree_fold_binomial (tree type, tree n, unsigned int k)
 {
-  bool overflow;
+  wi::overflow_type overflow;
   unsigned int i;
 
   /* Handle the most frequent cases.  */
@@ -961,6 +944,7 @@
 
   if (TREE_CODE (chrec) == SSA_NAME
       || VAR_P (chrec)
+      || TREE_CODE (chrec) == POLY_INT_CST
       || TREE_CODE (chrec) == PARM_DECL
       || TREE_CODE (chrec) == FUNCTION_DECL
       || TREE_CODE (chrec) == LABEL_DECL
@@ -1161,6 +1145,7 @@
 	    return false;
 	  break;
 	}
+      return true;
 
     default:
       return true;