Infer and push new value ranges for x in y < x.
authorKugan Vivekanandarajah <kuganv@linaro.org>
Mon, 10 Oct 2016 23:48:47 +0000 (23:48 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Mon, 10 Oct 2016 23:48:47 +0000 (23:48 +0000)
gcc/ChangeLog:

2016-10-11  Kugan Vivekanandarajah  <kuganv@linaro.org>

* tree-vrp.c (evrp_dom_walker::try_add_new_range): New.
(evrp_dom_walker::before_dom_children): Infer and push new value
ranges for x in y < x.

From-SVN: r240957

gcc/ChangeLog
gcc/tree-vrp.c

index 99e33a0c5851ab825384cee3479b1e535106dbbc..8e1ee8acfea645de78bd50c612582b054f2a4b4e 100644 (file)
@@ -1,3 +1,9 @@
+2016-10-11  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       * tree-vrp.c (evrp_dom_walker::try_add_new_range): New.
+       (evrp_dom_walker::before_dom_children): Infer and push new value
+       ranges for x in y < x.
+
 2016-10-10  Joseph Myers  <joseph@codesourcery.com>
 
        PR target/77586
index e82dffe6999470ea3e22de024f0301e999f4a4a1..8a129c6d704fbfd8fbcb17a834b2ff4133a7b5fb 100644 (file)
@@ -10650,6 +10650,7 @@ public:
   virtual void after_dom_children (basic_block);
   void push_value_range (const_tree var, value_range *vr);
   value_range *pop_value_range (const_tree var);
+  void try_add_new_range (tree op, tree_code code, tree limit);
 
   /* Cond_stack holds the old VR.  */
   auto_vec<std::pair <const_tree, value_range*> > stack;
@@ -10657,20 +10658,42 @@ public:
   vec<gimple *> stmts_to_fixup;
 };
 
+
+/*  Add new range to OP such that (OP CODE LIMIT) is true.  */
+
+void
+evrp_dom_walker::try_add_new_range (tree op, tree_code code, tree limit)
+{
+  value_range vr = VR_INITIALIZER;
+  value_range *old_vr = get_value_range (op);
+
+  /* Discover VR when condition is true.  */
+  extract_range_for_var_from_comparison_expr (op, code, op,
+                                             limit, &vr);
+  if (old_vr->type == VR_RANGE || old_vr->type == VR_ANTI_RANGE)
+    vrp_intersect_ranges (&vr, old_vr);
+  /* If we found any usable VR, set the VR to ssa_name and create a
+     PUSH old value in the stack with the old VR.  */
+  if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+    {
+      value_range *new_vr = vrp_value_range_pool.allocate ();
+      *new_vr = vr;
+      push_value_range (op, new_vr);
+    }
+}
+
 /* See if there is any new scope is entered with new VR and set that VR to
    ssa_name before visiting the statements in the scope.  */
 
 edge
 evrp_dom_walker::before_dom_children (basic_block bb)
 {
-  value_range *new_vr = NULL;
   tree op0 = NULL_TREE;
 
   push_value_range (NULL_TREE, NULL);
   if (single_pred_p (bb))
     {
       edge e = single_pred_edge (bb);
-      value_range vr = VR_INITIALIZER;
       gimple *stmt = last_stmt (e->src);
       if (stmt
          && gimple_code (stmt) == GIMPLE_COND
@@ -10683,7 +10706,6 @@ evrp_dom_walker::before_dom_children (basic_block bb)
             here.  */
          tree op1 = gimple_cond_rhs (stmt);
          tree_code code = gimple_cond_code (stmt);
-         value_range *old_vr = get_value_range (op0);
 
          if (TREE_OVERFLOW_P (op1))
            op1 = drop_tree_overflow (op1);
@@ -10692,18 +10714,21 @@ evrp_dom_walker::before_dom_children (basic_block bb)
          if (e->flags & EDGE_FALSE_VALUE)
            code = invert_tree_comparison (gimple_cond_code (stmt),
                                           HONOR_NANS (op0));
-         /* Discover VR when condition is true.  */
-         extract_range_for_var_from_comparison_expr (op0, code, op0, op1, &vr);
-         if (old_vr->type == VR_RANGE || old_vr->type == VR_ANTI_RANGE)
-           vrp_intersect_ranges (&vr, old_vr);
-
-         /* If we found any usable VR, set the VR to ssa_name and create a
-            PUSH old value in the stack with the old VR.  */
-         if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+         /* Add VR when (OP0 CODE OP1) condition is true.  */
+         try_add_new_range (op0, code, op1);
+
+         /* Register ranges for y in x < y where
+            y might have ranges that are useful.  */
+         tree limit;
+         tree_code new_code;
+         if (TREE_CODE (op1) == SSA_NAME
+             && extract_code_and_val_from_cond_with_ops (op1, code,
+                                                         op0, op1,
+                                                         false,
+                                                         &new_code, &limit))
            {
-             new_vr = vrp_value_range_pool.allocate ();
-             *new_vr = vr;
-             push_value_range (op0, new_vr);
+             /* Add VR when (OP1 NEW_CODE LIMIT) condition is true.  */
+             try_add_new_range (op1, new_code, limit);
            }
        }
     }