tree-flow.h (number_of_iterations_cond): Declaration removed.
authorZdenek Dvorak <dvorakz@suse.cz>
Tue, 5 Apr 2005 23:52:41 +0000 (01:52 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Tue, 5 Apr 2005 23:52:41 +0000 (23:52 +0000)
* tree-flow.h (number_of_iterations_cond): Declaration removed.
* tree-ssa-loop-niter.c (number_of_iterations_cond): Made static.
(number_of_iterations_special): New function.
(number_of_iterations_exit): Use number_of_iterations_special.
Use simplify_using_outer_evolutions only at -O3.
(number_of_iterations_cond, tree_simplify_using_condition,
simplify_using_initial_conditions, loop_niter_by_eval,
compare_trees, can_count_iv_in_wider_type_bound,
simplify_using_outer_evolutions): Use fold_build.

From-SVN: r97673

gcc/ChangeLog
gcc/tree-flow.h
gcc/tree-ssa-loop-niter.c

index b70fd2cfc59867b4418db8ed5b02d367889a917f..4c7b2aee115bb10100b6721bb8e04cea1a494e54 100644 (file)
@@ -1,3 +1,15 @@
+2005-04-06  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * tree-flow.h (number_of_iterations_cond): Declaration removed.
+       * tree-ssa-loop-niter.c (number_of_iterations_cond): Made static.
+       (number_of_iterations_special): New function.
+       (number_of_iterations_exit): Use number_of_iterations_special.
+       Use simplify_using_outer_evolutions only at -O3.
+       (number_of_iterations_cond, tree_simplify_using_condition,
+       simplify_using_initial_conditions, loop_niter_by_eval,
+       compare_trees, can_count_iv_in_wider_type_bound,
+       simplify_using_outer_evolutions): Use fold_build.
+
 2005-04-05  Thomas Fitzsimmons  <fitzsim@redhat.com>
 
        * doc/install.texi (Configuration): Document --with-java-home.
index ebc31ab27f6ad6381a80055d21e362cf73efdf83..b06a802be21f8f86c97f4a279c452e05677a92e4 100644 (file)
@@ -673,8 +673,6 @@ void canonicalize_induction_variables (struct loops *);
 void tree_unroll_loops_completely (struct loops *);
 void tree_ssa_iv_optimize (struct loops *);
 
-void number_of_iterations_cond (tree, tree, tree, enum tree_code, tree, tree,
-                               struct tree_niter_desc *);
 bool number_of_iterations_exit (struct loop *, edge,
                                struct tree_niter_desc *niter);
 tree find_loop_niter (struct loop *, edge *);
index abeb5002e1bc02200c274081231680e6c2840660..35d446cd363a8ca25e6e6ceb2eeedd8df0023d04 100644 (file)
@@ -137,7 +137,7 @@ inverse (tree x, tree mask)
    In case we are unable to determine number of iterations, contents of
    this structure is unchanged.  */
 
-void
+static void
 number_of_iterations_cond (tree type, tree base0, tree step0,
                           enum tree_code code, tree base1, tree step1,
                           struct tree_niter_desc *niter)
@@ -221,24 +221,24 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
       if (zero_p (step0))
        {
          if (mmax)
-           assumption = fold (build2 (EQ_EXPR, boolean_type_node, base0, mmax));
+           assumption = fold_build2 (EQ_EXPR, boolean_type_node, base0, mmax);
          else
            assumption = boolean_false_node;
          if (nonzero_p (assumption))
            goto zero_iter;
-         base0 = fold (build2 (PLUS_EXPR, type, base0,
-                               build_int_cst_type (type, 1)));
+         base0 = fold_build2 (PLUS_EXPR, type, base0,
+                              build_int_cst_type (type, 1));
        }
       else
        {
          if (mmin)
-           assumption = fold (build2 (EQ_EXPR, boolean_type_node, base1, mmin));
+           assumption = fold_build2 (EQ_EXPR, boolean_type_node, base1, mmin);
          else
            assumption = boolean_false_node;
          if (nonzero_p (assumption))
            goto zero_iter;
-         base1 = fold (build2 (MINUS_EXPR, type, base1,
-                               build_int_cst_type (type, 1)));
+         base1 = fold_build2 (MINUS_EXPR, type, base1,
+                              build_int_cst_type (type, 1));
        }
       noloop_assumptions = assumption;
       code = LE_EXPR;
@@ -274,7 +274,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
       else
        step = step0;
       delta = build2 (MINUS_EXPR, type, base1, base0);
-      delta = fold (build2 (FLOOR_MOD_EXPR, type, delta, step));
+      delta = fold_build2 (FLOOR_MOD_EXPR, type, delta, step);
       may_xform = boolean_false_node;
 
       if (TREE_CODE (delta) == INTEGER_CST)
@@ -305,8 +305,8 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
                                                   mmin, step);
                  bound = fold_binary_to_constant (MINUS_EXPR, type,
                                                   bound, delta);
-                 may_xform = fold (build2 (LE_EXPR, boolean_type_node,
-                                          bound, base0));
+                 may_xform = fold_build2 (LE_EXPR, boolean_type_node,
+                                          bound, base0);
                }
            }
          else
@@ -319,8 +319,8 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
                                                   mmax, step);
                  bound = fold_binary_to_constant (PLUS_EXPR, type,
                                                   bound, delta);
-                 may_xform = fold (build2 (LE_EXPR, boolean_type_node,
-                                          base1, bound));
+                 may_xform = fold_build2 (LE_EXPR, boolean_type_node,
+                                          base1, bound);
                }
            }
        }
@@ -335,18 +335,18 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
 
          if (zero_p (step0))
            {
-             base0 = fold (build2 (PLUS_EXPR, type, base0, delta));
-             base0 = fold (build2 (MINUS_EXPR, type, base0, step));
+             base0 = fold_build2 (PLUS_EXPR, type, base0, delta);
+             base0 = fold_build2 (MINUS_EXPR, type, base0, step);
            }
          else
            {
-             base1 = fold (build2 (MINUS_EXPR, type, base1, delta));
-             base1 = fold (build2 (PLUS_EXPR, type, base1, step));
+             base1 = fold_build2 (MINUS_EXPR, type, base1, delta);
+             base1 = fold_build2 (PLUS_EXPR, type, base1, step);
            }
 
-         assumption = fold (build2 (GT_EXPR, boolean_type_node, base0, base1));
-         noloop_assumptions = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
-                                           noloop_assumptions, assumption));
+         assumption = fold_build2 (GT_EXPR, boolean_type_node, base0, base1);
+         noloop_assumptions = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+                                           noloop_assumptions, assumption);
          code = NE_EXPR;
        }
     }
@@ -361,7 +361,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
         makes us able to do more involved computations of number of iterations
         than in other cases.  First transform the condition into shape
         s * i <> c, with s positive.  */
-      base1 = fold (build2 (MINUS_EXPR, type, base1, base0));
+      base1 = fold_build2 (MINUS_EXPR, type, base1, base0);
       base0 = NULL_TREE;
       if (!zero_p (step1))
        step0 = fold_unary_to_constant (NEGATE_EXPR, type, step1);
@@ -369,7 +369,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
       if (!tree_expr_nonnegative_p (fold_convert (signed_niter_type, step0)))
        {
          step0 = fold_unary_to_constant (NEGATE_EXPR, type, step0);
-         base1 = fold (build1 (NEGATE_EXPR, type, base1));
+         base1 = fold_build1 (NEGATE_EXPR, type, base1);
        }
 
       base1 = fold_convert (niter_type, base1);
@@ -387,16 +387,16 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
                                   (TYPE_PRECISION (niter_type)
                                    - tree_low_cst (bits, 1)));
 
-      assumption = fold (build2 (FLOOR_MOD_EXPR, niter_type, base1, d));
-      assumption = fold (build2 (EQ_EXPR, boolean_type_node,
-                                assumption,
-                                build_int_cst (niter_type, 0)));
-      assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
-                                 assumptions, assumption));
+      assumption = fold_build2 (FLOOR_MOD_EXPR, niter_type, base1, d);
+      assumption = fold_build2 (EQ_EXPR, boolean_type_node,
+                               assumption,
+                               build_int_cst (niter_type, 0));
+      assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+                                assumptions, assumption);
 
-      tmp = fold (build2 (EXACT_DIV_EXPR, niter_type, base1, d));
-      tmp = fold (build2 (MULT_EXPR, niter_type, tmp, inverse (s, bound)));
-      niter->niter = fold (build2 (BIT_AND_EXPR, niter_type, tmp, bound));
+      tmp = fold_build2 (EXACT_DIV_EXPR, niter_type, base1, d);
+      tmp = fold_build2 (MULT_EXPR, niter_type, tmp, inverse (s, bound));
+      niter->niter = fold_build2 (BIT_AND_EXPR, niter_type, tmp, bound);
     }
   else
     {
@@ -411,17 +411,17 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
          if (mmax)
            {
              bound = fold_binary_to_constant (MINUS_EXPR, type, mmax, step0);
-             assumption = fold (build2 (LE_EXPR, boolean_type_node,
-                                        base1, bound));
-             assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
-                                         assumptions, assumption));
+             assumption = fold_build2 (LE_EXPR, boolean_type_node,
+                                       base1, bound);
+             assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+                                        assumptions, assumption);
            }
 
          step = step0;
-         tmp = fold (build2 (PLUS_EXPR, type, base1, step0));
-         assumption = fold (build2 (GT_EXPR, boolean_type_node, base0, tmp));
-         delta = fold (build2 (PLUS_EXPR, type, base1, step));
-         delta = fold (build2 (MINUS_EXPR, type, delta, base0));
+         tmp = fold_build2 (PLUS_EXPR, type, base1, step0);
+         assumption = fold_build2 (GT_EXPR, boolean_type_node, base0, tmp);
+         delta = fold_build2 (PLUS_EXPR, type, base1, step);
+         delta = fold_build2 (MINUS_EXPR, type, delta, base0);
          delta = fold_convert (niter_type, delta);
        }
       else
@@ -432,22 +432,22 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
          if (mmin)
            {
              bound = fold_binary_to_constant (MINUS_EXPR, type, mmin, step1);
-             assumption = fold (build2 (LE_EXPR, boolean_type_node,
-                                       bound, base0));
-             assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
-                                        assumptions, assumption));
+             assumption = fold_build2 (LE_EXPR, boolean_type_node,
+                                       bound, base0);
+             assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+                                        assumptions, assumption);
            }
-         step = fold (build1 (NEGATE_EXPR, type, step1));
-         tmp = fold (build2 (PLUS_EXPR, type, base0, step1));
-         assumption = fold (build2 (GT_EXPR, boolean_type_node, tmp, base1));
-         delta = fold (build2 (MINUS_EXPR, type, base0, step));
-         delta = fold (build2 (MINUS_EXPR, type, base1, delta));
+         step = fold_build1 (NEGATE_EXPR, type, step1);
+         tmp = fold_build2 (PLUS_EXPR, type, base0, step1);
+         assumption = fold_build2 (GT_EXPR, boolean_type_node, tmp, base1);
+         delta = fold_build2 (MINUS_EXPR, type, base0, step);
+         delta = fold_build2 (MINUS_EXPR, type, base1, delta);
          delta = fold_convert (niter_type, delta);
        }
-      noloop_assumptions = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
-                                       noloop_assumptions, assumption));
-      delta = fold (build2 (FLOOR_DIV_EXPR, niter_type, delta,
-                           fold_convert (niter_type, step)));
+      noloop_assumptions = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+                                       noloop_assumptions, assumption);
+      delta = fold_build2 (FLOOR_DIV_EXPR, niter_type, delta,
+                          fold_convert (niter_type, step));
       niter->niter = delta;
     }
 
@@ -462,60 +462,131 @@ zero_iter:
   return;
 }
 
-/* Tries to simplify EXPR using the evolutions of the loop invariants
-   in the superloops of LOOP.  Returns the simplified expression
-   (or EXPR unchanged, if no simplification was possible).  */
 
-static tree
-simplify_using_outer_evolutions (struct loop *loop, tree expr)
+/* Similar to number_of_iterations_cond, but only handles the special
+   case of loops with step 1 or -1.  The meaning of the arguments
+   is the same as in number_of_iterations_cond.  The function
+   returns true if the special case was recognized, false otherwise.  */
+
+static bool
+number_of_iterations_special (tree type, tree base0, tree step0,
+                             enum tree_code code, tree base1, tree step1,
+                             struct tree_niter_desc *niter)
 {
-  enum tree_code code = TREE_CODE (expr);
-  bool changed;
-  tree e, e0, e1, e2;
+  tree niter_type = unsigned_type_for (type), mmax, mmin;
 
-  if (is_gimple_min_invariant (expr))
-    return expr;
+  /* Make < comparison from > ones.  */
+  if (code == GE_EXPR
+      || code == GT_EXPR)
+    {
+      SWAP (base0, base1);
+      SWAP (step0, step1);
+      code = swap_tree_comparison (code);
+    }
 
-  if (code == TRUTH_OR_EXPR
-      || code == TRUTH_AND_EXPR
-      || code == COND_EXPR)
+  switch (code)
     {
-      changed = false;
+    case NE_EXPR:
+      if (zero_p (step0))
+       {
+         if (zero_p (step1))
+           return false;
+         SWAP (base0, base1);
+         SWAP (step0, step1);
+       }
+      else if (!zero_p (step1))
+       return false;
 
-      e0 = simplify_using_outer_evolutions (loop, TREE_OPERAND (expr, 0));
-      if (TREE_OPERAND (expr, 0) != e0)
-       changed = true;
+      if (integer_onep (step0))
+       {
+         /* for (i = base0; i != base1; i++)  */
+         niter->assumptions = boolean_true_node;
+         niter->may_be_zero = boolean_false_node;
+         niter->niter = fold_build2 (MINUS_EXPR, type, base1, base0);
+         niter->additional_info = boolean_true_node;
+       }
+      else if (integer_all_onesp (step0))
+       {
+         /* for (i = base0; i != base1; i--)  */
+         niter->assumptions = boolean_true_node;
+         niter->may_be_zero = boolean_false_node;
+         niter->niter = fold_build2 (MINUS_EXPR, type, base0, base1);
+       }
+      else
+       return false;
 
-      e1 = simplify_using_outer_evolutions (loop, TREE_OPERAND (expr, 1));
-      if (TREE_OPERAND (expr, 1) != e1)
-       changed = true;
+      break;
 
-      if (code == COND_EXPR)
+    case LT_EXPR:
+      if ((step0 && integer_onep (step0) && zero_p (step1))
+         || (step1 && integer_all_onesp (step1) && zero_p (step0)))
        {
-         e2 = simplify_using_outer_evolutions (loop, TREE_OPERAND (expr, 2));
-         if (TREE_OPERAND (expr, 2) != e2)
-           changed = true;
+         /* for (i = base0; i < base1; i++)
+            
+            or
+
+            for (i = base1; i > base0; i--).
+            
+            In both cases # of iterations is base1 - base0.  */
+
+         niter->assumptions = boolean_true_node;
+         niter->may_be_zero = fold_build2 (GT_EXPR, boolean_type_node,
+                                           base0, base1);
+         niter->niter = fold_build2 (MINUS_EXPR, type, base1, base0);
        }
       else
-       e2 = NULL_TREE;
+       return false;
+      break;
 
-      if (changed)
+    case LE_EXPR:
+      if (POINTER_TYPE_P (type))
        {
-         if (code == COND_EXPR)
-           expr = build3 (code, boolean_type_node, e0, e1, e2);
+         /* We assume pointer arithmetic never overflows.  */
+         mmin = mmax = NULL_TREE;
+       }
+      else
+       {
+         mmin = TYPE_MIN_VALUE (type);
+         mmax = TYPE_MAX_VALUE (type);
+       }
+
+      if (step0 && integer_onep (step0) && zero_p (step1))
+       {
+         /* for (i = base0; i <= base1; i++)  */
+         if (mmax)
+           niter->assumptions = fold_build2 (NE_EXPR, boolean_type_node,
+                                             base1, mmax);
          else
-           expr = build2 (code, boolean_type_node, e0, e1);
-         expr = fold (expr);
+           niter->assumptions = boolean_true_node;
+         base1 = fold_build2 (PLUS_EXPR, type, base1,
+                              build_int_cst_type (type, 1));
        }
+      else if (step1 && integer_all_onesp (step1) && zero_p (step0))
+       {
+         /* for (i = base1; i >= base0; i--)  */
+         if (mmin)
+           niter->assumptions = fold_build2 (NE_EXPR, boolean_type_node,
+                                             base0, mmin);
+         else
+           niter->assumptions = boolean_true_node;
+         base0 = fold_build2 (MINUS_EXPR, type, base0,
+                              build_int_cst_type (type, 1));
+       }
+      else
+       return false;
 
-      return expr;
-    }
+      niter->may_be_zero = fold_build2 (GT_EXPR, boolean_type_node,
+                                       base0, base1);
+      niter->niter = fold_build2 (MINUS_EXPR, type, base1, base0);
+      break;
 
-  e = instantiate_parameters (loop, expr);
-  if (is_gimple_min_invariant (e))
-    return e;
+    default:
+      gcc_unreachable ();
+    }
 
-  return expr;
+  niter->niter = fold_convert (niter_type, niter->niter);
+  niter->additional_info = boolean_true_node;
+  return true;
 }
 
 /* Substitute NEW for OLD in EXPR and fold the result.  */
@@ -592,10 +663,9 @@ tree_simplify_using_condition (tree cond, tree expr)
       if (changed)
        {
          if (code == COND_EXPR)
-           expr = build3 (code, boolean_type_node, e0, e1, e2);
+           expr = fold_build3 (code, boolean_type_node, e0, e1, e2);
          else
-           expr = build2 (code, boolean_type_node, e0, e1);
-         expr = fold (expr);
+           expr = fold_build2 (code, boolean_type_node, e0, e1);
        }
 
       return expr;
@@ -648,14 +718,14 @@ tree_simplify_using_condition (tree cond, tree expr)
 
   /* Check whether COND ==> EXPR.  */
   notcond = invert_truthvalue (cond);
-  e = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
-                  notcond, expr));
+  e = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+                  notcond, expr);
   if (nonzero_p (e))
     return e;
 
   /* Check whether COND ==> not EXPR.  */
-  e = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
-                  cond, expr));
+  e = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+                  cond, expr);
   if (zero_p (e))
     return e;
 
@@ -695,10 +765,10 @@ simplify_using_initial_conditions (struct loop *loop, tree expr,
       exp = tree_simplify_using_condition (cond, expr);
 
       if (exp != expr)
-       *conds_used = fold (build2 (TRUTH_AND_EXPR,
+       *conds_used = fold_build2 (TRUTH_AND_EXPR,
                                   boolean_type_node,
                                   *conds_used,
-                                  cond));
+                                  cond);
 
       expr = exp;
     }
@@ -706,6 +776,61 @@ simplify_using_initial_conditions (struct loop *loop, tree expr,
   return expr;
 }
 
+/* Tries to simplify EXPR using the evolutions of the loop invariants
+   in the superloops of LOOP.  Returns the simplified expression
+   (or EXPR unchanged, if no simplification was possible).  */
+
+static tree
+simplify_using_outer_evolutions (struct loop *loop, tree expr)
+{
+  enum tree_code code = TREE_CODE (expr);
+  bool changed;
+  tree e, e0, e1, e2;
+
+  if (is_gimple_min_invariant (expr))
+    return expr;
+
+  if (code == TRUTH_OR_EXPR
+      || code == TRUTH_AND_EXPR
+      || code == COND_EXPR)
+    {
+      changed = false;
+
+      e0 = simplify_using_outer_evolutions (loop, TREE_OPERAND (expr, 0));
+      if (TREE_OPERAND (expr, 0) != e0)
+       changed = true;
+
+      e1 = simplify_using_outer_evolutions (loop, TREE_OPERAND (expr, 1));
+      if (TREE_OPERAND (expr, 1) != e1)
+       changed = true;
+
+      if (code == COND_EXPR)
+       {
+         e2 = simplify_using_outer_evolutions (loop, TREE_OPERAND (expr, 2));
+         if (TREE_OPERAND (expr, 2) != e2)
+           changed = true;
+       }
+      else
+       e2 = NULL_TREE;
+
+      if (changed)
+       {
+         if (code == COND_EXPR)
+           expr = fold_build3 (code, boolean_type_node, e0, e1, e2);
+         else
+           expr = fold_build2 (code, boolean_type_node, e0, e1);
+       }
+
+      return expr;
+    }
+
+  e = instantiate_parameters (loop, expr);
+  if (is_gimple_min_invariant (e))
+    return e;
+
+  return expr;
+}
+
 /* Stores description of number of iterations of LOOP derived from
    EXIT (an exit edge of the LOOP) in NITER.  Returns true if some
    useful information could be derived (and fields of NITER has
@@ -762,16 +887,28 @@ number_of_iterations_exit (struct loop *loop, edge exit,
     return false;
 
   niter->niter = NULL_TREE;
-  number_of_iterations_cond (type, base0, step0, code, base1, step1,
-                            niter);
-  if (!niter->niter)
-    return false;
 
-  niter->assumptions = simplify_using_outer_evolutions (loop,
-                                                       niter->assumptions);
-  niter->may_be_zero = simplify_using_outer_evolutions (loop,
-                                                       niter->may_be_zero);
-  niter->niter = simplify_using_outer_evolutions (loop, niter->niter);
+  /* Handle common special cases first, so that we do not need to use
+     generic (and slow) analysis very often.  */
+  if (!number_of_iterations_special (type, base0, step0, code, base1, step1,
+                                    niter))
+    {
+
+      number_of_iterations_cond (type, base0, step0, code, base1, step1,
+                                niter);
+
+      if (!niter->niter)
+       return false;
+    }
+
+  if (optimize >= 3)
+    {
+      niter->assumptions = simplify_using_outer_evolutions (loop,
+                                                           niter->assumptions);
+      niter->may_be_zero = simplify_using_outer_evolutions (loop,
+                                                           niter->may_be_zero);
+      niter->niter = simplify_using_outer_evolutions (loop, niter->niter);
+    }
 
   niter->additional_info = boolean_true_node;
   niter->assumptions
@@ -1046,7 +1183,7 @@ loop_niter_by_eval (struct loop *loop, edge exit)
       for (j = 0; j < 2; j++)
        aval[j] = get_val_for (op[j], val[j]);
 
-      acnd = fold (build2 (cmp, boolean_type_node, aval[0], aval[1]));
+      acnd = fold_build2 (cmp, boolean_type_node, aval[0], aval[1]);
       if (zero_p (acnd))
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1203,11 +1340,11 @@ compare_trees (tree a, tree b)
   a = fold_convert (type, a);
   b = fold_convert (type, b);
 
-  if (nonzero_p (fold (build2 (EQ_EXPR, boolean_type_node, a, b))))
+  if (nonzero_p (fold_build2 (EQ_EXPR, boolean_type_node, a, b)))
     return 0;
-  if (nonzero_p (fold (build2 (LT_EXPR, boolean_type_node, a, b))))
+  if (nonzero_p (fold_build2 (LT_EXPR, boolean_type_node, a, b)))
     return 1;
-  if (nonzero_p (fold (build2 (GT_EXPR, boolean_type_node, a, b))))
+  if (nonzero_p (fold_build2 (GT_EXPR, boolean_type_node, a, b)))
     return -1;
 
   return 2;
@@ -1271,8 +1408,8 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
 
   b = fold_convert (type, base);
   bplusstep = fold_convert (type,
-                           fold (build2 (PLUS_EXPR, inner_type, base, step)));
-  new_step = fold (build2 (MINUS_EXPR, type, bplusstep, b));
+                           fold_build2 (PLUS_EXPR, inner_type, base, step));
+  new_step = fold_build2 (MINUS_EXPR, type, bplusstep, b);
   if (TREE_CODE (new_step) != INTEGER_CST)
     return NULL_TREE;
 
@@ -1280,14 +1417,14 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
     {
     case -1:
       extreme = upper_bound_in_type (type, inner_type);
-      delta = fold (build2 (MINUS_EXPR, type, extreme, b));
+      delta = fold_build2 (MINUS_EXPR, type, extreme, b);
       new_step_abs = new_step;
       break;
 
     case 1:
       extreme = lower_bound_in_type (type, inner_type);
-      new_step_abs = fold (build1 (NEGATE_EXPR, type, new_step));
-      delta = fold (build2 (MINUS_EXPR, type, b, extreme));
+      new_step_abs = fold_build1 (NEGATE_EXPR, type, new_step);
+      delta = fold_build2 (MINUS_EXPR, type, b, extreme);
       break;
 
     case 0:
@@ -1300,8 +1437,8 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
   unsigned_type = unsigned_type_for (type);
   delta = fold_convert (unsigned_type, delta);
   new_step_abs = fold_convert (unsigned_type, new_step_abs);
-  valid_niter = fold (build2 (FLOOR_DIV_EXPR, unsigned_type,
-                            delta, new_step_abs));
+  valid_niter = fold_build2 (FLOOR_DIV_EXPR, unsigned_type,
+                            delta, new_step_abs);
 
   bound_type = TREE_TYPE (bound);
   if (TYPE_PRECISION (type) > TYPE_PRECISION (bound_type))
@@ -1313,24 +1450,22 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
     {
       /* After the statement OF we know that anything is executed at most
         BOUND times.  */
-      cond = build2 (GE_EXPR, boolean_type_node, valid_niter, bound);
+      cond = fold_build2 (GE_EXPR, boolean_type_node, valid_niter, bound);
     }
   else
     {
       /* Before the statement OF we know that anything is executed at most
         BOUND + 1 times.  */
-      cond = build2 (GT_EXPR, boolean_type_node, valid_niter, bound);
+      cond = fold_build2 (GT_EXPR, boolean_type_node, valid_niter, bound);
     }
 
-  cond = fold (cond);
   if (nonzero_p (cond))
     return new_step;
 
   /* Try taking additional conditions into account.  */
-  cond = build2 (TRUTH_OR_EXPR, boolean_type_node,
-               invert_truthvalue (additional),
-               cond);
-  cond = fold (cond);
+  cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
+                     invert_truthvalue (additional),
+                     cond);
   if (nonzero_p (cond))
     return new_step;