OSDN Git Service

2009-04-08 Thomas Quinot <quinot@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-niter.c
index 83baae7..6547382 100644 (file)
@@ -697,10 +697,12 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
       /* The final value of the iv is iv1->base + MOD, assuming that this
         computation does not overflow, and that
         iv0->base <= iv1->base + MOD.  */
-      if (!iv1->no_overflow && !integer_zerop (mod))
+      if (!iv0->no_overflow && !integer_zerop (mod))
        {
-         bound = fold_build2 (MINUS_EXPR, type,
+         bound = fold_build2 (MINUS_EXPR, type1,
                               TYPE_MAX_VALUE (type1), tmod);
+         if (POINTER_TYPE_P (type))
+           bound = fold_convert (type, bound);
          assumption = fold_build2 (LE_EXPR, boolean_type_node,
                                    iv1->base, bound);
          if (integer_zerop (assumption))
@@ -708,6 +710,11 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
        }
       if (mpz_cmp (mmod, bnds->below) < 0)
        noloop = boolean_false_node;
+      else if (POINTER_TYPE_P (type))
+       noloop = fold_build2 (GT_EXPR, boolean_type_node,
+                             iv0->base,
+                             fold_build2 (POINTER_PLUS_EXPR, type,
+                                          iv1->base, tmod));
       else
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
                              iv0->base,
@@ -719,10 +726,12 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
       /* The final value of the iv is iv0->base - MOD, assuming that this
         computation does not overflow, and that
         iv0->base - MOD <= iv1->base. */
-      if (!iv0->no_overflow && !integer_zerop (mod))
+      if (!iv1->no_overflow && !integer_zerop (mod))
        {
          bound = fold_build2 (PLUS_EXPR, type1,
                               TYPE_MIN_VALUE (type1), tmod);
+         if (POINTER_TYPE_P (type))
+           bound = fold_convert (type, bound);
          assumption = fold_build2 (GE_EXPR, boolean_type_node,
                                    iv0->base, bound);
          if (integer_zerop (assumption))
@@ -730,6 +739,13 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
        }
       if (mpz_cmp (mmod, bnds->below) < 0)
        noloop = boolean_false_node;
+      else if (POINTER_TYPE_P (type))
+       noloop = fold_build2 (GT_EXPR, boolean_type_node,
+                             fold_build2 (POINTER_PLUS_EXPR, type,
+                                          iv0->base,
+                                          fold_build1 (NEGATE_EXPR,
+                                                       type1, tmod)),
+                             iv1->base);
       else
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
                              fold_build2 (MINUS_EXPR, type1,
@@ -1084,10 +1100,10 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
     {
       if (integer_nonzerop (iv0->step))
        assumption = fold_build2 (NE_EXPR, boolean_type_node,
-                                 iv1->base, TYPE_MAX_VALUE (type1));
+                                 iv1->base, TYPE_MAX_VALUE (type));
       else
        assumption = fold_build2 (NE_EXPR, boolean_type_node,
-                                 iv0->base, TYPE_MIN_VALUE (type1));
+                                 iv0->base, TYPE_MIN_VALUE (type));
 
       if (integer_zerop (assumption))
        return false;
@@ -1097,8 +1113,18 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
     }
 
   if (integer_nonzerop (iv0->step))
-    iv1->base = fold_build2 (PLUS_EXPR, type1,
-                            iv1->base, build_int_cst (type1, 1));
+    {
+      if (POINTER_TYPE_P (type))
+       iv1->base = fold_build2 (POINTER_PLUS_EXPR, type, iv1->base,
+                                build_int_cst (type1, 1));
+      else
+       iv1->base = fold_build2 (PLUS_EXPR, type1, iv1->base,
+                                build_int_cst (type1, 1));
+    }
+  else if (POINTER_TYPE_P (type))
+    iv0->base = fold_build2 (POINTER_PLUS_EXPR, type, iv0->base,
+                            fold_build1 (NEGATE_EXPR, type1,
+                                         build_int_cst (type1, 1)));
   else
     iv0->base = fold_build2 (MINUS_EXPR, type1,
                             iv0->base, build_int_cst (type1, 1));
@@ -1451,8 +1477,7 @@ expand_simple_operations (tree expr)
 
   switch (code)
     {
-    case NOP_EXPR:
-    case CONVERT_EXPR:
+    CASE_CONVERT:
       /* Casts are simple.  */
       ee = expand_simple_operations (e);
       return fold_build1 (code, TREE_TYPE (expr), ee);
@@ -1782,9 +1807,9 @@ number_of_iterations_exit (struct loop *loop, edge exit,
       && !POINTER_TYPE_P (type))
     return false;
      
-  if (!simple_iv (loop, stmt, op0, &iv0, false))
+  if (!simple_iv (loop, loop_containing_stmt (stmt), op0, &iv0, false))
     return false;
-  if (!simple_iv (loop, stmt, op1, &iv1, false))
+  if (!simple_iv (loop, loop_containing_stmt (stmt), op1, &iv1, false))
     return false;
 
   /* We don't want to see undefined signed overflow warnings while
@@ -1968,17 +1993,13 @@ chain_of_csts_start (struct loop *loop, tree x)
 
   code = gimple_assign_rhs_code (stmt);
   if (gimple_references_memory_p (stmt)
-      /* Before alias information is computed, operand scanning marks
-        statements that write memory volatile.  However, the statements
-        that only read memory are not marked, thus gimple_references_memory_p
-        returns false for them.  */
       || TREE_CODE_CLASS (code) == tcc_reference
-      || TREE_CODE_CLASS (code) == tcc_declaration
-      || SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
+      || (code == ADDR_EXPR
+         && !is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
     return NULL;
 
   use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
-  if (use == NULL_USE_OPERAND_P)
+  if (use == NULL_TREE)
     return NULL;
 
   return chain_of_csts_start (loop, use);
@@ -2034,7 +2055,6 @@ static tree
 get_val_for (tree x, tree base)
 {
   gimple stmt;
-  tree nx, val, retval, rhs1, rhs2;
 
   gcc_assert (is_gimple_min_invariant (base));
 
@@ -2050,33 +2070,30 @@ get_val_for (tree x, tree base)
   /* STMT must be either an assignment of a single SSA name or an
      expression involving an SSA name and a constant.  Try to fold that
      expression using the value for the SSA name.  */
-  rhs1 = gimple_assign_rhs1 (stmt);
-  rhs2 = gimple_assign_rhs2 (stmt);
-  if (TREE_CODE (rhs1) == SSA_NAME)
-    nx = rhs1;
-  else if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
-    nx = rhs2;
-  else
-    gcc_unreachable ();
-
-  /* NX is now the SSA name for which we want to discover the base value.  */
-  val = get_val_for (nx, base);
-  if (rhs2)
-    {
-      /* If this is a binary expression, fold it.  If folding is
-        not possible, return a tree expression with the RHS of STMT.  */
-      rhs1 = (nx == rhs1) ? val : rhs1;
-      rhs2 = (nx == rhs2) ? val : rhs2;
-      retval = fold_binary (gimple_assign_rhs_code (stmt),
-                           gimple_expr_type (stmt), rhs1, rhs2);
-      if (retval == NULL_TREE)
-       retval= build2 (gimple_assign_rhs_code (stmt),
-                       gimple_expr_type (stmt), rhs1, rhs2);
+  if (gimple_assign_ssa_name_copy_p (stmt))
+    return get_val_for (gimple_assign_rhs1 (stmt), base);
+  else if (gimple_assign_rhs_class (stmt) == GIMPLE_UNARY_RHS
+          && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+    {
+      return fold_build1 (gimple_assign_rhs_code (stmt),
+                         gimple_expr_type (stmt),
+                         get_val_for (gimple_assign_rhs1 (stmt), base));
+    }
+  else if (gimple_assign_rhs_class (stmt) == GIMPLE_BINARY_RHS)
+    {
+      tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree rhs2 = gimple_assign_rhs2 (stmt);
+      if (TREE_CODE (rhs1) == SSA_NAME)
+       rhs1 = get_val_for (rhs1, base);
+      else if (TREE_CODE (rhs2) == SSA_NAME)
+       rhs2 = get_val_for (rhs2, base);
+      else
+       gcc_unreachable ();
+      return fold_build2 (gimple_assign_rhs_code (stmt),
+                         gimple_expr_type (stmt), rhs1, rhs2);
     }
   else
-    retval = val;
-      
-  return retval;
+    gcc_unreachable ();
 }
 
 
@@ -2918,6 +2935,12 @@ stmt_dominates_stmt_p (gimple s1, gimple s2)
     {
       gimple_stmt_iterator bsi;
 
+      if (gimple_code (s2) == GIMPLE_PHI)
+       return false;
+
+      if (gimple_code (s1) == GIMPLE_PHI)
+       return true;
+
       for (bsi = gsi_start_bb (bb1); gsi_stmt (bsi) != s2; gsi_next (&bsi))
        if (gsi_stmt (bsi) == s1)
          return true;
@@ -3052,7 +3075,7 @@ scev_probably_wraps_p (tree base, tree step,
 
   /* If we can use the fact that signed and pointer arithmetics does not
      wrap, we are done.  */
-  if (use_overflow_semantics && nowrap_type_p (type))
+  if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
     return false;
 
   /* To be able to use estimates on number of iterations of the loop,