OSDN Git Service

gcc/fortran:
[pf3gnuchains/gcc-fork.git] / gcc / tree-vrp.c
index 11e955f..1e1ffaa 100644 (file)
@@ -107,7 +107,7 @@ static int *vr_phi_edge_counts;
    TYPE_{MIN,MAX}_VALUE.  */
 
 static inline bool
-needs_overflow_infinity (tree type)
+needs_overflow_infinity (const_tree type)
 {
   return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
 }
@@ -119,7 +119,7 @@ needs_overflow_infinity (tree type)
    VARYING.  */
 
 static inline bool
-supports_overflow_infinity (tree type)
+supports_overflow_infinity (const_tree type)
 {
 #ifdef ENABLE_CHECKING
   gcc_assert (needs_overflow_infinity (type));
@@ -169,7 +169,7 @@ positive_overflow_infinity (tree type)
 /* Return whether VAL is a negative overflow infinity.  */
 
 static inline bool
-is_negative_overflow_infinity (tree val)
+is_negative_overflow_infinity (const_tree val)
 {
   return (needs_overflow_infinity (TREE_TYPE (val))
          && CONSTANT_CLASS_P (val)
@@ -180,7 +180,7 @@ is_negative_overflow_infinity (tree val)
 /* Return whether VAL is a positive overflow infinity.  */
 
 static inline bool
-is_positive_overflow_infinity (tree val)
+is_positive_overflow_infinity (const_tree val)
 {
   return (needs_overflow_infinity (TREE_TYPE (val))
          && CONSTANT_CLASS_P (val)
@@ -191,7 +191,7 @@ is_positive_overflow_infinity (tree val)
 /* Return whether VAL is a positive or negative overflow infinity.  */
 
 static inline bool
-is_overflow_infinity (tree val)
+is_overflow_infinity (const_tree val)
 {
   return (needs_overflow_infinity (TREE_TYPE (val))
          && CONSTANT_CLASS_P (val)
@@ -229,7 +229,7 @@ avoid_overflow_infinity (tree val)
    to the integer constant with the same value in the type.  */
 
 static inline bool
-vrp_val_is_max (tree val)
+vrp_val_is_max (const_tree val)
 {
   tree type_max = TYPE_MAX_VALUE (TREE_TYPE (val));
 
@@ -242,7 +242,7 @@ vrp_val_is_max (tree val)
    will be true for a negative overflow infinity.  */
 
 static inline bool
-vrp_val_is_min (tree val)
+vrp_val_is_min (const_tree val)
 {
   tree type_min = TYPE_MIN_VALUE (TREE_TYPE (val));
 
@@ -256,7 +256,7 @@ vrp_val_is_min (tree val)
    current function signature.  */
 
 static bool
-nonnull_arg_p (tree arg)
+nonnull_arg_p (const_tree arg)
 {
   tree t, attrs, fntype;
   unsigned HOST_WIDE_INT arg_num;
@@ -462,7 +462,7 @@ set_value_range_to_undefined (value_range_t *vr)
    return NULL.  Otherwise create an empty range if none existed for VAR.  */
 
 static value_range_t *
-get_value_range (tree var)
+get_value_range (const_tree var)
 {
   value_range_t *vr;
   tree sym;
@@ -504,7 +504,7 @@ get_value_range (tree var)
 /* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */
 
 static inline bool
-vrp_operand_equal_p (tree val1, tree val2)
+vrp_operand_equal_p (const_tree val1, const_tree val2)
 {
   if (val1 == val2)
     return true;
@@ -518,7 +518,7 @@ vrp_operand_equal_p (tree val1, tree val2)
 /* Return true, if the bitmaps B1 and B2 are equal.  */
 
 static inline bool
-vrp_bitmap_equal_p (bitmap b1, bitmap b2)
+vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
 {
   return (b1 == b2
          || (b1 && b2
@@ -536,7 +536,7 @@ vrp_bitmap_equal_p (bitmap b1, bitmap b2)
    is the range object associated with another SSA name.  */
 
 static inline bool
-update_value_range (tree var, value_range_t *new_vr)
+update_value_range (const_tree var, value_range_t *new_vr)
 {
   value_range_t *old_vr;
   bool is_new;
@@ -562,7 +562,7 @@ update_value_range (tree var, value_range_t *new_vr)
    point where equivalence processing can be turned on/off.  */
 
 static void
-add_equivalence (bitmap *equiv, tree var)
+add_equivalence (bitmap *equiv, const_tree var)
 {
   unsigned ver = SSA_NAME_VERSION (var);
   value_range_t *vr = vr_value[ver];
@@ -1044,7 +1044,7 @@ range_includes_zero_p (value_range_t *vr)
    false otherwise or if no value range information is available.  */
 
 bool
-ssa_name_nonnegative_p (tree t)
+ssa_name_nonnegative_p (const_tree t)
 {
   value_range_t *vr = get_value_range (t);
 
@@ -1066,7 +1066,7 @@ ssa_name_nonnegative_p (tree t)
    false otherwise or if no value range information is available.  */
 
 bool
-ssa_name_nonzero_p (tree t)
+ssa_name_nonzero_p (const_tree t)
 {
   value_range_t *vr = get_value_range (t);
 
@@ -2636,12 +2636,19 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
   if (vr->type == VR_ANTI_RANGE)
     return;
 
+  /* Ensure that there are not values in the scev cache based on assumptions
+     on ranges of ssa names that were changed
+     (in set_value_range/set_value_range_to_varying).  Preserve cached numbers
+     of iterations, that were computed before the start of VRP (we do not
+     recompute these each time to save the compile time).  */
+  scev_reset_except_niters ();
+
   chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
 
   /* Like in PR19590, scev can return a constant function.  */
   if (is_gimple_min_invariant (chrec))
     {
-      set_value_range (vr, VR_RANGE, chrec, chrec, vr->equiv);
+      set_value_range_to_value (vr, chrec, vr->equiv);
       return;
     }
 
@@ -3252,7 +3259,7 @@ build_assert_expr_for (tree cond, tree v)
    point values.  */
 
 static inline bool
-fp_predicate (tree expr)
+fp_predicate (const_tree expr)
 {
   return (COMPARISON_CLASS_P (expr)
          && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))));
@@ -4339,7 +4346,7 @@ check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
 
   low_sub = up_sub = TREE_OPERAND (ref, 1);
 
-  if (!up_bound || !locus || TREE_NO_WARNING (ref)
+  if (!up_bound || TREE_NO_WARNING (ref)
       || TREE_CODE (up_bound) != INTEGER_CST
       /* Can not check flexible arrays.  */
       || (TYPE_SIZE (TREE_TYPE (ref)) == NULL_TREE
@@ -4441,6 +4448,12 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
   tree stmt = (tree)data;
   location_t *location = EXPR_LOCUS (stmt);
 
+  if (!EXPR_HAS_LOCATION (stmt))
+    {
+      *walk_subtree = FALSE;
+      return NULL_TREE;
+    }
+
   *walk_subtree = TRUE;
 
   if (TREE_CODE (t) == ARRAY_REF)
@@ -6041,6 +6054,20 @@ vrp_finalize (void)
   vr_phi_edge_counts = NULL;
 }
 
+/* Calculates number of iterations for all loops, to ensure that they are
+   cached.  */
+
+static void
+record_numbers_of_iterations (void)
+{
+  loop_iterator li;
+  struct loop *loop;
+
+  FOR_EACH_LOOP (li, loop, 0)
+    {
+      number_of_latch_executions (loop);
+    }
+}
 
 /* Main entry point to VRP (Value Range Propagation).  This pass is
    loosely based on J. R. C. Patterson, ``Accurate Static Branch
@@ -6095,6 +6122,17 @@ execute_vrp (void)
 
   insert_range_assertions ();
 
+  /* Compute the # of iterations for each loop before we start the VRP
+     analysis.  The value ranges determined by VRP are used in expression
+     simplification, that is also used by the # of iterations analysis.
+     However, in the middle of the VRP analysis, the value ranges do not take
+     all the possible paths in CFG into account, so they do not have to be
+     correct, and the # of iterations analysis can obtain wrong results.
+     This is a problem, since the results of the # of iterations analysis
+     are cached, so these mistakes would not be corrected when the value
+     ranges are corrected.  */
+  record_numbers_of_iterations ();
+
   vrp_initialize ();
   ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
   vrp_finalize ();