wide_int min, max;
enum value_range_kind range_type;
+ if (!query)
+ query = get_global_range_query ();
+
if (integral)
{
value_range vr;
- if (query && query->range_of_expr (vr, exp, stmt))
- {
- if (vr.undefined_p ())
- vr.set_varying (TREE_TYPE (exp));
- range_type = vr.kind ();
- min = wi::to_wide (vr.min ());
- max = wi::to_wide (vr.max ());
- }
- else
- range_type = determine_value_range (exp, &min, &max);
+
+ query->range_of_expr (vr, exp, stmt);
+
+ if (vr.undefined_p ())
+ vr.set_varying (TREE_TYPE (exp));
+ range_type = vr.kind ();
+ min = wi::to_wide (vr.min ());
+ max = wi::to_wide (vr.max ());
}
else
range_type = VR_VARYING;
#include "gimplify.h"
#include "dumpfile.h"
#include "cfgexpand.h"
+#include "value-query.h"
/* Extends CST as appropriate for the affine combinations COMB. */
for below case:
(T1)(X *+- CST) -> (T1)X *+- (T1)CST
if X *+- CST doesn't overflow by range information. */
+ value_range vr;
if (TYPE_UNSIGNED (itype)
&& TYPE_OVERFLOW_WRAPS (itype)
&& TREE_CODE (op1) == INTEGER_CST
- && determine_value_range (op0, &minv, &maxv) == VR_RANGE)
+ && get_range_query (cfun)->range_of_expr (vr, op0)
+ && vr.kind () == VR_RANGE)
{
+ wide_int minv = vr.lower_bound ();
+ wide_int maxv = vr.upper_bound ();
wi::overflow_type overflow = wi::OVF_NONE;
signop sign = UNSIGNED;
if (icode == PLUS_EXPR)
if (INTEGRAL_TYPE_P (type))
*var = fold_convert (sizetype, *var);
*off = ssize_int (0);
- if (exp_range && code != SSA_NAME)
- {
- wide_int var_min, var_max;
- if (determine_value_range (exp, &var_min, &var_max) == VR_RANGE)
- *exp_range = value_range (type, var_min, var_max);
- }
+
+ value_range r;
+ if (exp_range && code != SSA_NAME
+ && get_range_query (cfun)->range_of_expr (r, exp)
+ && !r.undefined_p ())
+ *exp_range = r;
}
/* Expresses EXP as VAR + OFF, where OFF is a constant. VAR has the same
{
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, vr1;
- determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
- determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
- range_fold_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
- &vr0, &vr1);
- }
- else if (UNARY_CLASS_P (expr))
- {
- value_range vr0;
- determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
- range_fold_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
- &vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
- }
- else if (TREE_CODE (expr) == INTEGER_CST)
- vr->set (expr);
- else
- {
- value_range r;
- /* 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))
- && get_range_query (cfun)->range_of_expr (r, expr)
- && !r.undefined_p ())
- *vr = r;
- else
- vr->set_varying (TREE_TYPE (expr));
- }
-}
-
-/* Compute a value-range for EXPR and set it in *MIN and *MAX. Return
- the determined range type. */
-
-value_range_kind
-determine_value_range (tree expr, wide_int *min, wide_int *max)
-{
- value_range vr;
- determine_value_range_1 (&vr, expr);
- if (!vr.varying_p () && vr.constant_p ())
- {
- *min = wi::to_wide (vr.min ());
- *max = wi::to_wide (vr.max ());
- return vr.kind ();
- }
-
- return VR_VARYING;
-}
extern bool overflow_comparison_p (tree_code, tree, tree, bool, tree *);
extern tree get_single_symbol (tree, bool *, tree *);
extern void maybe_set_nonzero_bits (edge, tree);
-extern value_range_kind determine_value_range (tree, wide_int *, wide_int *);
extern wide_int masked_increment (const wide_int &val_in, const wide_int &mask,
const wide_int &sgnbit, unsigned int prec);