{
return new pass_vrp (ctxt);
}
+
+
+/* Worker for determine_value_range. */
+
+static void
+determine_value_range_1 (value_range *vr, tree expr)
+{
+ if (BINARY_CLASS_P (expr))
+ {
+ value_range vr0 = VR_INITIALIZER, vr1 = VR_INITIALIZER;
+ determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
+ determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
+ extract_range_from_binary_expr_1 (vr, TREE_CODE (expr), TREE_TYPE (expr),
+ &vr0, &vr1);
+ }
+ else if (UNARY_CLASS_P (expr))
+ {
+ value_range vr0 = VR_INITIALIZER;
+ determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
+ extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
+ &vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
+ }
+ else if (TREE_CODE (expr) == INTEGER_CST)
+ set_value_range_to_value (vr, expr, NULL);
+ else
+ {
+ value_range_type kind;
+ wide_int min, max;
+ /* For SSA names try to extract range info computed by VRP. Otherwise
+ fall back to varying. */
+ if (TREE_CODE (expr) == SSA_NAME
+ && INTEGRAL_TYPE_P (TREE_TYPE (expr))
+ && (kind = get_range_info (expr, &min, &max)) != VR_VARYING)
+ set_value_range (vr, kind, wide_int_to_tree (TREE_TYPE (expr), min),
+ wide_int_to_tree (TREE_TYPE (expr), max), NULL);
+ else
+ set_value_range_to_varying (vr);
+ }
+}
+
+/* Compute a value-range for EXPR and set it in *MIN and *MAX. Return
+ the determined range type. */
+
+value_range_type
+determine_value_range (tree expr, wide_int *min, wide_int *max)
+{
+ value_range vr = VR_INITIALIZER;
+ determine_value_range_1 (&vr, expr);
+ if ((vr.type == VR_RANGE
+ || vr.type == VR_ANTI_RANGE)
+ && !symbolic_range_p (&vr))
+ {
+ *min = wi::to_wide (vr.min);
+ *max = wi::to_wide (vr.max);
+ return vr.type;
+ }
+
+ return VR_VARYING;
+}