OSDN Git Service

2010-03-11 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-vrp.c
index 6e60709..0071e82 100644 (file)
@@ -1898,9 +1898,9 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
 
   res = int_const_binop (code, val1, val2, 0);
 
-  /* If we are not using wrapping arithmetic, operate symbolically
-     on -INF and +INF.  */
-  if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
+  /* If we are using unsigned arithmetic, operate symbolically
+     on -INF and +INF as int_const_binop only handles signed overflow.  */
+  if (TYPE_UNSIGNED (TREE_TYPE (val1)))
     {
       int checkz = compare_values (res, val1);
       bool overflow = false;
@@ -1937,6 +1937,10 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
        }
 
     }
+  else if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
+    /* If the singed operation wraps then int_const_binop has done
+       everything we want.  */
+    ;
   else if ((TREE_OVERFLOW (res)
            && !TREE_OVERFLOW (val1)
            && !TREE_OVERFLOW (val2))
@@ -3276,7 +3280,8 @@ vrp_var_may_overflow (tree var, gimple stmt)
     return true;
 
   l = loop_containing_stmt (stmt);
-  if (l == NULL)
+  if (l == NULL
+      || !loop_outer (l))
     return true;
 
   chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
@@ -3911,7 +3916,6 @@ register_new_assert_for (tree name, tree expr,
                         gimple_stmt_iterator si)
 {
   assert_locus_t n, loc, last_loc;
-  bool found;
   basic_block dest_bb;
 
 #if defined ENABLE_CHECKING
@@ -3960,7 +3964,6 @@ register_new_assert_for (tree name, tree expr,
      COMP_CODE and VAL could be implemented.  */
   loc = asserts_for[SSA_NAME_VERSION (name)];
   last_loc = loc;
-  found = false;
   while (loc)
     {
       if (loc->comp_code == comp_code
@@ -4833,6 +4836,10 @@ process_assert_insertions_for (tree name, assert_locus_t loc)
   edge_iterator ei;
   edge e;
 
+  /* If we have X <=> X do not insert an assert expr for that.  */
+  if (loc->expr == loc->val)
+    return false;
+
   cond = build2 (loc->comp_code, boolean_type_node, loc->expr, loc->val);
   assert_stmt = build_assert_expr_for (cond, name);
   if (loc->e)
@@ -5124,36 +5131,16 @@ check_all_array_refs (void)
 
   FOR_EACH_BB (bb)
     {
-      /* Skip bb's that are clearly unreachable.  */
-      if (single_pred_p (bb))
-      {
-       int i;
-       bool reachable = true;
-       edge e2;
-       edge e = EDGE_PRED (bb, 0);
-       basic_block pred_bb = e->src;
-       gimple ls = NULL;
-
-       for (i = 0; VEC_iterate (edge, to_remove_edges, i, e2); ++i)
-         if (e == e2)
-           {
-             reachable = false;
-             break;
-           }
-
-       if (!reachable)
-         continue;
+      edge_iterator ei;
+      edge e;
+      bool executable = false;
 
-       if (!gsi_end_p (gsi_last_bb (pred_bb)))
-         ls = gsi_stmt (gsi_last_bb (pred_bb));
+      /* Skip blocks that were found to be unreachable.  */
+      FOR_EACH_EDGE (e, ei, bb->preds)
+       executable |= !!(e->flags & EDGE_EXECUTABLE);
+      if (!executable)
+       continue;
 
-       if (ls && gimple_code (ls) == GIMPLE_COND
-           && ((gimple_cond_false_p (ls)
-                && (EDGE_PRED (bb, 0)->flags & EDGE_TRUE_VALUE))
-               || (gimple_cond_true_p (ls)
-                   && (EDGE_PRED (bb, 0)->flags & EDGE_FALSE_VALUE))))
-         continue;
-      }
       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
        {
          gimple stmt = gsi_stmt (si);
@@ -5360,7 +5347,6 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
           && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
          || POINTER_TYPE_P (TREE_TYPE (lhs))))
     {
-      struct loop *l;
       value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
 
       if (code == GIMPLE_CALL)
@@ -5368,12 +5354,6 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
       else
        extract_range_from_assignment (&new_vr, stmt);
 
-      /* If STMT is inside a loop, we may be able to know something
-        else about the range of LHS by examining scalar evolution
-        information.  */
-      if (current_loops && (l = loop_containing_stmt (stmt)))
-       adjust_range_with_scev (&new_vr, l, stmt, lhs);
-
       if (update_value_range (lhs, &new_vr))
        {
          *output_p = lhs;
@@ -5997,7 +5977,7 @@ vrp_visit_switch_stmt (gimple stmt, edge *taken_edge_p)
 {
   tree op, val;
   value_range_t *vr;
-  size_t i = 0, j = 0, n;
+  size_t i = 0, j = 0;
   bool take_default;
 
   *taken_edge_p = NULL;
@@ -6020,8 +6000,6 @@ vrp_visit_switch_stmt (gimple stmt, edge *taken_edge_p)
     return SSA_PROP_VARYING;
 
   /* Find the single edge that is taken from the switch expression.  */
-  n = gimple_switch_num_labels (stmt);
-
   take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
 
   /* Check if the range spans no CASE_LABEL. If so, we only reach the default
@@ -6279,6 +6257,7 @@ vrp_visit_phi_node (gimple phi)
   value_range_t *lhs_vr = get_value_range (lhs);
   value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
   int edges, old_edges;
+  struct loop *l;
 
   copy_value_range (&vr_result, lhs_vr);
 
@@ -6342,6 +6321,13 @@ vrp_visit_phi_node (gimple phi)
        }
     }
 
+  /* If this is a loop PHI node SCEV may known more about its
+     value-range.  */
+  if (current_loops
+      && (l = loop_containing_stmt (phi))
+      && l->header == gimple_bb (phi))
+    adjust_range_with_scev (&vr_result, l, phi, lhs);
+
   if (vr_result.type == VR_VARYING)
     goto varying;
 
@@ -6930,6 +6916,7 @@ simplify_switch_using_ranges (gimple stmt)
          fprintf (dump_file, "removing unreachable case label\n");
        }
       VEC_safe_push (edge, heap, to_remove_edges, e);
+      e->flags &= ~EDGE_EXECUTABLE;
     }
 
   /* And queue an update for the stmt.  */
@@ -7259,7 +7246,7 @@ vrp_finalize (void)
   substitute_and_fold (single_val_range, vrp_fold_stmt);
 
   if (warn_array_bounds)
-      check_all_array_refs ();
+    check_all_array_refs ();
 
   /* We must identify jump threading opportunities before we release
      the datastructures built by VRP.  */