[EVRP] Register ranges for y in (x COND y) for Early VRP.

Message ID 60bc27ef-2a36-3b50-1acf-71c5e12d839a@linaro.org
State New
Headers show

Commit Message

kugan Oct. 6, 2016, 8:55 p.m.
Hi,

Attached patch Register ranges for y in (x COND y) for Early VRP.

Bootstrapped and regression tested on x86_64-linux-gnu with no new 
regressions. Is this OK for trunk?

Thanks,
Kugan


gcc/ChangeLog:

2016-10-06  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 COND x.

Patch hide | download patch | download mbox

From a90aac71afe66d47268dfb3d0cb7657c96e96b15 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
Date: Mon, 3 Oct 2016 10:12:27 +1100
Subject: [PATCH 2/5] Register ranges for y in x < y

1
---
 gcc/tree-vrp.c | 54 ++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 46bbd82..0892709 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -10640,6 +10640,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;
@@ -10647,20 +10648,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
@@ -10673,7 +10696,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);
@@ -10682,18 +10704,22 @@  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);
 	    }
 	}
     }
-- 
2.7.4