OSDN Git Service

* tree-into-ssa.c: Re-organize internal functions.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-niter.c
index 2a66a6b..21bfce8 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions to determine/estimate number of iterations of a loop.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
    
 This file is part of GCC.
    
@@ -36,15 +36,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ggc.h"
 #include "tree-chrec.h"
 #include "tree-scalar-evolution.h"
+#include "tree-data-ref.h"
 #include "params.h"
 #include "flags.h"
 #include "tree-inline.h"
 
 #define SWAP(X, Y) do { void *tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
 
-/* Just to shorten the ugly names.  */
-#define EXEC_BINARY nondestructive_fold_binary_to_constant
-#define EXEC_UNARY nondestructive_fold_unary_to_constant
 
 /*
 
@@ -52,15 +50,34 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 */
 
-/* Returns true if ARG is either NULL_TREE or constant zero.  */
+/* Returns true if ARG is either NULL_TREE or constant zero.  Unlike
+   integer_zerop, it does not care about overflow flags.  */
 
-static bool
+bool
 zero_p (tree arg)
 {
   if (!arg)
     return true;
 
-  return integer_zerop (arg);
+  if (TREE_CODE (arg) != INTEGER_CST)
+    return false;
+
+  return (TREE_INT_CST_LOW (arg) == 0 && TREE_INT_CST_HIGH (arg) == 0);
+}
+
+/* Returns true if ARG a nonzero constant.  Unlike integer_nonzerop, it does
+   not care about overflow flags.  */
+
+static bool
+nonzero_p (tree arg)
+{
+  if (!arg)
+    return false;
+
+  if (TREE_CODE (arg) != INTEGER_CST)
+    return false;
+
+  return (TREE_INT_CST_LOW (arg) != 0 || TREE_INT_CST_HIGH (arg) != 0);
 }
 
 /* Returns inverse of X modulo 2^s, where MASK = 2^s-1.  */
@@ -69,35 +86,42 @@ static tree
 inverse (tree x, tree mask)
 {
   tree type = TREE_TYPE (x);
-  tree ctr = EXEC_BINARY (RSHIFT_EXPR, type, mask, integer_one_node);
-  tree rslt = convert (type, integer_one_node);
+  tree rslt;
+  unsigned ctr = tree_floor_log2 (mask);
 
-  while (integer_nonzerop (ctr))
+  if (TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT)
     {
-      rslt = EXEC_BINARY (MULT_EXPR, type, rslt, x);
-      rslt = EXEC_BINARY (BIT_AND_EXPR, type, rslt, mask);
-      x = EXEC_BINARY (MULT_EXPR, type, x, x);
-      x = EXEC_BINARY (BIT_AND_EXPR, type, x, mask);
-      ctr = EXEC_BINARY (RSHIFT_EXPR, type, ctr, integer_one_node);
-    }
+      unsigned HOST_WIDE_INT ix;
+      unsigned HOST_WIDE_INT imask;
+      unsigned HOST_WIDE_INT irslt = 1;
 
-  return rslt;
-}
+      gcc_assert (cst_and_fits_in_hwi (x));
+      gcc_assert (cst_and_fits_in_hwi (mask));
 
-/* Returns unsigned variant of TYPE.  */
+      ix = int_cst_value (x);
+      imask = int_cst_value (mask);
 
-static tree
-unsigned_type_for (tree type)
-{
-  return make_unsigned_type (TYPE_PRECISION (type));
-}
+      for (; ctr; ctr--)
+       {
+         irslt *= ix;
+         ix *= ix;
+       }
+      irslt &= imask;
 
-/* Returns signed variant of TYPE.  */
+      rslt = build_int_cst_type (type, irslt);
+    }
+  else
+    {
+      rslt = build_int_cst_type (type, 1);
+      for (; ctr; ctr--)
+       {
+         rslt = fold_binary_to_constant (MULT_EXPR, type, rslt, x);
+         x = fold_binary_to_constant (MULT_EXPR, type, x, x);
+       }
+      rslt = fold_binary_to_constant (BIT_AND_EXPR, type, rslt, mask);
+    }
 
-static tree
-signed_type_for (tree type)
-{
-  return make_signed_type (TYPE_PRECISION (type));
+  return rslt;
 }
 
 /* Determine the number of iterations according to condition (for staying
@@ -125,6 +149,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
   tree assumptions = boolean_true_node;
   tree noloop_assumptions = boolean_false_node;
   tree niter_type, signed_niter_type;
+  tree bits;
 
   /* The meaning of these assumptions is this:
      if !assumptions
@@ -151,7 +176,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
       if (code != NE_EXPR)
        return;
 
-      step0 = EXEC_BINARY (MINUS_EXPR, type, step0, step1);
+      step0 = fold_binary_to_constant (MINUS_EXPR, type, step0, step1);
       step1 = NULL_TREE;
     }
 
@@ -190,30 +215,30 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
       /* We want to take care only of <=; this is easy,
         as in cases the overflow would make the transformation unsafe the loop
         does not roll.  Seemingly it would make more sense to want to take
-        care of <, as NE is more simmilar to it, but the problem is that here
+        care of <, as NE is more similar to it, but the problem is that here
         the transformation would be more difficult due to possibly infinite
         loops.  */
       if (zero_p (step0))
        {
          if (mmax)
-           assumption = fold (build (EQ_EXPR, boolean_type_node, base0, mmax));
+           assumption = fold (build2 (EQ_EXPR, boolean_type_node, base0, mmax));
          else
            assumption = boolean_false_node;
-         if (integer_nonzerop (assumption))
+         if (nonzero_p (assumption))
            goto zero_iter;
-         base0 = fold (build (PLUS_EXPR, type, base0,
-                              convert (type, integer_one_node)));
+         base0 = fold (build2 (PLUS_EXPR, type, base0,
+                               build_int_cst_type (type, 1)));
        }
       else
        {
          if (mmin)
-           assumption = fold (build (EQ_EXPR, boolean_type_node, base1, mmin));
+           assumption = fold (build2 (EQ_EXPR, boolean_type_node, base1, mmin));
          else
            assumption = boolean_false_node;
-         if (integer_nonzerop (assumption))
+         if (nonzero_p (assumption))
            goto zero_iter;
-         base1 = fold (build (MINUS_EXPR, type, base1,
-                              convert (type, integer_one_node)));
+         base1 = fold (build2 (MINUS_EXPR, type, base1,
+                               build_int_cst_type (type, 1)));
        }
       noloop_assumptions = assumption;
       code = LE_EXPR;
@@ -245,17 +270,17 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
   if (code != NE_EXPR)
     {
       if (zero_p (step0))
-       step = EXEC_UNARY (NEGATE_EXPR, type, step1);
+       step = fold_unary_to_constant (NEGATE_EXPR, type, step1);
       else
        step = step0;
-      delta = build (MINUS_EXPR, type, base1, base0);
-      delta = fold (build (FLOOR_MOD_EXPR, type, delta, step));
+      delta = build2 (MINUS_EXPR, type, base1, base0);
+      delta = fold (build2 (FLOOR_MOD_EXPR, type, delta, step));
       may_xform = boolean_false_node;
 
       if (TREE_CODE (delta) == INTEGER_CST)
        {
-         tmp = EXEC_BINARY (MINUS_EXPR, type, step,
-                            convert (type, integer_one_node));
+         tmp = fold_binary_to_constant (MINUS_EXPR, type, step,
+                                        build_int_cst_type (type, 1));
          if (was_sharp
              && operand_equal_p (delta, tmp, 0))
            {
@@ -266,7 +291,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
                 obviously if the test for overflow during that transformation
                 passed, we cannot overflow here.  Most importantly any
                 loop with sharp end condition and step 1 falls into this
-                cathegory, so handling this case specially is definitely
+                category, so handling this case specially is definitely
                 worth the troubles.  */
              may_xform = boolean_true_node;
            }
@@ -276,9 +301,11 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
                may_xform = boolean_true_node;
              else
                {
-                 bound = EXEC_BINARY (PLUS_EXPR, type, mmin, step);
-                 bound = EXEC_BINARY (MINUS_EXPR, type, bound, delta);
-                 may_xform = fold (build (LE_EXPR, boolean_type_node,
+                 bound = fold_binary_to_constant (PLUS_EXPR, type,
+                                                  mmin, step);
+                 bound = fold_binary_to_constant (MINUS_EXPR, type,
+                                                  bound, delta);
+                 may_xform = fold (build2 (LE_EXPR, boolean_type_node,
                                           bound, base0));
                }
            }
@@ -288,35 +315,37 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
                may_xform = boolean_true_node;
              else
                {
-                 bound = EXEC_BINARY (MINUS_EXPR, type, mmax, step);
-                 bound = EXEC_BINARY (PLUS_EXPR, type, bound, delta);
-                 may_xform = fold (build (LE_EXPR, boolean_type_node,
+                 bound = fold_binary_to_constant (MINUS_EXPR, type,
+                                                  mmax, step);
+                 bound = fold_binary_to_constant (PLUS_EXPR, type,
+                                                  bound, delta);
+                 may_xform = fold (build2 (LE_EXPR, boolean_type_node,
                                           base1, bound));
                }
            }
        }
 
-      if (!integer_zerop (may_xform))
+      if (!zero_p (may_xform))
        {
          /* We perform the transformation always provided that it is not
             completely senseless.  This is OK, as we would need this assumption
             to determine the number of iterations anyway.  */
-         if (!integer_nonzerop (may_xform))
+         if (!nonzero_p (may_xform))
            assumptions = may_xform;
 
          if (zero_p (step0))
            {
-             base0 = build (PLUS_EXPR, type, base0, delta);
-             base0 = fold (build (MINUS_EXPR, type, base0, step));
+             base0 = fold (build2 (PLUS_EXPR, type, base0, delta));
+             base0 = fold (build2 (MINUS_EXPR, type, base0, step));
            }
          else
            {
-             base1 = build (MINUS_EXPR, type, base1, delta);
-             base1 = fold (build (PLUS_EXPR, type, base1, step));
+             base1 = fold (build2 (MINUS_EXPR, type, base1, delta));
+             base1 = fold (build2 (PLUS_EXPR, type, base1, step));
            }
 
-         assumption = fold (build (GT_EXPR, boolean_type_node, base0, base1));
-         noloop_assumptions = fold (build (TRUTH_OR_EXPR, boolean_type_node,
+         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;
        }
@@ -332,40 +361,31 @@ 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 (build (MINUS_EXPR, type, base1, base0));
+      base1 = fold (build2 (MINUS_EXPR, type, base1, base0));
       base0 = NULL_TREE;
       if (!zero_p (step1))
-       step0 = EXEC_UNARY (NEGATE_EXPR, type, step1);
+       step0 = fold_unary_to_constant (NEGATE_EXPR, type, step1);
       step1 = NULL_TREE;
-      if (!tree_expr_nonnegative_p (convert (signed_niter_type, step0)))
+      if (!tree_expr_nonnegative_p (fold_convert (signed_niter_type, step0)))
        {
-         step0 = EXEC_UNARY (NEGATE_EXPR, type, step0);
+         step0 = fold_unary_to_constant (NEGATE_EXPR, type, step0);
          base1 = fold (build1 (NEGATE_EXPR, type, base1));
        }
 
-      base1 = convert (niter_type, base1);
-      step0 = convert (niter_type, step0);
+      base1 = fold_convert (niter_type, base1);
+      step0 = fold_convert (niter_type, step0);
 
-      /* Let nsd (s, size of mode) = d.  If d does not divide c, the loop
+      /* Let nsd (step, size of mode) = d.  If d does not divide c, the loop
         is infinite.  Otherwise, the number of iterations is
         (inverse(s/d) * (c/d)) mod (size of mode/d).  */
-      s = step0;
-      d = integer_one_node;
-      bound = convert (niter_type, build_int_cst (NULL_TREE, -1));
-      while (1)
-       {
-         tmp = EXEC_BINARY (BIT_AND_EXPR, niter_type, s,
-                            convert (niter_type, integer_one_node));
-         if (integer_nonzerop (tmp))
-           break;
-         
-         s = EXEC_BINARY (RSHIFT_EXPR, niter_type, s,
-                          convert (niter_type, integer_one_node));
-         d = EXEC_BINARY (LSHIFT_EXPR, niter_type, d,
-                          convert (niter_type, integer_one_node));
-         bound = EXEC_BINARY (RSHIFT_EXPR, niter_type, bound,
-                              convert (niter_type, integer_one_node));
-       }
+      bits = num_ending_zeros (step0);
+      d = fold_binary_to_constant (LSHIFT_EXPR, niter_type,
+                                  build_int_cst_type (niter_type, 1), bits);
+      s = fold_binary_to_constant (RSHIFT_EXPR, niter_type, step0, bits);
+
+      bound = build_low_bits_mask (niter_type,
+                                  (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,
@@ -374,9 +394,9 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
       assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
                                  assumptions, assumption));
 
-      tmp = fold (build (EXACT_DIV_EXPR, niter_type, base1, d));
-      tmp = fold (build (MULT_EXPR, niter_type, tmp, inverse (s, bound)));
-      niter->niter = fold (build (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
     {
@@ -390,19 +410,19 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
        {
          if (mmax)
            {
-             bound = EXEC_BINARY (MINUS_EXPR, type, mmax, step0);
-             assumption = fold (build (LE_EXPR, boolean_type_node,
-                                       base1, bound));
-             assumptions = fold (build (TRUTH_AND_EXPR, boolean_type_node,
-                                        assumptions, assumption));
+             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));
            }
 
          step = step0;
-         tmp = fold (build (PLUS_EXPR, type, base1, step0));
-         assumption = fold (build (GT_EXPR, boolean_type_node, base0, tmp));
-         delta = fold (build (PLUS_EXPR, type, base1, step));
-         delta = fold (build (MINUS_EXPR, type, delta, base0));
-         delta = convert (niter_type, delta);
+         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
        {
@@ -411,23 +431,23 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
             we can again compute number of iterations as (b - (a - s)) / s.  */
          if (mmin)
            {
-             bound = EXEC_BINARY (MINUS_EXPR, type, mmin, step1);
-             assumption = fold (build (LE_EXPR, boolean_type_node,
+             bound = fold_binary_to_constant (MINUS_EXPR, type, mmin, step1);
+             assumption = fold (build2 (LE_EXPR, boolean_type_node,
                                        bound, base0));
-             assumptions = fold (build (TRUTH_AND_EXPR, boolean_type_node,
+             assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
                                         assumptions, assumption));
            }
          step = fold (build1 (NEGATE_EXPR, type, step1));
-         tmp = fold (build (PLUS_EXPR, type, base0, step1));
-         assumption = fold (build (GT_EXPR, boolean_type_node, tmp, base1));
-         delta = fold (build (MINUS_EXPR, type, base0, step));
-         delta = fold (build (MINUS_EXPR, type, base1, delta));
-         delta = convert (niter_type, delta);
+         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 (build (TRUTH_OR_EXPR, boolean_type_node,
+      noloop_assumptions = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
                                        noloop_assumptions, assumption));
-      delta = fold (build (FLOOR_DIV_EXPR, niter_type, delta,
-                          convert (niter_type, step)));
+      delta = fold (build2 (FLOOR_DIV_EXPR, niter_type, delta,
+                           fold_convert (niter_type, step)));
       niter->niter = delta;
     }
 
@@ -438,7 +458,7 @@ number_of_iterations_cond (tree type, tree base0, tree step0,
 zero_iter:
   niter->assumptions = boolean_true_node;
   niter->may_be_zero = boolean_true_node;
-  niter->niter = convert (type, integer_zero_node);
+  niter->niter = build_int_cst_type (type, 0);
   return;
 }
 
@@ -482,9 +502,9 @@ simplify_using_outer_evolutions (struct loop *loop, tree expr)
       if (changed)
        {
          if (code == COND_EXPR)
-           expr = build (code, boolean_type_node, e0, e1, e2);
+           expr = build3 (code, boolean_type_node, e0, e1, e2);
          else
-           expr = build (code, boolean_type_node, e0, e1);
+           expr = build2 (code, boolean_type_node, e0, e1);
          expr = fold (expr);
        }
 
@@ -498,6 +518,41 @@ simplify_using_outer_evolutions (struct loop *loop, tree expr)
   return expr;
 }
 
+/* Substitute NEW for OLD in EXPR and fold the result.  */
+
+static tree
+simplify_replace_tree (tree expr, tree old, tree new)
+{
+  unsigned i, n;
+  tree ret = NULL_TREE, e, se;
+
+  if (!expr)
+    return NULL_TREE;
+
+  if (expr == old
+      || operand_equal_p (expr, old, 0))
+    return unshare_expr (new);
+
+  if (!EXPR_P (expr))
+    return expr;
+
+  n = TREE_CODE_LENGTH (TREE_CODE (expr));
+  for (i = 0; i < n; i++)
+    {
+      e = TREE_OPERAND (expr, i);
+      se = simplify_replace_tree (e, old, new);
+      if (e == se)
+       continue;
+
+      if (!ret)
+       ret = copy_node (expr);
+
+      TREE_OPERAND (ret, i) = se;
+    }
+
+  return (ret ? fold (ret) : expr);
+}
+
 /* Tries to simplify EXPR using the condition COND.  Returns the simplified
    expression (or EXPR unchanged, if no simplification was possible).*/
 
@@ -537,26 +592,71 @@ tree_simplify_using_condition (tree cond, tree expr)
       if (changed)
        {
          if (code == COND_EXPR)
-           expr = build (code, boolean_type_node, e0, e1, e2);
+           expr = build3 (code, boolean_type_node, e0, e1, e2);
          else
-           expr = build (code, boolean_type_node, e0, e1);
+           expr = build2 (code, boolean_type_node, e0, e1);
          expr = fold (expr);
        }
 
       return expr;
     }
 
+  /* In case COND is equality, we may be able to simplify EXPR by copy/constant
+     propagation, and vice versa.  Fold does not handle this, since it is
+     considered too expensive.  */
+  if (TREE_CODE (cond) == EQ_EXPR)
+    {
+      e0 = TREE_OPERAND (cond, 0);
+      e1 = TREE_OPERAND (cond, 1);
+
+      /* We know that e0 == e1.  Check whether we cannot simplify expr
+        using this fact.  */
+      e = simplify_replace_tree (expr, e0, e1);
+      if (zero_p (e) || nonzero_p (e))
+       return e;
+
+      e = simplify_replace_tree (expr, e1, e0);
+      if (zero_p (e) || nonzero_p (e))
+       return e;
+    }
+  if (TREE_CODE (expr) == EQ_EXPR)
+    {
+      e0 = TREE_OPERAND (expr, 0);
+      e1 = TREE_OPERAND (expr, 1);
+
+      /* If e0 == e1 (EXPR) implies !COND, then EXPR cannot be true.  */
+      e = simplify_replace_tree (cond, e0, e1);
+      if (zero_p (e))
+       return e;
+      e = simplify_replace_tree (cond, e1, e0);
+      if (zero_p (e))
+       return e;
+    }
+  if (TREE_CODE (expr) == NE_EXPR)
+    {
+      e0 = TREE_OPERAND (expr, 0);
+      e1 = TREE_OPERAND (expr, 1);
+
+      /* If e0 == e1 (!EXPR) implies !COND, then EXPR must be true.  */
+      e = simplify_replace_tree (cond, e0, e1);
+      if (zero_p (e))
+       return boolean_true_node;
+      e = simplify_replace_tree (cond, e1, e0);
+      if (zero_p (e))
+       return boolean_true_node;
+    }
+
   /* Check whether COND ==> EXPR.  */
   notcond = invert_truthvalue (cond);
-  e = fold (build (TRUTH_OR_EXPR, boolean_type_node,
+  e = fold (build2 (TRUTH_OR_EXPR, boolean_type_node,
                   notcond, expr));
-  if (integer_nonzerop (e))
+  if (nonzero_p (e))
     return e;
 
   /* Check whether COND ==> not EXPR.  */
-  e = fold (build (TRUTH_AND_EXPR, boolean_type_node,
+  e = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
                   cond, expr));
-  if (integer_zerop (e))
+  if (zero_p (e))
     return e;
 
   return expr;
@@ -582,8 +682,8 @@ simplify_using_initial_conditions (struct loop *loop, tree expr,
        bb != ENTRY_BLOCK_PTR;
        bb = get_immediate_dominator (CDI_DOMINATORS, bb))
     {
-      e = bb->pred;
-      if (e->pred_next)
+      e = EDGE_PRED (bb, 0);
+      if (EDGE_COUNT (bb->preds) > 1)
        continue;
 
       if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
@@ -595,7 +695,7 @@ simplify_using_initial_conditions (struct loop *loop, tree expr,
       exp = tree_simplify_using_condition (cond, expr);
 
       if (exp != expr)
-       *conds_used = fold (build (TRUTH_AND_EXPR,
+       *conds_used = fold (build2 (TRUTH_AND_EXPR,
                                   boolean_type_node,
                                   *conds_used,
                                   cond));
@@ -685,6 +785,75 @@ number_of_iterations_exit (struct loop *loop, edge exit,
   return integer_onep (niter->assumptions);
 }
 
+/* Try to determine the number of iterations of LOOP.  If we succeed,
+   expression giving number of iterations is returned and *EXIT is
+   set to the edge from that the information is obtained.  Otherwise
+   chrec_dont_know is returned.  */
+
+tree
+find_loop_niter (struct loop *loop, edge *exit)
+{
+  unsigned n_exits, i;
+  edge *exits = get_loop_exit_edges (loop, &n_exits);
+  edge ex;
+  tree niter = NULL_TREE, aniter;
+  struct tree_niter_desc desc;
+
+  *exit = NULL;
+  for (i = 0; i < n_exits; i++)
+    {
+      ex = exits[i];
+      if (!just_once_each_iteration_p (loop, ex->src))
+       continue;
+
+      if (!number_of_iterations_exit (loop, ex, &desc))
+       continue;
+
+      if (nonzero_p (desc.may_be_zero))
+       {
+         /* We exit in the first iteration through this exit.
+            We won't find anything better.  */
+         niter = build_int_cst_type (unsigned_type_node, 0);
+         *exit = ex;
+         break;
+       }
+
+      if (!zero_p (desc.may_be_zero))
+       continue;
+
+      aniter = desc.niter;
+
+      if (!niter)
+       {
+         /* Nothing recorded yet.  */
+         niter = aniter;
+         *exit = ex;
+         continue;
+       }
+
+      /* Prefer constants, the lower the better.  */
+      if (TREE_CODE (aniter) != INTEGER_CST)
+       continue;
+
+      if (TREE_CODE (niter) != INTEGER_CST)
+       {
+         niter = aniter;
+         *exit = ex;
+         continue;
+       }
+
+      if (tree_int_cst_lt (aniter, niter))
+       {
+         niter = aniter;
+         *exit = ex;
+         continue;
+       }
+    }
+  free (exits);
+
+  return niter ? niter : chrec_dont_know;
+}
+
 /*
 
    Analysis of a number of iterations of a loop by a brute-force evaluation.
@@ -877,8 +1046,8 @@ 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 (build (cmp, boolean_type_node, aval[0], aval[1]));
-      if (integer_zerop (acnd))
+      acnd = fold (build2 (cmp, boolean_type_node, aval[0], aval[1]));
+      if (zero_p (acnd))
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
            fprintf (dump_file,
@@ -917,13 +1086,11 @@ find_loop_niter_by_eval (struct loop *loop, edge *exit)
        continue;
 
       aniter = loop_niter_by_eval (loop, ex);
-      if (chrec_contains_undetermined (aniter)
-         || TREE_CODE (aniter) != INTEGER_CST)
+      if (chrec_contains_undetermined (aniter))
        continue;
 
       if (niter
-         && !integer_nonzerop (fold (build (LT_EXPR, boolean_type_node,
-                                            aniter, niter))))
+         && !tree_int_cst_lt (aniter, niter))
        continue;
 
       niter = aniter;
@@ -940,24 +1107,10 @@ find_loop_niter_by_eval (struct loop *loop, edge *exit)
 
 */
 
-/* The structure describing a bound on number of iterations of a loop.  */
-
-struct nb_iter_bound
-{
-  tree bound;          /* The expression whose value is an upper bound on the
-                          number of executions of anything after ...  */
-  tree at_stmt;                /* ... this statement during one execution of loop.  */
-  tree additional;     /* A conjunction of conditions the operands of BOUND
-                          satisfy.  The additional information about the value
-                          of the bound may be derived from it.  */
-  struct nb_iter_bound *next;
-                       /* The next bound in a list.  */
-};
-
 /* Records that AT_STMT is executed at most BOUND times in LOOP.  The
    additional condition ADDITIONAL is recorded with the bound.  */
 
-static void
+void
 record_estimate (struct loop *loop, tree bound, tree additional, tree at_stmt)
 {
   struct nb_iter_bound *elt = xmalloc (sizeof (struct nb_iter_bound));
@@ -996,19 +1149,25 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
 
       niter = niter_desc.niter;
       type = TREE_TYPE (niter);
-      if (!integer_zerop (niter_desc.may_be_zero)
-         && !integer_nonzerop (niter_desc.may_be_zero))
-       niter = build (COND_EXPR, type, niter_desc.may_be_zero,
-                      convert (type, integer_zero_node),
-                      niter);
+      if (!zero_p (niter_desc.may_be_zero)
+         && !nonzero_p (niter_desc.may_be_zero))
+       niter = build3 (COND_EXPR, type, niter_desc.may_be_zero,
+                       build_int_cst_type (type, 0),
+                       niter);
       record_estimate (loop, niter,
                       niter_desc.additional_info,
                       last_stmt (exits[i]->src));
     }
   free (exits);
   
-  /* TODO Here we could use other possibilities, like bounds of arrays accessed
-     in the loop.  */
+  /* Analyzes the bounds of arrays accessed in the loop.  */
+  if (loop->estimated_nb_iterations == NULL_TREE)
+    {
+      varray_type datarefs;
+      VARRAY_GENERIC_PTR_INIT (datarefs, 3, "datarefs");
+      find_data_references_in_loop (loop, &datarefs);
+      free_data_refs (datarefs);
+    }
 }
 
 /* Records estimates on numbers of iterations of LOOPS.  */
@@ -1041,93 +1200,19 @@ compare_trees (tree a, tree b)
   else
     type = typeb;
 
-  a = convert (type, a);
-  b = convert (type, b);
+  a = fold_convert (type, a);
+  b = fold_convert (type, b);
 
-  if (integer_nonzerop (fold (build (EQ_EXPR, boolean_type_node, a, b))))
+  if (nonzero_p (fold (build2 (EQ_EXPR, boolean_type_node, a, b))))
     return 0;
-  if (integer_nonzerop (fold (build (LT_EXPR, boolean_type_node, a, b))))
+  if (nonzero_p (fold (build2 (LT_EXPR, boolean_type_node, a, b))))
     return 1;
-  if (integer_nonzerop (fold (build (GT_EXPR, boolean_type_node, a, b))))
+  if (nonzero_p (fold (build2 (GT_EXPR, boolean_type_node, a, b))))
     return -1;
 
   return 2;
 }
 
-/* Returns the largest value obtainable by casting something in INNER type to
-   OUTER type.  */
-
-tree
-upper_bound_in_type (tree outer, tree inner)
-{
-  unsigned HOST_WIDE_INT lo, hi;
-  unsigned bits = TYPE_PRECISION (inner);
-
-  if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner))
-    {
-      /* Zero extending in these cases.  */
-      if (bits <= HOST_BITS_PER_WIDE_INT)
-       {
-         hi = 0;
-         lo = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (HOST_BITS_PER_WIDE_INT - bits);
-       }
-      else
-       {
-         hi = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (2 * HOST_BITS_PER_WIDE_INT - bits);
-         lo = ~(unsigned HOST_WIDE_INT) 0;
-       }
-    }
-  else
-    {
-      /* Sign extending in these cases.  */
-      if (bits <= HOST_BITS_PER_WIDE_INT)
-       {
-         hi = 0;
-         lo = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (HOST_BITS_PER_WIDE_INT - bits) >> 1;
-       }
-      else
-       {
-         hi = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (2 * HOST_BITS_PER_WIDE_INT - bits) >> 1;
-         lo = ~(unsigned HOST_WIDE_INT) 0;
-       }
-    }
-
-  return convert (outer,
-                 convert (inner,
-                          build_int_cst_wide (NULL_TREE, lo, hi)));
-}
-
-/* Returns the smallest value obtainable by casting something in INNER type to
-   OUTER type.  */
-
-tree
-lower_bound_in_type (tree outer, tree inner)
-{
-  unsigned HOST_WIDE_INT lo, hi;
-  unsigned bits = TYPE_PRECISION (inner);
-
-  if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner))
-    lo = hi = 0;
-  else if (bits <= HOST_BITS_PER_WIDE_INT)
-    {
-      hi = ~(unsigned HOST_WIDE_INT) 0;
-      lo = (~(unsigned HOST_WIDE_INT) 0) << (bits - 1);
-    }
-  else
-    {
-      hi = (~(unsigned HOST_WIDE_INT) 0) << (bits - HOST_BITS_PER_WIDE_INT - 1);
-      lo = 0;
-    }
-
-  return convert (outer,
-                 convert (inner,
-                          build_int_cst_wide (NULL_TREE, lo, hi)));
-}
-
 /* Returns true if statement S1 dominates statement S2.  */
 
 static bool
@@ -1184,10 +1269,10 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
   tree valid_niter, extreme, unsigned_type, delta, bound_type;
   tree cond;
 
-  b = convert (type, base);
-  bplusstep = convert (type,
-                      fold (build (PLUS_EXPR, inner_type, base, step)));
-  new_step = fold (build (MINUS_EXPR, type, bplusstep, b));
+  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));
   if (TREE_CODE (new_step) != INTEGER_CST)
     return NULL_TREE;
 
@@ -1195,14 +1280,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 (build (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 (build (NEGATE_EXPR, type, new_step));
-      delta = fold (build (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:
@@ -1213,40 +1298,40 @@ can_count_iv_in_wider_type_bound (tree type, tree base, tree step,
     }
 
   unsigned_type = unsigned_type_for (type);
-  delta = convert (unsigned_type, delta);
-  new_step_abs = convert (unsigned_type, new_step_abs);
-  valid_niter = fold (build (FLOOR_DIV_EXPR, unsigned_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));
 
   bound_type = TREE_TYPE (bound);
   if (TYPE_PRECISION (type) > TYPE_PRECISION (bound_type))
-    bound = convert (unsigned_type, bound);
+    bound = fold_convert (unsigned_type, bound);
   else
-    valid_niter = convert (bound_type, valid_niter);
+    valid_niter = fold_convert (bound_type, valid_niter);
     
   if (at_stmt && stmt_dominates_stmt_p (of, at_stmt))
     {
       /* After the statement OF we know that anything is executed at most
         BOUND times.  */
-      cond = build (GE_EXPR, boolean_type_node, valid_niter, bound);
+      cond = 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 = build (GT_EXPR, boolean_type_node, valid_niter, bound);
+      cond = build2 (GT_EXPR, boolean_type_node, valid_niter, bound);
     }
 
   cond = fold (cond);
-  if (integer_nonzerop (cond))
+  if (nonzero_p (cond))
     return new_step;
 
   /* Try taking additional conditions into account.  */
-  cond = build (TRUTH_OR_EXPR, boolean_type_node,
+  cond = build2 (TRUTH_OR_EXPR, boolean_type_node,
                invert_truthvalue (additional),
                cond);
   cond = fold (cond);
-  if (integer_nonzerop (cond))
+  if (nonzero_p (cond))
     return new_step;
 
   return NULL_TREE;