OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-niter.c
index 35d446c..b3bde28 100644 (file)
@@ -624,14 +624,70 @@ simplify_replace_tree (tree expr, tree old, tree new)
   return (ret ? fold (ret) : expr);
 }
 
+/* Expand definitions of ssa names in EXPR as long as they are simple
+   enough, and return the new expression.  */
+
+static tree
+expand_simple_operations (tree expr)
+{
+  unsigned i, n;
+  tree ret = NULL_TREE, e, ee, stmt;
+  enum tree_code code = TREE_CODE (expr);
+
+  if (is_gimple_min_invariant (expr))
+    return expr;
+
+  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+    {
+      n = TREE_CODE_LENGTH (code);
+      for (i = 0; i < n; i++)
+       {
+         e = TREE_OPERAND (expr, i);
+         ee = expand_simple_operations (e);
+         if (e == ee)
+           continue;
+
+         if (!ret)
+           ret = copy_node (expr);
+
+         TREE_OPERAND (ret, i) = ee;
+       }
+
+      return (ret ? fold (ret) : expr);
+    }
+
+  if (TREE_CODE (expr) != SSA_NAME)
+    return expr;
+
+  stmt = SSA_NAME_DEF_STMT (expr);
+  if (TREE_CODE (stmt) != MODIFY_EXPR)
+    return expr;
+
+  e = TREE_OPERAND (stmt, 1);
+  if (/* Casts are simple.  */
+      TREE_CODE (e) != NOP_EXPR
+      && TREE_CODE (e) != CONVERT_EXPR
+      /* Copies are simple.  */
+      && TREE_CODE (e) != SSA_NAME
+      /* Assignments of invariants are simple.  */
+      && !is_gimple_min_invariant (e)
+      /* And increments and decrements by a constant are simple.  */
+      && !((TREE_CODE (e) == PLUS_EXPR
+           || TREE_CODE (e) == MINUS_EXPR)
+          && is_gimple_min_invariant (TREE_OPERAND (e, 1))))
+    return expr;
+
+  return expand_simple_operations (e);
+}
+
 /* Tries to simplify EXPR using the condition COND.  Returns the simplified
-   expression (or EXPR unchanged, if no simplification was possible).*/
+   expression (or EXPR unchanged, if no simplification was possible).  */
 
 static tree
-tree_simplify_using_condition (tree cond, tree expr)
+tree_simplify_using_condition_1 (tree cond, tree expr)
 {
   bool changed;
-  tree e, e0, e1, e2, notcond;
+  tree e, te, e0, e1, e2, notcond;
   enum tree_code code = TREE_CODE (expr);
 
   if (code == INTEGER_CST)
@@ -643,17 +699,17 @@ tree_simplify_using_condition (tree cond, tree expr)
     {
       changed = false;
 
-      e0 = tree_simplify_using_condition (cond, TREE_OPERAND (expr, 0));
+      e0 = tree_simplify_using_condition_1 (cond, TREE_OPERAND (expr, 0));
       if (TREE_OPERAND (expr, 0) != e0)
        changed = true;
 
-      e1 = tree_simplify_using_condition (cond, TREE_OPERAND (expr, 1));
+      e1 = tree_simplify_using_condition_1 (cond, TREE_OPERAND (expr, 1));
       if (TREE_OPERAND (expr, 1) != e1)
        changed = true;
 
       if (code == COND_EXPR)
        {
-         e2 = tree_simplify_using_condition (cond, TREE_OPERAND (expr, 2));
+         e2 = tree_simplify_using_condition_1 (cond, TREE_OPERAND (expr, 2));
          if (TREE_OPERAND (expr, 2) != e2)
            changed = true;
        }
@@ -716,22 +772,37 @@ tree_simplify_using_condition (tree cond, tree expr)
        return boolean_true_node;
     }
 
+  te = expand_simple_operations (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, te);
   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, te);
   if (zero_p (e))
     return e;
 
   return expr;
 }
 
+/* Tries to simplify EXPR using the condition COND.  Returns the simplified
+   expression (or EXPR unchanged, if no simplification was possible).
+   Wrapper around tree_simplify_using_condition_1 that ensures that chains
+   of simple operations in definitions of ssa names in COND are expanded,
+   so that things like casts or incrementing the value of the bound before
+   the loop do not cause us to fail.  */
+
+static tree
+tree_simplify_using_condition (tree cond, tree expr)
+{
+  cond = expand_simple_operations (cond);
+
+  return tree_simplify_using_condition_1 (cond, expr);
+}
+     
 /* Tries to simplify EXPR using the conditions on entry to LOOP.
    Record the conditions used for simplification to CONDS_USED.
    Returns the simplified expression (or EXPR unchanged, if no
@@ -881,9 +952,9 @@ number_of_iterations_exit (struct loop *loop, edge exit,
       && !POINTER_TYPE_P (type))
     return false;
      
-  if (!simple_iv (loop, stmt, op0, &base0, &step0))
+  if (!simple_iv (loop, stmt, op0, &base0, &step0, false))
     return false;
-  if (!simple_iv (loop, stmt, op1, &base1, &step1))
+  if (!simple_iv (loop, stmt, op1, &base1, &step1, false))
     return false;
 
   niter->niter = NULL_TREE;
@@ -1010,8 +1081,8 @@ static tree
 chain_of_csts_start (struct loop *loop, tree x)
 {
   tree stmt = SSA_NAME_DEF_STMT (x);
+  tree use;
   basic_block bb = bb_for_stmt (stmt);
-  use_optype uses;
 
   if (!bb
       || !flow_bb_inside_loop_p (loop, bb))
@@ -1028,20 +1099,16 @@ chain_of_csts_start (struct loop *loop, tree x)
   if (TREE_CODE (stmt) != MODIFY_EXPR)
     return NULL_TREE;
 
-  get_stmt_operands (stmt);
-  if (NUM_VUSES (STMT_VUSE_OPS (stmt)) > 0)
-    return NULL_TREE;
-  if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0)
+  if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
     return NULL_TREE;
-  if (NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
+  if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
     return NULL_TREE;
-  if (NUM_DEFS (STMT_DEF_OPS (stmt)) > 1)
-    return NULL_TREE;
-  uses = STMT_USE_OPS (stmt);
-  if (NUM_USES (uses) != 1)
+
+  use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
+  if (use == NULL_USE_OPERAND_P)
     return NULL_TREE;
 
-  return chain_of_csts_start (loop, USE_OP (uses, 0));
+  return chain_of_csts_start (loop, use);
 }
 
 /* Determines whether the expression X is derived from a result of a phi node
@@ -1094,8 +1161,8 @@ static tree
 get_val_for (tree x, tree base)
 {
   tree stmt, nx, val;
-  use_optype uses;
   use_operand_p op;
+  ssa_op_iter iter;
 
   if (!x)
     return base;
@@ -1104,16 +1171,19 @@ get_val_for (tree x, tree base)
   if (TREE_CODE (stmt) == PHI_NODE)
     return base;
 
-  uses = STMT_USE_OPS (stmt);
-  op = USE_OP_PTR (uses, 0);
-
-  nx = USE_FROM_PTR (op);
-  val = get_val_for (nx, base);
-  SET_USE (op, val);
-  val = fold (TREE_OPERAND (stmt, 1));
-  SET_USE (op, nx);
+  FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
+    {
+      nx = USE_FROM_PTR (op);
+      val = get_val_for (nx, base);
+      SET_USE (op, val);
+      val = fold (TREE_OPERAND (stmt, 1));
+      SET_USE (op, nx);
+      /* only iterate loop once.  */
+      return val;
+    }
 
-  return val;
+  /* Should never reach here.  */
+  gcc_unreachable();
 }
 
 /* Tries to count the number of iterations of LOOP till it exits by EXIT