+2018-11-12 Richard Biener <rguenther@suse.de>
+
+ * tree-vrp.h (value_range_base::symbolic_p,
+ value_range_base::constant_p, value_range_base::zero_p,
+ value_range_base::singleton_p): Move from value_range.
+ (value_range::dump): Add.
+ * gimple-ssa-evrp-analyze.c
+ (evrp_range_analyzer::record_ranges_from_phis): Use set_varying.
+ * ipa-cp.c (ipcp_vr_lattice::print): Use dump_value_range.
+ * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
+ Use set_varying.
+ * tree-vrp.c (value_range::symbolic_p): Move to value_range_base.
+ (value_range::constant_p): Likewise.
+ (value_range::singleton_p): Likewise.
+ (value_range_base::dump): Add.
+ (set_value_range_to_undefined): Remove.
+ (set_value_range_to_varying): Likewise.
+ (range_int_cst_p): Take value_range_base argument.
+ (range_int_cst_singleton_p): Likewise.
+ (value_range_constant_singleton): Likewise.
+ (vrp_set_zero_nonzero_bits): Likewise.
+ (extract_range_from_multiplicative_op): Use set_varying.
+ (extract_range_from_binary_expr_1): Likewise. Use set_undefined.
+ (extract_range_from_unary_expr): Likewise.
+ (dump_value_range_base): Change to overload of dump_value_range.
+ (vrp_prop::vrp_initialize): Use set_varying and set_undefined.
+ (vrp_prop::visit_stmt): Likewise.
+ (value_range::intersect_helper): Likewise.
+ (value_range::union_helper): Likewise.
+ (determine_value_range_1): Likewise.
+
2018-11-12 Richard Biener <rguenther@suse.de>
* tree-vrp.c (set_value_range_to_nonnull): Clear equiv.
vr_values->extract_range_from_phi_node (phi, &vr_result);
else
{
- set_value_range_to_varying (&vr_result);
+ vr_result.set_varying ();
/* When we have an unvisited executable predecessor we can't
use PHI arg ranges which may be still UNDEFINED but have
to use VARYING for them. But we can still resort to
void
ipcp_vr_lattice::print (FILE * f)
{
- dump_value_range_base (f, &m_vr);
+ dump_value_range (f, &m_vr);
}
/* Print all ipcp_lattices of all functions to F. */
else if (TREE_CODE (src) == INTEGER_CST)
set_value_range_to_value (new_vr, src, NULL);
else
- set_value_range_to_varying (new_vr);
+ new_vr->set_varying ();
/* This is a temporary range for DST, so push it. */
evrp_range_analyzer->push_value_range (dst, new_vr);
/* Return TRUE if this is a symbolic range. */
bool
-value_range::symbolic_p () const
+value_range_base::symbolic_p () const
{
return (!varying_p ()
&& !undefined_p ()
constants would be represented as [-MIN, +MAX]. */
bool
-value_range::constant_p () const
+value_range_base::constant_p () const
{
return (!varying_p ()
&& !undefined_p ()
So, [&x, &x] counts as a singleton. */
bool
-value_range::singleton_p (tree *result) const
+value_range_base::singleton_p (tree *result) const
{
if (m_kind == VR_RANGE
&& vrp_operand_equal_p (min (), max ())
}
}
+void
+value_range_base::dump () const
+{
+ dump_value_range (stderr, this);
+ fprintf (stderr, "\n");
+}
+
void
value_range::dump () const
{
return vr_type;
}
-/* Set value range VR to VR_UNDEFINED. */
-
-static inline void
-set_value_range_to_undefined (value_range *vr)
-{
- vr->set_undefined ();
-}
-
-/* Set value range VR to VR_VARYING. */
-
-void
-set_value_range_to_varying (value_range *vr)
-{
- vr->set_varying ();
-}
-
/* Set value range VR to {T, MIN, MAX, EQUIV}. */
void
a singleton. */
bool
-range_int_cst_p (const value_range *vr)
+range_int_cst_p (const value_range_base *vr)
{
return (vr->kind () == VR_RANGE
&& TREE_CODE (vr->min ()) == INTEGER_CST
/* Return true if VR is a INTEGER_CST singleton. */
bool
-range_int_cst_singleton_p (const value_range *vr)
+range_int_cst_singleton_p (const value_range_base *vr)
{
return (range_int_cst_p (vr)
&& tree_int_cst_equal (vr->min (), vr->max ()));
is not the best name. */
tree
-value_range_constant_singleton (const value_range *vr)
+value_range_constant_singleton (const value_range_base *vr)
{
tree result = NULL;
if (vr->singleton_p (&result))
bool
vrp_set_zero_nonzero_bits (const tree expr_type,
- const value_range *vr,
+ const value_range_base *vr,
wide_int *may_be_nonzero,
wide_int *must_be_nonzero)
{
wide_int_to_tree (type, res_lb),
wide_int_to_tree (type, res_ub), NULL);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
/* If BOUND will include a symbolic bound, adjust it accordingly,
if (!INTEGRAL_TYPE_P (expr_type)
&& !POINTER_TYPE_P (expr_type))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
&& code != BIT_IOR_EXPR
&& code != BIT_XOR_EXPR)
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
/* If both ranges are UNDEFINED, so is the result. */
if (vr0.undefined_p () && vr1.undefined_p ())
{
- set_value_range_to_undefined (vr);
+ vr->set_undefined ();
return;
}
/* If one of the ranges is UNDEFINED drop it to VARYING for the following
have UNDEFINED result for all or some value-ranges of the not UNDEFINED
operand. */
else if (vr0.undefined_p ())
- set_value_range_to_varying (&vr0);
+ vr0.set_varying ();
else if (vr1.undefined_p ())
- set_value_range_to_varying (&vr1);
+ vr1.set_varying ();
/* We get imprecise results from ranges_from_anti_range when
code is EXACT_DIV_EXPR. We could mask out bits in the resulting
|| vr0.symbolic_p ()
|| vr1.symbolic_p ()))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
else if (range_is_null (&vr0) && range_is_null (&vr1))
set_value_range_to_null (vr, expr_type);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
else if (code == POINTER_PLUS_EXPR)
{
else if (range_is_null (&vr0) && range_is_null (&vr1))
set_value_range_to_null (vr, expr_type);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
else if (code == BIT_AND_EXPR)
{
else if (range_is_null (&vr0) || range_is_null (&vr1))
set_value_range_to_null (vr, expr_type);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
if (((bool)min_ovf && sym_min_op0 != sym_min_op1)
|| ((bool)max_ovf && sym_max_op0 != sym_max_op1))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
wmin, wmax, min_ovf, max_ovf);
if (type == VR_VARYING)
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
a single range or anti-range as the above is
[-INF+1, +INF(OVF)] intersected with ~[5, 5]
but one could use a scheme similar to equivalences for this. */
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
}
vr->update (VR_RANGE, wide_int_to_tree (expr_type, wmin),
wide_int_to_tree (expr_type, wmax));
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
else if (code == MULT_EXPR)
if (!range_int_cst_p (&vr0)
|| !range_int_cst_p (&vr1))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
}
}
}
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
else if (code == TRUNC_DIV_EXPR
/* Special case explicit division by zero as undefined. */
if (range_is_null (&vr1))
{
- set_value_range_to_undefined (vr);
+ vr->set_undefined ();
return;
}
TYPE_OVERFLOW_UNDEFINED (expr_type),
extra_range_p, extra_min, extra_max))
{
- set_value_range_to_varying (vr);
+ vr->set_undefined ();
return;
}
set_value_range (vr, VR_RANGE,
{
if (range_is_null (&vr1))
{
- set_value_range_to_undefined (vr);
+ vr->set_undefined ();
return;
}
wide_int wmin, wmax, tmp;
set_value_range (vr, VR_RANGE, min, max, NULL);
}
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
else if (code == BIT_IOR_EXPR)
set_value_range (vr, VR_RANGE, min, max, NULL);
}
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
else if (code == BIT_XOR_EXPR)
set_value_range (vr, VR_RANGE, min, max, NULL);
}
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
}
|| max == NULL_TREE
|| TREE_OVERFLOW_P (max))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
Note that we do accept [-INF, -INF] and [+INF, +INF]. */
if (vrp_val_is_min (min) && vrp_val_is_max (max))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
/* If the new range has its limits swapped around (MIN > MAX),
then the operation caused one of them to wrap around, mark
the new range VARYING. */
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
else
set_value_range (vr, type, min, max, NULL);
|| !(INTEGRAL_TYPE_P (type)
|| POINTER_TYPE_P (type)))
{
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
/* If VR0 is UNDEFINED, so is the result. */
if (vr0.undefined_p ())
{
- set_value_range_to_undefined (vr);
+ vr->set_undefined ();
return;
}
else if (range_is_null (&vr0))
set_value_range_to_null (vr, type);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
vr->set_and_canonicalize (VR_RANGE, min, max, NULL);
}
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
else if (code == ABS_EXPR)
wide_int_to_tree (type, wmin),
wide_int_to_tree (type, wmax), NULL);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
/* For unhandled operations fall back to varying. */
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
/* Debugging dumps. */
-void dump_value_range (FILE *, const value_range *);
-void debug_value_range (const value_range *);
-void dump_all_value_ranges (FILE *);
-void dump_vr_equiv (FILE *, bitmap);
-void debug_vr_equiv (bitmap);
-
void
dump_value_range (FILE *file, const value_range *vr)
{
}
void
-dump_value_range_base (FILE *file, const value_range_base *vr)
+dump_value_range (FILE *file, const value_range_base *vr)
{
if (!vr)
fprintf (file, "[]");
/* Dump value range VR to stderr. */
+DEBUG_FUNCTION void
+debug_value_range (const value_range_base *vr)
+{
+ dump_value_range (stderr, vr);
+}
+
+/* Dump value range VR to stderr. */
+
DEBUG_FUNCTION void
debug_value_range (const value_range *vr)
{
- vr->dump ();
+ dump_value_range (stderr, vr);
}
if (!stmt_interesting_for_vrp (phi))
{
tree lhs = PHI_RESULT (phi);
- set_value_range_to_varying (get_value_range (lhs));
+ get_value_range (lhs)->set_varying ();
prop_set_simulate_again (phi, false);
}
else
use_operand_p use_p;
enum ssa_prop_result res = SSA_PROP_VARYING;
- set_value_range_to_varying (get_value_range (lhs));
+ get_value_range (lhs)->set_varying ();
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
{
return;
if (vr1->undefined_p ())
{
- set_value_range_to_undefined (vr0);
+ vr0->set_undefined ();
return;
}
if (vr1->varying_p ())
{
- set_value_range_to_varying (vr0);
+ vr0->set_varying ();
return;
}
return;
}
- set_value_range_to_varying (vr0);
+ vr0->set_varying ();
return;
}
vr0->set_and_canonicalize (vr0->kind (), vr0->min (), vr0->max (),
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);
+ vr->set_varying ();
}
}
tree max () const;
/* Types of value ranges. */
+ bool symbolic_p () const;
+ bool constant_p () const;
bool undefined_p () const;
bool varying_p () const;
+ void set_varying ();
+ void set_undefined ();
void union_ (const value_range_base *);
bool ignore_equivs_equal_p (const value_range_base &) const;
- void set_varying ();
- void set_undefined ();
-
/* Misc methods. */
tree type () const;
bool may_contain_p (tree) const;
void set_and_canonicalize (enum value_range_kind, tree, tree);
+ bool zero_p () const;
+ bool singleton_p (tree *result = NULL) const;
void dump (FILE *) const;
+ void dump () const;
protected:
void set (value_range_kind, tree, tree);
void union_ (const value_range *);
/* Types of value ranges. */
- bool symbolic_p () const;
- bool constant_p () const;
void set_undefined ();
void set_varying ();
void equiv_add (const_tree, const value_range *, bitmap_obstack * = NULL);
/* Misc methods. */
- bool zero_p () const;
- bool singleton_p (tree *result = NULL) const;
void deep_copy (const value_range *);
void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap);
void dump (FILE *) const;
/* Return TRUE if range is the constant zero. */
inline bool
-value_range::zero_p () const
+value_range_base::zero_p () const
{
return (m_kind == VR_RANGE
&& integer_zerop (m_min)
}
extern void dump_value_range (FILE *, const value_range *);
-extern void dump_value_range_base (FILE *, const value_range_base *);
-extern void extract_range_from_unary_expr (value_range *vr,
- enum tree_code code,
- tree type,
- const value_range *vr0_,
- tree op0_type);
-
-extern bool vrp_operand_equal_p (const_tree, const_tree);
-extern enum value_range_kind intersect_range_with_nonzero_bits
- (enum value_range_kind, wide_int *, wide_int *, const wide_int &, signop);
+extern void dump_value_range (FILE *, const value_range_base *);
struct assert_info
{
extern void register_edge_assert_for (tree, edge, enum tree_code,
tree, tree, vec<assert_info> &);
extern bool stmt_interesting_for_vrp (gimple *);
-extern void set_value_range_to_varying (value_range *);
extern bool range_includes_zero_p (const value_range_base *);
extern bool infer_value_range (gimple *, tree, tree_code *, tree *);
extern void set_value_range_to_nonnull (value_range *, tree);
+extern void set_value_range_to_null (value_range *, tree);
extern void set_value_range (value_range *, enum value_range_kind, tree,
tree, bitmap);
+extern void set_value_range_to_value (value_range *, tree, bitmap);
+
extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap);
-extern tree value_range_constant_singleton (const value_range *);
+
+extern tree value_range_constant_singleton (const value_range_base *);
+extern bool range_int_cst_p (const value_range_base *);
+extern bool range_int_cst_singleton_p (const value_range_base *);
+
extern int compare_values (tree, tree);
extern int compare_values_warnv (tree, tree, bool *);
+extern int operand_less_p (tree, tree);
extern bool vrp_val_is_min (const_tree);
extern bool vrp_val_is_max (const_tree);
-extern void set_value_range_to_value (value_range *, tree, bitmap);
+extern int value_inside_range (tree, tree, tree);
+
+extern tree vrp_val_min (const_tree);
+extern tree vrp_val_max (const_tree);
+
+extern void extract_range_from_unary_expr (value_range *vr,
+ enum tree_code code,
+ tree type,
+ const value_range *vr0_,
+ tree op0_type);
extern void extract_range_from_binary_expr_1 (value_range *, enum tree_code,
tree, const value_range *,
const value_range *);
-extern tree vrp_val_min (const_tree);
-extern tree vrp_val_max (const_tree);
-extern void set_value_range_to_null (value_range *, tree);
-extern bool range_int_cst_p (const value_range *);
-extern int operand_less_p (tree, tree);
+
+extern bool vrp_operand_equal_p (const_tree, const_tree);
+extern enum value_range_kind intersect_range_with_nonzero_bits
+ (enum value_range_kind, wide_int *, wide_int *, const wide_int &, signop);
+extern bool vrp_set_zero_nonzero_bits (const tree, const value_range_base *,
+ wide_int *, wide_int *);
+
extern bool find_case_label_range (gswitch *, tree, tree, size_t *, size_t *);
extern bool find_case_label_index (gswitch *, size_t, tree, size_t *);
-extern bool vrp_set_zero_nonzero_bits (const tree, const value_range *,
- wide_int *, wide_int *);
extern bool overflow_comparison_p (tree_code, tree, tree, bool, tree *);
-extern bool range_int_cst_singleton_p (const value_range *);
-extern int value_inside_range (tree, tree, 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 *);
+
#endif /* GCC_TREE_VRP_H */
set_value_range_to_truthvalue (value_range *vr, tree type)
{
if (TYPE_PRECISION (type) == 1)
- set_value_range_to_varying (vr);
+ vr->set_varying ();
else
vr->update (VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1));
}
vr->set_varying ();
}
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
else if (TREE_CODE (sym) == RESULT_DECL
&& DECL_BY_REFERENCE (sym))
value_range *vr = get_value_range (def);
/* Avoid writing to vr_const_varying get_value_range may return. */
if (!vr->varying_p ())
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
}
called. */
if (new_vr->undefined_p ())
{
- set_value_range_to_varying (old_vr);
- set_value_range_to_varying (new_vr);
+ old_vr->set_varying ();
+ new_vr->set_varying ();
return true;
}
else
if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
|| limit == var)
{
- set_value_range_to_varying (vr_p);
+ vr_p->set_varying ();
return;
}
all should be optimized away above us. */
if (cond_code == LT_EXPR
&& compare_values (max, min) == 0)
- set_value_range_to_varying (vr_p);
+ vr_p->set_varying ();
else
{
/* For LT_EXPR, we create the range [MIN, MAX - 1]. */
all should be optimized away above us. */
if (cond_code == GT_EXPR
&& compare_values (min, max) == 0)
- set_value_range_to_varying (vr_p);
+ vr_p->set_varying ();
else
{
/* For GT_EXPR, we create the range [MIN + 1, MAX]. */
else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL);
else
- set_value_range_to_varying (&vr0);
+ vr0.set_varying ();
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1))
set_value_range_to_value (&vr1, op1, NULL);
else
- set_value_range_to_varying (&vr1);
+ vr1.set_varying ();
/* If one argument is varying, we can sometimes still deduce a
range for the output: any + [3, +INF] is in [MIN+3, +INF]. */
else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL);
else
- set_value_range_to_varying (&vr0);
+ vr0.set_varying ();
::extract_range_from_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
}
else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL);
else
- set_value_range_to_varying (&vr0);
+ vr0.set_varying ();
tree op1 = gimple_assign_rhs3 (stmt);
value_range vr1;
else if (is_gimple_min_invariant (op1))
set_value_range_to_value (&vr1, op1, NULL);
else
- set_value_range_to_varying (&vr1);
+ vr1.set_varying ();
/* The resulting value range is the union of the operand ranges */
vr->deep_copy (&vr0);
else if (TREE_CODE (op0) == INTEGER_CST)
set_value_range_to_value (&vr0, op0, NULL);
else
- set_value_range_to_varying (&vr0);
+ vr0.set_varying ();
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST)
set_value_range_to_value (&vr1, op1, NULL);
else
- set_value_range_to_varying (&vr1);
+ vr1.set_varying ();
tree vr0min = vr0.min (), vr0max = vr0.max ();
tree vr1min = vr1.min (), vr1max = vr1.max ();
if (vr->kind () == VR_RANGE
&& (vr->min () == vr->max ()
|| operand_equal_p (vr->min (), vr->max (), 0)))
- set_value_range_to_varying (vr);
+ vr->set_varying ();
return;
}
}
NULL);
else if (TYPE_PRECISION (type) == 1
&& !TYPE_UNSIGNED (type))
- set_value_range_to_varying (vr);
+ vr->set_varying ();
else
set_value_range (vr, VR_RANGE, build_int_cst (type, 0),
build_int_cst (type, 1), NULL);
else if (vrp_stmt_computes_nonzero (stmt))
set_value_range_to_nonnull (vr, type);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
}
&& is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL);
else
- set_value_range_to_varying (vr);
+ vr->set_varying ();
if (vr->varying_p ())
extract_range_basic (vr, stmt);
goto update_range;
varying:
- set_value_range_to_varying (vr_result);
+ vr_result->set_varying ();
scev_check:
/* If this is a loop PHI node SCEV may known more about its value-range.
|| compare_values (vr_result->min (), vr_result->max ()) > 0))
;
else
- set_value_range_to_varying (vr_result);
+ vr_result->set_varying ();
/* If the new range is different than the previous value, keep
iterating. */