@@ -4395,6 +4395,67 @@ vrp_prop::vrp_finalize (vrp_folder *folder, bool warn_array_bounds_p)
}
}
+/* 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 (vr_values *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)
+ || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+ return;
+
+ innerop = gimple_assign_rhs1 (def_stmt);
+
+ 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");
+ }
+ }
+ }
+ }
+}
+
/* Main entry point to VRP (Value Range Propagation). This pass is
loosely based on J. R. C. Patterson, ``Accurate Static Branch
Prediction by Value Range Propagation,'' in SIGPLAN Conference on
@@ -4482,8 +4543,8 @@ execute_vrp (struct function *fun, bool warn_array_bounds_p)
{
gimple *last = last_stmt (bb);
if (last && gimple_code (last) == GIMPLE_COND)
- simplify_cond_using_ranges_2 (&vrp_prop.vr_values,
- as_a <gcond *> (last));
+ vrp_simplify_cond_using_ranges (&vrp_prop.vr_values,
+ as_a <gcond *> (last));
}
free_numbers_of_iterations_estimates (fun);
@@ -3594,7 +3594,7 @@ test_for_singularity (enum tree_code cond_code, tree op0,
/* Return whether the value range *VR fits in an integer type specified
by PRECISION and UNSIGNED_P. */
-static bool
+bool
range_fits_type_p (const value_range *vr,
unsigned dest_precision, signop dest_sgn)
{
@@ -3781,67 +3781,6 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
return false;
}
-/* 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. */
-
-void
-simplify_cond_using_ranges_2 (vr_values *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)
- || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
- return;
-
- innerop = gimple_assign_rhs1 (def_stmt);
-
- 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");
- }
- }
- }
- }
-}
-
/* Simplify a switch statement using the value range of the switch
argument. */
@@ -170,9 +170,8 @@ class vr_values : public range_query
extern tree get_output_for_vrp (gimple *);
-// FIXME: Move this to tree-vrp.c.
-void simplify_cond_using_ranges_2 (class vr_values *, gcond *);
-
+extern bool range_fits_type_p (const value_range *vr,
+ unsigned dest_precision, signop dest_sgn);
extern bool bounds_of_var_in_loop (tree *min, tree *max, range_query *,
class loop *loop, gimple *stmt, tree var);