[COMMITTED] Move vrp_simplify_cond_using_ranges to the simplifier.

Message ID 76be2fd3-f36a-7eb7-d452-87c56424d51b@redhat.com
State Committed
Headers
Series [COMMITTED] Move vrp_simplify_cond_using_ranges to the simplifier. |

Commit Message

Andrew MacLeod Oct. 26, 2021, 12:04 a.m. UTC
  VRP currently performs a simplification that we can move into the 
general simplification code. I'll just quote the comment:

    If the conditional is of the form SSA_NAME op constant and the SSA_NAME
    was set via a type conversion, try to replace the SSA_NAME with the RHS
    of the type conversion.  Doing so makes the conversion dead which helps
    subsequent passes.  */

This patch moves the routine to the simplify_using_ranges class, and 
calls it when other conditional simplifications fail.  It also moves the 
simplfy_cast_conds routine into the VRP folder instead of being a 
standalone static function in tree-vrp.c.

Bootstrapped on x86_64-pc-linux-gnu with no regressions. Pushed.

Andrew
  

Patch

From f5bacd9c5be5e129688d9c91eeed05e7b968117e Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Mon, 25 Oct 2021 18:04:06 -0400
Subject: [PATCH 2/2] Move vrp_simplify_cond_using_ranges into the simplifier.

This static VRP routine does a simplification with casted conditions.  Add it
to the general simplfier, and continue to invoke if from the VRP folder.

	* tree-vrp.c (vrp_simplify_cond_using_ranges): Add return type and
	move to vr-values.c.
	(simplify_casted_conds): Move to vrp_folder class.
	(execute_vrp): Call via vrp_folder now.
	* vr-values.c (simplify_cond_using_ranges_1): Call simplify_casted_cond.
	(simplify_using_ranges::simplify_casted_cond): Relocate from tree-vrp.c.
	* vr-values.h (simplify_casted_cond): Add prototype.
---
 gcc/tree-vrp.c  | 91 ++++++++-----------------------------------------
 gcc/vr-values.c | 69 +++++++++++++++++++++++++++++++++++++
 gcc/vr-values.h |  1 +
 3 files changed, 85 insertions(+), 76 deletions(-)

diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index a948c524098..38ea50303e0 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4031,6 +4031,7 @@  class vrp_folder : public substitute_and_fold_engine
     : substitute_and_fold_engine (/* Fold all stmts.  */ true),
       m_vr_values (v), simplifier (v)
     {  }
+  void simplify_casted_conds (function *fun);
 
 private:
   tree value_of_expr (tree name, gimple *stmt) OVERRIDE
@@ -4117,78 +4118,6 @@  vrp_folder::fold_stmt (gimple_stmt_iterator *si)
   return simplifier.simplify (si);
 }
 
-/* STMT is a conditional at the end of a basic block.
-
-   If the conditional is of the form SSA_NAME op constant and the SSA_NAME
-   was set via a type conversion, try to replace the SSA_NAME with the RHS
-   of the type conversion.  Doing so makes the conversion dead which helps
-   subsequent passes.  */
-
-static void
-vrp_simplify_cond_using_ranges (range_query *query, gcond *stmt)
-{
-  tree op0 = gimple_cond_lhs (stmt);
-  tree op1 = gimple_cond_rhs (stmt);
-
-  /* If we have a comparison of an SSA_NAME (OP0) against a constant,
-     see if OP0 was set by a type conversion where the source of
-     the conversion is another SSA_NAME with a range that fits
-     into the range of OP0's type.
-
-     If so, the conversion is redundant as the earlier SSA_NAME can be
-     used for the comparison directly if we just massage the constant in the
-     comparison.  */
-  if (TREE_CODE (op0) == SSA_NAME
-      && TREE_CODE (op1) == INTEGER_CST)
-    {
-      gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
-      tree innerop;
-
-      if (!is_gimple_assign (def_stmt))
-	return;
-
-      switch (gimple_assign_rhs_code (def_stmt))
-	{
-	CASE_CONVERT:
-	  innerop = gimple_assign_rhs1 (def_stmt);
-	  break;
-	case VIEW_CONVERT_EXPR:
-	  innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
-	  if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
-	    return;
-	  break;
-	default:
-	  return;
-	}
-
-      if (TREE_CODE (innerop) == SSA_NAME
-	  && !POINTER_TYPE_P (TREE_TYPE (innerop))
-	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
-	  && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
-	{
-	  const value_range *vr = query->get_value_range (innerop);
-
-	  if (range_int_cst_p (vr)
-	      && range_fits_type_p (vr,
-				    TYPE_PRECISION (TREE_TYPE (op0)),
-				    TYPE_SIGN (TREE_TYPE (op0)))
-	      && int_fits_type_p (op1, TREE_TYPE (innerop)))
-	    {
-	      tree newconst = fold_convert (TREE_TYPE (innerop), op1);
-	      gimple_cond_set_lhs (stmt, innerop);
-	      gimple_cond_set_rhs (stmt, newconst);
-	      update_stmt (stmt);
-	      if (dump_file && (dump_flags & TDF_DETAILS))
-		{
-		  fprintf (dump_file, "Folded into: ");
-		  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
-		  fprintf (dump_file, "\n");
-		}
-	    }
-	}
-    }
-}
-
 /* A comparison of an SSA_NAME against a constant where the SSA_NAME
    was set by a type conversion can often be rewritten to use the RHS
    of the type conversion.  Do this optimization for all conditionals
@@ -4198,15 +4127,25 @@  vrp_simplify_cond_using_ranges (range_query *query, gcond *stmt)
    So that transformation is not performed until after jump threading
    is complete.  */
 
-static void
-simplify_casted_conds (function *fun, range_query *query)
+void
+vrp_folder::simplify_casted_conds (function *fun)
 {
   basic_block bb;
   FOR_EACH_BB_FN (bb, fun)
     {
       gimple *last = last_stmt (bb);
       if (last && gimple_code (last) == GIMPLE_COND)
-	vrp_simplify_cond_using_ranges (query, as_a <gcond *> (last));
+	{
+	  if (simplifier.simplify_casted_cond (as_a <gcond *> (last)))
+	    {
+	      if (dump_file && (dump_flags & TDF_DETAILS))
+		{
+		  fprintf (dump_file, "Folded into: ");
+		  print_gimple_stmt (dump_file, last, 0, TDF_SLIM);
+		  fprintf (dump_file, "\n");
+		}
+	    }
+	}
     }
 }
 
@@ -4301,7 +4240,7 @@  execute_vrp (struct function *fun, bool warn_array_bounds_p)
       array_checker.check ();
     }
 
-  simplify_casted_conds (fun, &vrp_vr_values);
+  folder.simplify_casted_conds (fun);
 
   free_numbers_of_iterations_estimates (fun);
 
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index d0f7cb41bc8..00246c9d3af 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -3630,6 +3630,75 @@  simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
 	    }
 	}
     }
+  // Try to simplify casted conditions.
+  return simplify_casted_cond (stmt);
+}
+
+/* STMT is a conditional at the end of a basic block.
+
+   If the conditional is of the form SSA_NAME op constant and the SSA_NAME
+   was set via a type conversion, try to replace the SSA_NAME with the RHS
+   of the type conversion.  Doing so makes the conversion dead which helps
+   subsequent passes.  */
+
+bool
+simplify_using_ranges::simplify_casted_cond (gcond *stmt)
+{
+  tree op0 = gimple_cond_lhs (stmt);
+  tree op1 = gimple_cond_rhs (stmt);
+
+  /* If we have a comparison of an SSA_NAME (OP0) against a constant,
+     see if OP0 was set by a type conversion where the source of
+     the conversion is another SSA_NAME with a range that fits
+     into the range of OP0's type.
+
+     If so, the conversion is redundant as the earlier SSA_NAME can be
+     used for the comparison directly if we just massage the constant in the
+     comparison.  */
+  if (TREE_CODE (op0) == SSA_NAME
+      && TREE_CODE (op1) == INTEGER_CST)
+    {
+      gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
+      tree innerop;
+
+      if (!is_gimple_assign (def_stmt))
+	return false;
+
+      switch (gimple_assign_rhs_code (def_stmt))
+	{
+	CASE_CONVERT:
+	  innerop = gimple_assign_rhs1 (def_stmt);
+	  break;
+	case VIEW_CONVERT_EXPR:
+	  innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
+	  if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
+	    return false;
+	  break;
+	default:
+	  return false;
+	}
+
+      if (TREE_CODE (innerop) == SSA_NAME
+	  && !POINTER_TYPE_P (TREE_TYPE (innerop))
+	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
+	  && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
+	{
+	  const value_range *vr = query->get_value_range (innerop);
+
+	  if (range_int_cst_p (vr)
+	      && range_fits_type_p (vr,
+				    TYPE_PRECISION (TREE_TYPE (op0)),
+				    TYPE_SIGN (TREE_TYPE (op0)))
+	      && int_fits_type_p (op1, TREE_TYPE (innerop)))
+	    {
+	      tree newconst = fold_convert (TREE_TYPE (innerop), op1);
+	      gimple_cond_set_lhs (stmt, innerop);
+	      gimple_cond_set_rhs (stmt, newconst);
+	      update_stmt (stmt);
+	      return true;
+	    }
+	}
+    }
   return false;
 }
 
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 821bcb9d58d..21dc4eaebce 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -44,6 +44,7 @@  public:
   tree vrp_evaluate_conditional_warnv_with_ops (gimple *stmt, enum tree_code,
 						tree, tree, bool,
 						bool *, bool *);
+  bool simplify_casted_cond (gcond *);
 
 private:
   bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
-- 
2.17.2